diff --git a/.changeset/README.md b/.changeset/README.md
new file mode 100644
index 00000000..e5b6d8d6
--- /dev/null
+++ b/.changeset/README.md
@@ -0,0 +1,8 @@
+# Changesets
+
+Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
+with multi-package repos, or single-package repos to help you version and publish your code. You can
+find the full documentation for it [in our repository](https://github.com/changesets/changesets)
+
+We have a quick list of common questions to get you started engaging with this project in
+[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
diff --git a/.changeset/blue-hounds-sort.md b/.changeset/blue-hounds-sort.md
new file mode 100644
index 00000000..350243c3
--- /dev/null
+++ b/.changeset/blue-hounds-sort.md
@@ -0,0 +1,7 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+---
+
+add fetch package
diff --git a/.changeset/chilled-emus-own.md b/.changeset/chilled-emus-own.md
new file mode 100644
index 00000000..31a79699
--- /dev/null
+++ b/.changeset/chilled-emus-own.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+feat(fetcher): change fetcher model to factory
diff --git a/.changeset/config.json b/.changeset/config.json
new file mode 100644
index 00000000..99119101
--- /dev/null
+++ b/.changeset/config.json
@@ -0,0 +1,11 @@
+{
+ "$schema": "https://unpkg.com/@changesets/config@2.2.0/schema.json",
+ "changelog": "@changesets/cli/changelog",
+ "commit": true,
+ "fixed": [["@zodios/*"]],
+ "linked": [],
+ "access": "public",
+ "baseBranch": "main",
+ "updateInternalDependencies": "patch",
+ "ignore": []
+}
diff --git a/.changeset/curly-shrimps-destroy.md b/.changeset/curly-shrimps-destroy.md
new file mode 100644
index 00000000..01eba10d
--- /dev/null
+++ b/.changeset/curly-shrimps-destroy.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+feat: improve typings
diff --git a/.changeset/famous-rules-drop.md b/.changeset/famous-rules-drop.md
new file mode 100644
index 00000000..ce7187ce
--- /dev/null
+++ b/.changeset/famous-rules-drop.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+feat(react): migrate react to v11
diff --git a/.changeset/few-icons-march.md b/.changeset/few-icons-march.md
new file mode 100644
index 00000000..7d0dbe2c
--- /dev/null
+++ b/.changeset/few-icons-march.md
@@ -0,0 +1,10 @@
+---
+"@zodios/express": major
+"@zodios/testing": major
+"@zodios/axios": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/core": major
+---
+
+migrate to typescript v11
diff --git a/.changeset/five-apricots-breathe.md b/.changeset/five-apricots-breathe.md
new file mode 100644
index 00000000..0cec17bc
--- /dev/null
+++ b/.changeset/five-apricots-breathe.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+chore(deps): update zod
diff --git a/.changeset/gentle-ligers-mix.md b/.changeset/gentle-ligers-mix.md
new file mode 100644
index 00000000..7cf20528
--- /dev/null
+++ b/.changeset/gentle-ligers-mix.md
@@ -0,0 +1,8 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/testing": major
+---
+
+fix(testing): safely export hooks
diff --git a/.changeset/good-tigers-tie.md b/.changeset/good-tigers-tie.md
new file mode 100644
index 00000000..683ffa0c
--- /dev/null
+++ b/.changeset/good-tigers-tie.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+chore(deps): update fp-ts
diff --git a/.changeset/gorgeous-dolls-fry.md b/.changeset/gorgeous-dolls-fry.md
new file mode 100644
index 00000000..63a430ec
--- /dev/null
+++ b/.changeset/gorgeous-dolls-fry.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+fix(react): do not double fetch if react-query signal is not used
diff --git a/.changeset/long-fans-dress.md b/.changeset/long-fans-dress.md
new file mode 100644
index 00000000..9055b49e
--- /dev/null
+++ b/.changeset/long-fans-dress.md
@@ -0,0 +1,7 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+---
+
+chore(deps): upgrade axios
diff --git a/.changeset/lucky-brooms-fry.md b/.changeset/lucky-brooms-fry.md
new file mode 100644
index 00000000..b37568b9
--- /dev/null
+++ b/.changeset/lucky-brooms-fry.md
@@ -0,0 +1,6 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+---
+
+fix axios tests
diff --git a/.changeset/nervous-kings-bow.md b/.changeset/nervous-kings-bow.md
new file mode 100644
index 00000000..01eba10d
--- /dev/null
+++ b/.changeset/nervous-kings-bow.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+feat: improve typings
diff --git a/.changeset/nice-kids-attend.md b/.changeset/nice-kids-attend.md
new file mode 100644
index 00000000..9b877540
--- /dev/null
+++ b/.changeset/nice-kids-attend.md
@@ -0,0 +1,8 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/testing": major
+---
+
+feat(testing): add testing package
diff --git a/.changeset/nice-wombats-boil.md b/.changeset/nice-wombats-boil.md
new file mode 100644
index 00000000..30ee71b7
--- /dev/null
+++ b/.changeset/nice-wombats-boil.md
@@ -0,0 +1,8 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/testing": major
+---
+
+feat(testing): add response testing handlers
diff --git a/.changeset/odd-avocados-prove.md b/.changeset/odd-avocados-prove.md
new file mode 100644
index 00000000..2933adcc
--- /dev/null
+++ b/.changeset/odd-avocados-prove.md
@@ -0,0 +1,11 @@
+---
+"@zodios/express": major
+"@zodios/openapi": major
+"@zodios/testing": major
+"@zodios/axios": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/core": major
+---
+
+feat(openapi): add openapi
diff --git a/.changeset/polite-bugs-confess.md b/.changeset/polite-bugs-confess.md
new file mode 100644
index 00000000..f68777d6
--- /dev/null
+++ b/.changeset/polite-bugs-confess.md
@@ -0,0 +1,7 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+---
+
+feat(fetch): remove qs dependency
diff --git a/.changeset/polite-points-float.md b/.changeset/polite-points-float.md
new file mode 100644
index 00000000..335a0fce
--- /dev/null
+++ b/.changeset/polite-points-float.md
@@ -0,0 +1,8 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/testing": major
+---
+
+fix(testing): import types from core instead of relaive directory
diff --git a/.changeset/pre.json b/.changeset/pre.json
new file mode 100644
index 00000000..69e29fde
--- /dev/null
+++ b/.changeset/pre.json
@@ -0,0 +1,43 @@
+{
+ "mode": "pre",
+ "tag": "beta",
+ "initialVersions": {
+ "@zodios/core": "11.0.0-beta.0",
+ "@zodios/axios": "11.0.0-beta.0",
+ "@zodios/fetch": "11.0.0-beta.5",
+ "@zodios/testing": "11.0.0-beta.8",
+ "@zodios/react": "11.0.0-beta.12",
+ "@zodios/express": "11.0.0-beta.17",
+ "@zodios/openapi": "10.4.7"
+ },
+ "changesets": [
+ "blue-hounds-sort",
+ "chilled-emus-own",
+ "curly-shrimps-destroy",
+ "famous-rules-drop",
+ "few-icons-march",
+ "five-apricots-breathe",
+ "gentle-ligers-mix",
+ "good-tigers-tie",
+ "gorgeous-dolls-fry",
+ "long-fans-dress",
+ "lucky-brooms-fry",
+ "nervous-kings-bow",
+ "nice-kids-attend",
+ "nice-wombats-boil",
+ "odd-avocados-prove",
+ "polite-bugs-confess",
+ "polite-points-float",
+ "quiet-rockets-dream",
+ "rare-zoos-serve",
+ "rich-pigs-thank",
+ "short-hounds-mix",
+ "silent-garlics-scream",
+ "slimy-pugs-melt",
+ "slow-worms-destroy",
+ "small-horses-laugh",
+ "soft-seas-lie",
+ "tasty-bags-happen",
+ "twelve-dingos-cover"
+ ]
+}
diff --git a/.changeset/quiet-rockets-dream.md b/.changeset/quiet-rockets-dream.md
new file mode 100644
index 00000000..e1f7571e
--- /dev/null
+++ b/.changeset/quiet-rockets-dream.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+feat(plugin): add new zodios plugin system
diff --git a/.changeset/rare-zoos-serve.md b/.changeset/rare-zoos-serve.md
new file mode 100644
index 00000000..92d4bb31
--- /dev/null
+++ b/.changeset/rare-zoos-serve.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+chore(deps): update typescript
diff --git a/.changeset/rich-pigs-thank.md b/.changeset/rich-pigs-thank.md
new file mode 100644
index 00000000..edd7998f
--- /dev/null
+++ b/.changeset/rich-pigs-thank.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+fix(react): bump version
diff --git a/.changeset/short-hounds-mix.md b/.changeset/short-hounds-mix.md
new file mode 100644
index 00000000..d8422aee
--- /dev/null
+++ b/.changeset/short-hounds-mix.md
@@ -0,0 +1,7 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+---
+
+add basic mocks helpers
diff --git a/.changeset/silent-garlics-scream.md b/.changeset/silent-garlics-scream.md
new file mode 100644
index 00000000..3dd43a4c
--- /dev/null
+++ b/.changeset/silent-garlics-scream.md
@@ -0,0 +1,6 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+---
+
+sync axios and core versions
diff --git a/.changeset/slimy-pugs-melt.md b/.changeset/slimy-pugs-melt.md
new file mode 100644
index 00000000..c66680b1
--- /dev/null
+++ b/.changeset/slimy-pugs-melt.md
@@ -0,0 +1,7 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+---
+
+tests(core): fix tests
diff --git a/.changeset/slow-worms-destroy.md b/.changeset/slow-worms-destroy.md
new file mode 100644
index 00000000..092f0a99
--- /dev/null
+++ b/.changeset/slow-worms-destroy.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+refactor: factor http verbs
diff --git a/.changeset/small-horses-laugh.md b/.changeset/small-horses-laugh.md
new file mode 100644
index 00000000..9c04282d
--- /dev/null
+++ b/.changeset/small-horses-laugh.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+chore: fix type exports for nodenext
diff --git a/.changeset/soft-seas-lie.md b/.changeset/soft-seas-lie.md
new file mode 100644
index 00000000..ac75425e
--- /dev/null
+++ b/.changeset/soft-seas-lie.md
@@ -0,0 +1,8 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/testing": major
+---
+
+refactor(testing): move base hooks to testing
diff --git a/.changeset/tasty-bags-happen.md b/.changeset/tasty-bags-happen.md
new file mode 100644
index 00000000..116d6243
--- /dev/null
+++ b/.changeset/tasty-bags-happen.md
@@ -0,0 +1,7 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+---
+
+chore(fetch): fix deps
diff --git a/.changeset/twelve-dingos-cover.md b/.changeset/twelve-dingos-cover.md
new file mode 100644
index 00000000..90835623
--- /dev/null
+++ b/.changeset/twelve-dingos-cover.md
@@ -0,0 +1,9 @@
+---
+"@zodios/axios": major
+"@zodios/core": major
+"@zodios/fetch": major
+"@zodios/react": major
+"@zodios/testing": major
+---
+
+feat(react): simplify exported instance
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4edc70f1..17f80cdd 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,17 +7,17 @@ on:
push:
branches: [main]
paths:
- - src/**
- - yarn.lock
+ - packages/**
+ - pnpm-lock.yaml
- package.json
- - tsconfig.json
+ - .github/workflows/ci.yml
pull_request:
branches: [main]
paths:
- - src/**
- - yarn.lock
+ - packages/**
+ - pnpm-lock.yaml
- package.json
- - tsconfig.json
+ - .github/workflows/ci.yml
jobs:
build:
@@ -29,15 +29,20 @@ jobs:
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- - uses: actions/checkout@v3
+ - name: Checkout
+ uses: actions/checkout@v3
+ - name: Install pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ version: 7
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- cache: "yarn"
- - run: yarn install --ignore-engines
- - run: yarn build
- - run: yarn test
+ cache: "pnpm"
+ - run: pnpm install
+ - run: pnpm build
+ - run: pnpm test
analyze:
name: Analyze
runs-on: ubuntu-latest
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
deleted file mode 100644
index 2e39c9cf..00000000
--- a/.github/workflows/publish.yml
+++ /dev/null
@@ -1,66 +0,0 @@
-# publish on npm when there is a new version tag
-
-name: publish
-on:
- push:
- tags: [v*]
-
-jobs:
- publish:
- runs-on: ubuntu-latest
- strategy:
- matrix:
- node-version: [16.x]
- steps:
- - uses: actions/checkout@v3
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v3
- with:
- registry-url: "https://registry.npmjs.org"
- node-version: ${{ matrix.node-version }}
- cache: "yarn"
- - name: install dependencies
- run: yarn install
- - name: build
- run: yarn build
- - name: run test
- run: yarn test
- - name: publish to npm
- # only run when tag has no 'rc' in it
- if: ${{ !contains(github.ref, 'rc') }}
- run: yarn publish --access public
- env:
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- - name: publish beta to npm
- # only run when tag has 'rc' in it
- if: ${{ contains(github.ref, 'rc') }}
- run: yarn publish --access public --tag beta
- env:
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- - name: generate changelog
- uses: orhun/git-cliff-action@v2
- id: cliff
- with:
- args: --latest --strip footer
- env:
- OUTPUT: CHANGES.md
- - name: save changelog
- id: changelog
- shell: bash
- run: |
- changelog=$(cat ${{ steps.cliff.outputs.changelog }})
- changelog="${changelog//'%'/'%25'}"
- changelog="${changelog//$'\n'/'%0A'}"
- changelog="${changelog//$'\r'/'%0D'}"
- echo "changelog=$changelog" >> $GITHUB_OUTPUT
- - name: create release
- id: release
- uses: actions/create-release@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- tag_name: ${{ github.ref }}
- release_name: Release ${{ github.ref }}
- body: ${{ steps.changelog.outputs.changelog }}
- draft: false
- prerelease: false
diff --git a/.gitignore b/.gitignore
index 325cfc22..0af2e3cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -106,3 +106,8 @@ lib
# Developpement directory
.devcontainer
+# Turbo
+.turbo
+
+# Output
+lib/**
diff --git a/examples/next-turbo/.eslintrc.js b/examples/next-turbo/.eslintrc.js
new file mode 100644
index 00000000..5b999efa
--- /dev/null
+++ b/examples/next-turbo/.eslintrc.js
@@ -0,0 +1,10 @@
+module.exports = {
+ root: true,
+ // This tells ESLint to load the config from the package `eslint-config-custom`
+ extends: ["custom"],
+ settings: {
+ next: {
+ rootDir: ["apps/*/"],
+ },
+ },
+};
diff --git a/examples/next-turbo/.gitignore b/examples/next-turbo/.gitignore
new file mode 100644
index 00000000..849425fe
--- /dev/null
+++ b/examples/next-turbo/.gitignore
@@ -0,0 +1,33 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+node_modules
+.pnp
+.pnp.js
+
+# testing
+coverage
+
+# next.js
+.next/
+out/
+build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+.pnpm-debug.log*
+
+# local env files
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+# turbo
+.turbo
diff --git a/examples/next-turbo/README.md b/examples/next-turbo/README.md
new file mode 100644
index 00000000..760edf2b
--- /dev/null
+++ b/examples/next-turbo/README.md
@@ -0,0 +1,73 @@
+# Turborepo starter
+
+This is an official pnpm starter turborepo.
+
+## What's inside?
+
+This turborepo uses [pnpm](https://pnpm.io) as a package manager. It includes the following packages/apps:
+
+### Apps and Packages
+
+- `docs`: a [Next.js](https://nextjs.org) app
+- `web`: another [Next.js](https://nextjs.org) app
+- `ui`: a stub React component library shared by both `web` and `docs` applications
+- `eslint-config-custom`: `eslint` configurations (includes `eslint-config-next` and `eslint-config-prettier`)
+- `tsconfig`: `tsconfig.json`s used throughout the monorepo
+
+Each package/app is 100% [TypeScript](https://www.typescriptlang.org/).
+
+### Utilities
+
+This turborepo has some additional tools already setup for you:
+
+- [TypeScript](https://www.typescriptlang.org/) for static type checking
+- [ESLint](https://eslint.org/) for code linting
+- [Prettier](https://prettier.io) for code formatting
+
+### Build
+
+To build all apps and packages, run the following command:
+
+```
+cd my-turborepo
+pnpm run build
+```
+
+### Develop
+
+To develop all apps and packages, run the following command:
+
+```
+cd my-turborepo
+pnpm run dev
+```
+
+### Remote Caching
+
+Turborepo can use a technique known as [Remote Caching](https://turborepo.org/docs/core-concepts/remote-caching) to share cache artifacts across machines, enabling you to share build caches with your team and CI/CD pipelines.
+
+By default, Turborepo will cache locally. To enable Remote Caching you will need an account with Vercel. If you don't have an account you can [create one](https://vercel.com/signup), then enter the following commands:
+
+```
+cd my-turborepo
+pnpm dlx turbo login
+```
+
+This will authenticate the Turborepo CLI with your [Vercel account](https://vercel.com/docs/concepts/personal-accounts/overview).
+
+Next, you can link your Turborepo to your Remote Cache by running the following command from the root of your turborepo:
+
+```
+pnpm dlx turbo link
+```
+
+## Useful Links
+
+Learn more about the power of Turborepo:
+
+- [Pipelines](https://turborepo.org/docs/core-concepts/pipelines)
+- [Caching](https://turborepo.org/docs/core-concepts/caching)
+- [Remote Caching](https://turborepo.org/docs/core-concepts/remote-caching)
+- [Scoped Tasks](https://turborepo.org/docs/core-concepts/scopes)
+- [Configuration Options](https://turborepo.org/docs/reference/configuration)
+- [CLI Usage](https://turborepo.org/docs/reference/command-line-reference)
diff --git a/examples/next-turbo/apps/docs/.eslintrc.js b/examples/next-turbo/apps/docs/.eslintrc.js
new file mode 100644
index 00000000..c8df6075
--- /dev/null
+++ b/examples/next-turbo/apps/docs/.eslintrc.js
@@ -0,0 +1,4 @@
+module.exports = {
+ root: true,
+ extends: ["custom"],
+};
diff --git a/examples/next-turbo/apps/docs/README.md b/examples/next-turbo/apps/docs/README.md
new file mode 100644
index 00000000..1d67ece7
--- /dev/null
+++ b/examples/next-turbo/apps/docs/README.md
@@ -0,0 +1,30 @@
+## Getting Started
+
+First, run the development server:
+
+```bash
+yarn dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
+
+[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
+
+The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_source=github.com&utm_medium=referral&utm_campaign=turborepo-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
diff --git a/examples/next-turbo/apps/docs/next-env.d.ts b/examples/next-turbo/apps/docs/next-env.d.ts
new file mode 100644
index 00000000..4f11a03d
--- /dev/null
+++ b/examples/next-turbo/apps/docs/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/examples/next-turbo/apps/docs/next.config.js b/examples/next-turbo/apps/docs/next.config.js
new file mode 100644
index 00000000..5e578c4f
--- /dev/null
+++ b/examples/next-turbo/apps/docs/next.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ reactStrictMode: true,
+ experimental: {
+ transpilePackages: ["ui"],
+ },
+};
diff --git a/examples/next-turbo/apps/docs/package.json b/examples/next-turbo/apps/docs/package.json
new file mode 100644
index 00000000..4c1d7760
--- /dev/null
+++ b/examples/next-turbo/apps/docs/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "docs",
+ "version": "0.0.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev --port 3001",
+ "build": "next build",
+ "start": "next start",
+ "lint": "next lint"
+ },
+ "dependencies": {
+ "next": "12.3.1",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "ui": "workspace:*"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.0.0",
+ "eslint-config-custom": "workspace:*",
+ "eslint": "7.32.0",
+ "tsconfig": "workspace:*",
+ "@types/node": "^17.0.12",
+ "@types/react": "^18.0.22",
+ "@types/react-dom": "^18.0.7",
+ "typescript": "5.0.2"
+ }
+}
diff --git a/examples/next-turbo/apps/docs/pages/index.tsx b/examples/next-turbo/apps/docs/pages/index.tsx
new file mode 100644
index 00000000..0d1dabc1
--- /dev/null
+++ b/examples/next-turbo/apps/docs/pages/index.tsx
@@ -0,0 +1,10 @@
+import { Button } from "ui";
+
+export default function Docs() {
+ return (
+
+
Docs
+
+
+ );
+}
diff --git a/examples/next-turbo/apps/docs/tsconfig.json b/examples/next-turbo/apps/docs/tsconfig.json
new file mode 100644
index 00000000..a355365b
--- /dev/null
+++ b/examples/next-turbo/apps/docs/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "tsconfig/nextjs.json",
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}
diff --git a/examples/next-turbo/apps/web/.eslintrc.js b/examples/next-turbo/apps/web/.eslintrc.js
new file mode 100644
index 00000000..c8df6075
--- /dev/null
+++ b/examples/next-turbo/apps/web/.eslintrc.js
@@ -0,0 +1,4 @@
+module.exports = {
+ root: true,
+ extends: ["custom"],
+};
diff --git a/examples/next-turbo/apps/web/README.md b/examples/next-turbo/apps/web/README.md
new file mode 100644
index 00000000..1d67ece7
--- /dev/null
+++ b/examples/next-turbo/apps/web/README.md
@@ -0,0 +1,30 @@
+## Getting Started
+
+First, run the development server:
+
+```bash
+yarn dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
+
+[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
+
+The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_source=github.com&utm_medium=referral&utm_campaign=turborepo-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
diff --git a/examples/next-turbo/apps/web/common/api.ts b/examples/next-turbo/apps/web/common/api.ts
new file mode 100644
index 00000000..f97e053b
--- /dev/null
+++ b/examples/next-turbo/apps/web/common/api.ts
@@ -0,0 +1,13 @@
+import { makeApi } from "@zodios/core";
+import z from "zod";
+
+export const api = makeApi([
+ {
+ method: "get",
+ path: "/health",
+ alias: "health",
+ response: z.object({
+ status: z.literal("ok"),
+ }),
+ },
+]);
diff --git a/examples/next-turbo/apps/web/next-env.d.ts b/examples/next-turbo/apps/web/next-env.d.ts
new file mode 100644
index 00000000..4f11a03d
--- /dev/null
+++ b/examples/next-turbo/apps/web/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/examples/next-turbo/apps/web/next.config.js b/examples/next-turbo/apps/web/next.config.js
new file mode 100644
index 00000000..5e578c4f
--- /dev/null
+++ b/examples/next-turbo/apps/web/next.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ reactStrictMode: true,
+ experimental: {
+ transpilePackages: ["ui"],
+ },
+};
diff --git a/examples/next-turbo/apps/web/package.json b/examples/next-turbo/apps/web/package.json
new file mode 100644
index 00000000..8b068186
--- /dev/null
+++ b/examples/next-turbo/apps/web/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "web",
+ "version": "0.0.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "next lint"
+ },
+ "dependencies": {
+ "@tanstack/react-query": "^4.13.0",
+ "@zodios/core": "^10.4.3",
+ "@zodios/express": "^10.4.2",
+ "@zodios/react": "^10.3.3",
+ "axios": "^1.1.3",
+ "express": "^4.18.2",
+ "next": "12.3.2-canary.40",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "ui": "workspace:0.0.0",
+ "zod": "^3.19.1"
+ },
+ "devDependencies": {
+ "@babel/core": "^7.19.6",
+ "@types/express": "^4.17.14",
+ "@types/node": "^17.0.45",
+ "@types/react": "^18.0.24",
+ "@types/react-dom": "^18.0.8",
+ "eslint": "7.32.0",
+ "eslint-config-custom": "workspace:0.0.0",
+ "tsconfig": "workspace:0.0.0",
+ "typescript": "5.0.2"
+ }
+}
diff --git a/examples/next-turbo/apps/web/pages/_app.tsx b/examples/next-turbo/apps/web/pages/_app.tsx
new file mode 100644
index 00000000..3c79ddbb
--- /dev/null
+++ b/examples/next-turbo/apps/web/pages/_app.tsx
@@ -0,0 +1,14 @@
+import type { AppProps } from "next/app";
+import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
+
+const queryClient = new QueryClient();
+
+function MyApp({ Component, pageProps }: AppProps) {
+ return (
+
+
+
+ );
+}
+
+export default MyApp;
diff --git a/examples/next-turbo/apps/web/pages/api/[...zodios].ts b/examples/next-turbo/apps/web/pages/api/[...zodios].ts
new file mode 100644
index 00000000..0d172f46
--- /dev/null
+++ b/examples/next-turbo/apps/web/pages/api/[...zodios].ts
@@ -0,0 +1,3 @@
+import { app } from "../../server/routers/app";
+
+export default app;
diff --git a/examples/next-turbo/apps/web/pages/index.tsx b/examples/next-turbo/apps/web/pages/index.tsx
new file mode 100644
index 00000000..62496a53
--- /dev/null
+++ b/examples/next-turbo/apps/web/pages/index.tsx
@@ -0,0 +1,23 @@
+import { Button } from "ui";
+import { api } from "../common/api";
+import { Zodios } from "@zodios/core";
+import { ZodiosHooks } from "@zodios/react";
+
+const zodios = new Zodios("/api", api);
+const zodiosHooks = new ZodiosHooks("health", zodios);
+
+export default function Web() {
+ const { data: health, isLoading } = zodiosHooks.useHealth();
+ return (
+
+
Health Status
+ {isLoading ? (
+
Loading...
+ ) : (
+
+ Status: {health?.status}
+
+ )}
+
+ );
+}
diff --git a/examples/next-turbo/apps/web/server/context.ts b/examples/next-turbo/apps/web/server/context.ts
new file mode 100644
index 00000000..5583411e
--- /dev/null
+++ b/examples/next-turbo/apps/web/server/context.ts
@@ -0,0 +1,11 @@
+import { zodiosContext } from "@zodios/express";
+import z from "zod";
+
+export const ctx = zodiosContext(
+ z.object({
+ user: z.object({
+ id: z.string(),
+ name: z.string(),
+ }),
+ })
+);
diff --git a/examples/next-turbo/apps/web/server/routers/app.ts b/examples/next-turbo/apps/web/server/routers/app.ts
new file mode 100644
index 00000000..c8c53357
--- /dev/null
+++ b/examples/next-turbo/apps/web/server/routers/app.ts
@@ -0,0 +1,10 @@
+import { ctx } from "../context";
+import { api } from "../../common/api";
+
+export const app = ctx.nextApp();
+const router = ctx.router(api);
+app.use("/api", router);
+
+router.get("/health", (req, res) => {
+ res.status(200).json({ status: "ok" });
+});
diff --git a/examples/next-turbo/apps/web/tsconfig.json b/examples/next-turbo/apps/web/tsconfig.json
new file mode 100644
index 00000000..a355365b
--- /dev/null
+++ b/examples/next-turbo/apps/web/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "tsconfig/nextjs.json",
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}
diff --git a/examples/next-turbo/package.json b/examples/next-turbo/package.json
new file mode 100644
index 00000000..c49485d1
--- /dev/null
+++ b/examples/next-turbo/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "zodios-turbo",
+ "version": "0.0.0",
+ "private": true,
+ "workspaces": [
+ "apps/*",
+ "packages/*"
+ ],
+ "scripts": {
+ "build": "turbo run build",
+ "dev": "turbo run dev --parallel",
+ "lint": "turbo run lint",
+ "format": "prettier --write \"**/*.{ts,tsx,md}\""
+ },
+ "devDependencies": {
+ "eslint-config-custom": "workspace:*",
+ "prettier": "latest",
+ "turbo": "latest"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "dependencies": {},
+ "packageManager": "pnpm@7.14.0"
+}
\ No newline at end of file
diff --git a/examples/next-turbo/packages/eslint-config-custom/index.js b/examples/next-turbo/packages/eslint-config-custom/index.js
new file mode 100644
index 00000000..2ea526a5
--- /dev/null
+++ b/examples/next-turbo/packages/eslint-config-custom/index.js
@@ -0,0 +1,7 @@
+module.exports = {
+ extends: ["next", "turbo", "prettier"],
+ rules: {
+ "@next/next/no-html-link-for-pages": "off",
+ "react/jsx-key": "off",
+ },
+};
diff --git a/examples/next-turbo/packages/eslint-config-custom/package.json b/examples/next-turbo/packages/eslint-config-custom/package.json
new file mode 100644
index 00000000..ee80e8fb
--- /dev/null
+++ b/examples/next-turbo/packages/eslint-config-custom/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "eslint-config-custom",
+ "version": "0.0.0",
+ "main": "index.js",
+ "license": "MIT",
+ "dependencies": {
+ "eslint": "^7.23.0",
+ "eslint-config-next": "^12.0.8",
+ "eslint-config-prettier": "^8.3.0",
+ "eslint-plugin-react": "7.31.8",
+ "eslint-config-turbo": "latest"
+ },
+ "devDependencies": {
+ "typescript": "5.0.2"
+ },
+ "publishConfig": {
+ "access": "public"
+ }
+}
diff --git a/examples/next-turbo/packages/tsconfig/README.md b/examples/next-turbo/packages/tsconfig/README.md
new file mode 100644
index 00000000..0da79cf2
--- /dev/null
+++ b/examples/next-turbo/packages/tsconfig/README.md
@@ -0,0 +1,3 @@
+# `tsconfig`
+
+These are base shared `tsconfig.json`s from which all other `tsconfig.json`'s inherit from.
diff --git a/examples/next-turbo/packages/tsconfig/base.json b/examples/next-turbo/packages/tsconfig/base.json
new file mode 100644
index 00000000..d72a9f3a
--- /dev/null
+++ b/examples/next-turbo/packages/tsconfig/base.json
@@ -0,0 +1,20 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "Default",
+ "compilerOptions": {
+ "composite": false,
+ "declaration": true,
+ "declarationMap": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "inlineSources": false,
+ "isolatedModules": true,
+ "moduleResolution": "node",
+ "noUnusedLocals": false,
+ "noUnusedParameters": false,
+ "preserveWatchOutput": true,
+ "skipLibCheck": true,
+ "strict": true
+ },
+ "exclude": ["node_modules"]
+}
diff --git a/examples/next-turbo/packages/tsconfig/nextjs.json b/examples/next-turbo/packages/tsconfig/nextjs.json
new file mode 100644
index 00000000..cd9cd38f
--- /dev/null
+++ b/examples/next-turbo/packages/tsconfig/nextjs.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "Next.js",
+ "extends": "./base.json",
+ "compilerOptions": {
+ "target": "ES6",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "incremental": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "Node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve"
+ },
+ "include": ["src", "next-env.d.ts"],
+ "exclude": ["node_modules"]
+}
diff --git a/examples/next-turbo/packages/tsconfig/package.json b/examples/next-turbo/packages/tsconfig/package.json
new file mode 100644
index 00000000..f4810fc3
--- /dev/null
+++ b/examples/next-turbo/packages/tsconfig/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "tsconfig",
+ "version": "0.0.0",
+ "private": true,
+ "files": [
+ "base.json",
+ "nextjs.json",
+ "react-library.json"
+ ]
+}
diff --git a/examples/next-turbo/packages/tsconfig/react-library.json b/examples/next-turbo/packages/tsconfig/react-library.json
new file mode 100644
index 00000000..af8711c5
--- /dev/null
+++ b/examples/next-turbo/packages/tsconfig/react-library.json
@@ -0,0 +1,11 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "display": "React Library",
+ "extends": "./base.json",
+ "compilerOptions": {
+ "jsx": "react-jsx",
+ "lib": ["ES2015"],
+ "module": "ESNext",
+ "target": "es6"
+ }
+}
diff --git a/examples/next-turbo/packages/ui/Button.tsx b/examples/next-turbo/packages/ui/Button.tsx
new file mode 100644
index 00000000..7d5c6a73
--- /dev/null
+++ b/examples/next-turbo/packages/ui/Button.tsx
@@ -0,0 +1,4 @@
+import * as React from "react";
+export const Button = () => {
+ return ;
+};
diff --git a/examples/next-turbo/packages/ui/index.tsx b/examples/next-turbo/packages/ui/index.tsx
new file mode 100644
index 00000000..916730e8
--- /dev/null
+++ b/examples/next-turbo/packages/ui/index.tsx
@@ -0,0 +1,2 @@
+import * as React from "react";
+export * from "./Button";
diff --git a/examples/next-turbo/packages/ui/package.json b/examples/next-turbo/packages/ui/package.json
new file mode 100644
index 00000000..9cd2ee44
--- /dev/null
+++ b/examples/next-turbo/packages/ui/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "ui",
+ "version": "0.0.0",
+ "main": "./index.tsx",
+ "types": "./index.tsx",
+ "license": "MIT",
+ "scripts": {
+ "lint": "eslint *.ts*"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.17",
+ "@types/react-dom": "^18.0.6",
+ "eslint": "^7.32.0",
+ "eslint-config-custom": "workspace:*",
+ "react": "^18.2.0",
+ "tsconfig": "workspace:*",
+ "typescript": "5.0.2"
+ }
+}
diff --git a/examples/next-turbo/packages/ui/tsconfig.json b/examples/next-turbo/packages/ui/tsconfig.json
new file mode 100644
index 00000000..cd6c94d6
--- /dev/null
+++ b/examples/next-turbo/packages/ui/tsconfig.json
@@ -0,0 +1,5 @@
+{
+ "extends": "tsconfig/react-library.json",
+ "include": ["."],
+ "exclude": ["dist", "build", "node_modules"]
+}
diff --git a/examples/next-turbo/pnpm-lock.yaml b/examples/next-turbo/pnpm-lock.yaml
new file mode 100644
index 00000000..019267c5
--- /dev/null
+++ b/examples/next-turbo/pnpm-lock.yaml
@@ -0,0 +1,3019 @@
+lockfileVersion: 5.4
+
+importers:
+
+ .:
+ specifiers:
+ eslint-config-custom: workspace:*
+ prettier: latest
+ turbo: latest
+ devDependencies:
+ eslint-config-custom: link:packages/eslint-config-custom
+ prettier: 2.7.1
+ turbo: 1.6.2
+
+ apps/docs:
+ specifiers:
+ '@babel/core': ^7.0.0
+ '@types/node': ^17.0.12
+ '@types/react': ^18.0.22
+ '@types/react-dom': ^18.0.7
+ eslint: 7.32.0
+ eslint-config-custom: workspace:*
+ next: 12.3.1
+ react: 18.2.0
+ react-dom: 18.2.0
+ tsconfig: workspace:*
+ typescript: ^4.5.3
+ ui: workspace:*
+ dependencies:
+ next: 12.3.1_qtpcxnaaarbm4ws7ughq6oxfve
+ react: 18.2.0
+ react-dom: 18.2.0_react@18.2.0
+ ui: link:../../packages/ui
+ devDependencies:
+ '@babel/core': 7.19.6
+ '@types/node': 17.0.45
+ '@types/react': 18.0.24
+ '@types/react-dom': 18.0.8
+ eslint: 7.32.0
+ eslint-config-custom: link:../../packages/eslint-config-custom
+ tsconfig: link:../../packages/tsconfig
+ typescript: 4.8.4
+
+ apps/web:
+ specifiers:
+ '@babel/core': ^7.19.6
+ '@tanstack/react-query': ^4.13.0
+ '@types/express': ^4.17.14
+ '@types/node': ^17.0.45
+ '@types/react': ^18.0.24
+ '@types/react-dom': ^18.0.8
+ '@zodios/core': ^10.4.3
+ '@zodios/express': ^10.4.2
+ '@zodios/react': ^10.3.3
+ axios: ^1.1.3
+ eslint: 7.32.0
+ eslint-config-custom: workspace:0.0.0
+ express: ^4.18.2
+ next: 12.3.2-canary.40
+ react: 18.2.0
+ react-dom: 18.2.0
+ tsconfig: workspace:0.0.0
+ typescript: ^4.8.4
+ ui: workspace:0.0.0
+ zod: ^3.19.1
+ dependencies:
+ '@tanstack/react-query': 4.13.0_biqbaboplfbrettd7655fr4n2y
+ '@types/express': 4.17.14
+ '@zodios/core': 10.4.3_axios@1.1.3+zod@3.19.1
+ '@zodios/express': 10.4.2_za6leqvtaqdjr5gzlbrsemzpwi
+ '@zodios/react': 10.3.3_tbpsitbqmenqxmwimr6kvnccvq
+ axios: 1.1.3
+ express: 4.18.2
+ next: 12.3.2-canary.40_qtpcxnaaarbm4ws7ughq6oxfve
+ react: 18.2.0
+ react-dom: 18.2.0_react@18.2.0
+ ui: link:../../packages/ui
+ zod: 3.19.1
+ devDependencies:
+ '@babel/core': 7.19.6
+ '@types/node': 17.0.45
+ '@types/react': 18.0.24
+ '@types/react-dom': 18.0.8
+ eslint: 7.32.0
+ eslint-config-custom: link:../../packages/eslint-config-custom
+ tsconfig: link:../../packages/tsconfig
+ typescript: 4.8.4
+
+ packages/eslint-config-custom:
+ specifiers:
+ eslint: ^7.23.0
+ eslint-config-next: ^12.0.8
+ eslint-config-prettier: ^8.3.0
+ eslint-config-turbo: latest
+ eslint-plugin-react: 7.31.8
+ typescript: ^4.7.4
+ dependencies:
+ eslint: 7.32.0
+ eslint-config-next: 12.3.1_3rubbgt5ekhqrcgx4uwls3neim
+ eslint-config-prettier: 8.5.0_eslint@7.32.0
+ eslint-config-turbo: 0.0.4_eslint@7.32.0
+ eslint-plugin-react: 7.31.8_eslint@7.32.0
+ devDependencies:
+ typescript: 4.8.4
+
+ packages/tsconfig:
+ specifiers: {}
+
+ packages/ui:
+ specifiers:
+ '@types/react': ^18.0.17
+ '@types/react-dom': ^18.0.6
+ eslint: ^7.32.0
+ eslint-config-custom: workspace:*
+ react: ^18.2.0
+ tsconfig: workspace:*
+ typescript: ^4.5.2
+ devDependencies:
+ '@types/react': 18.0.24
+ '@types/react-dom': 18.0.8
+ eslint: 7.32.0
+ eslint-config-custom: link:../eslint-config-custom
+ react: 18.2.0
+ tsconfig: link:../tsconfig
+ typescript: 4.8.4
+
+packages:
+
+ /@ampproject/remapping/2.2.0:
+ resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/gen-mapping': 0.1.1
+ '@jridgewell/trace-mapping': 0.3.17
+
+ /@babel/code-frame/7.12.11:
+ resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==}
+ dependencies:
+ '@babel/highlight': 7.18.6
+
+ /@babel/code-frame/7.18.6:
+ resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/highlight': 7.18.6
+
+ /@babel/compat-data/7.20.0:
+ resolution: {integrity: sha512-Gt9jszFJYq7qzXVK4slhc6NzJXnOVmRECWcVjF/T23rNXD9NtWQ0W3qxdg+p9wWIB+VQw3GYV/U2Ha9bRTfs4w==}
+ engines: {node: '>=6.9.0'}
+
+ /@babel/core/7.19.6:
+ resolution: {integrity: sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@ampproject/remapping': 2.2.0
+ '@babel/code-frame': 7.18.6
+ '@babel/generator': 7.20.0
+ '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.19.6
+ '@babel/helper-module-transforms': 7.19.6
+ '@babel/helpers': 7.20.0
+ '@babel/parser': 7.20.0
+ '@babel/template': 7.18.10
+ '@babel/traverse': 7.20.0
+ '@babel/types': 7.20.0
+ convert-source-map: 1.9.0
+ debug: 4.3.4
+ gensync: 1.0.0-beta.2
+ json5: 2.2.1
+ semver: 6.3.0
+ transitivePeerDependencies:
+ - supports-color
+
+ /@babel/generator/7.20.0:
+ resolution: {integrity: sha512-GUPcXxWibClgmYJuIwC2Bc2Lg+8b9VjaJ+HlNdACEVt+Wlr1eoU1OPZjZRm7Hzl0gaTsUZNQfeihvZJhG7oc3w==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.20.0
+ '@jridgewell/gen-mapping': 0.3.2
+ jsesc: 2.5.2
+
+ /@babel/helper-compilation-targets/7.20.0_@babel+core@7.19.6:
+ resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+ dependencies:
+ '@babel/compat-data': 7.20.0
+ '@babel/core': 7.19.6
+ '@babel/helper-validator-option': 7.18.6
+ browserslist: 4.21.4
+ semver: 6.3.0
+
+ /@babel/helper-environment-visitor/7.18.9:
+ resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==}
+ engines: {node: '>=6.9.0'}
+
+ /@babel/helper-function-name/7.19.0:
+ resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/template': 7.18.10
+ '@babel/types': 7.20.0
+
+ /@babel/helper-hoist-variables/7.18.6:
+ resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.20.0
+
+ /@babel/helper-module-imports/7.18.6:
+ resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.20.0
+
+ /@babel/helper-module-transforms/7.19.6:
+ resolution: {integrity: sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-environment-visitor': 7.18.9
+ '@babel/helper-module-imports': 7.18.6
+ '@babel/helper-simple-access': 7.19.4
+ '@babel/helper-split-export-declaration': 7.18.6
+ '@babel/helper-validator-identifier': 7.19.1
+ '@babel/template': 7.18.10
+ '@babel/traverse': 7.20.0
+ '@babel/types': 7.20.0
+ transitivePeerDependencies:
+ - supports-color
+
+ /@babel/helper-simple-access/7.19.4:
+ resolution: {integrity: sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.20.0
+
+ /@babel/helper-split-export-declaration/7.18.6:
+ resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/types': 7.20.0
+
+ /@babel/helper-string-parser/7.19.4:
+ resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==}
+ engines: {node: '>=6.9.0'}
+
+ /@babel/helper-validator-identifier/7.19.1:
+ resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
+ engines: {node: '>=6.9.0'}
+
+ /@babel/helper-validator-option/7.18.6:
+ resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==}
+ engines: {node: '>=6.9.0'}
+
+ /@babel/helpers/7.20.0:
+ resolution: {integrity: sha512-aGMjYraN0zosCEthoGLdqot1oRsmxVTQRHadsUPz5QM44Zej2PYRz7XiDE7GqnkZnNtLbOuxqoZw42vkU7+XEQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/template': 7.18.10
+ '@babel/traverse': 7.20.0
+ '@babel/types': 7.20.0
+ transitivePeerDependencies:
+ - supports-color
+
+ /@babel/highlight/7.18.6:
+ resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-validator-identifier': 7.19.1
+ chalk: 2.4.2
+ js-tokens: 4.0.0
+
+ /@babel/parser/7.20.0:
+ resolution: {integrity: sha512-G9VgAhEaICnz8iiJeGJQyVl6J2nTjbW0xeisva0PK6XcKsga7BIaqm4ZF8Rg1Wbaqmy6znspNqhPaPkyukujzg==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+ dependencies:
+ '@babel/types': 7.20.0
+
+ /@babel/runtime-corejs3/7.20.0:
+ resolution: {integrity: sha512-v1JH7PeAAGBEyTQM9TqojVl+b20zXtesFKCJHu50xMxZKD1fX0TKaKHPsZfFkXfs7D1M9M6Eeqg1FkJ3a0x2dA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ core-js-pure: 3.26.0
+ regenerator-runtime: 0.13.10
+ dev: false
+
+ /@babel/runtime/7.20.0:
+ resolution: {integrity: sha512-NDYdls71fTXoU8TZHfbBWg7DiZfNzClcKui/+kyi6ppD2L1qnWW3VV6CjtaBXSUGGhiTWJ6ereOIkUvenif66Q==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ regenerator-runtime: 0.13.10
+ dev: false
+
+ /@babel/template/7.18.10:
+ resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.18.6
+ '@babel/parser': 7.20.0
+ '@babel/types': 7.20.0
+
+ /@babel/traverse/7.20.0:
+ resolution: {integrity: sha512-5+cAXQNARgjRUK0JWu2UBwja4JLSO/rBMPJzpsKb+oBF5xlUuCfljQepS4XypBQoiigL0VQjTZy6WiONtUdScQ==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/code-frame': 7.18.6
+ '@babel/generator': 7.20.0
+ '@babel/helper-environment-visitor': 7.18.9
+ '@babel/helper-function-name': 7.19.0
+ '@babel/helper-hoist-variables': 7.18.6
+ '@babel/helper-split-export-declaration': 7.18.6
+ '@babel/parser': 7.20.0
+ '@babel/types': 7.20.0
+ debug: 4.3.4
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+
+ /@babel/types/7.20.0:
+ resolution: {integrity: sha512-Jlgt3H0TajCW164wkTOTzHkZb075tMQMULzrLUoUeKmO7eFL96GgDxf7/Axhc5CAuKE3KFyVW1p6ysKsi2oXAg==}
+ engines: {node: '>=6.9.0'}
+ dependencies:
+ '@babel/helper-string-parser': 7.19.4
+ '@babel/helper-validator-identifier': 7.19.1
+ to-fast-properties: 2.0.0
+
+ /@eslint/eslintrc/0.4.3:
+ resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ ajv: 6.12.6
+ debug: 4.3.4
+ espree: 7.3.1
+ globals: 13.17.0
+ ignore: 4.0.6
+ import-fresh: 3.3.0
+ js-yaml: 3.14.1
+ minimatch: 3.1.2
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ /@humanwhocodes/config-array/0.5.0:
+ resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==}
+ engines: {node: '>=10.10.0'}
+ dependencies:
+ '@humanwhocodes/object-schema': 1.2.1
+ debug: 4.3.4
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ /@humanwhocodes/object-schema/1.2.1:
+ resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
+
+ /@jridgewell/gen-mapping/0.1.1:
+ resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/set-array': 1.1.2
+ '@jridgewell/sourcemap-codec': 1.4.14
+
+ /@jridgewell/gen-mapping/0.3.2:
+ resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ '@jridgewell/set-array': 1.1.2
+ '@jridgewell/sourcemap-codec': 1.4.14
+ '@jridgewell/trace-mapping': 0.3.17
+
+ /@jridgewell/resolve-uri/3.1.0:
+ resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
+ engines: {node: '>=6.0.0'}
+
+ /@jridgewell/set-array/1.1.2:
+ resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
+ engines: {node: '>=6.0.0'}
+
+ /@jridgewell/sourcemap-codec/1.4.14:
+ resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
+
+ /@jridgewell/trace-mapping/0.3.17:
+ resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==}
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.0
+ '@jridgewell/sourcemap-codec': 1.4.14
+
+ /@next/env/12.3.1:
+ resolution: {integrity: sha512-9P9THmRFVKGKt9DYqeC2aKIxm8rlvkK38V1P1sRE7qyoPBIs8l9oo79QoSdPtOWfzkbDAVUqvbQGgTMsb8BtJg==}
+ dev: false
+
+ /@next/env/12.3.2-canary.40:
+ resolution: {integrity: sha512-Fd6ZDf07ESDJ/C3IvmeWsXNyb6/BvlEM6KHoZU9l+Z/mqSH83T3AnVo44Rj7Pbr9K1aQvEq2qKW1zcsM4pZVwg==}
+ dev: false
+
+ /@next/eslint-plugin-next/12.3.1:
+ resolution: {integrity: sha512-sw+lTf6r6P0j+g/n9y4qdWWI2syPqZx+uc0+B/fRENqfR3KpSid6MIKqc9gNwGhJASazEQ5b3w8h4cAET213jw==}
+ dependencies:
+ glob: 7.1.7
+ dev: false
+
+ /@next/swc-android-arm-eabi/12.3.1:
+ resolution: {integrity: sha512-i+BvKA8tB//srVPPQxIQN5lvfROcfv4OB23/L1nXznP+N/TyKL8lql3l7oo2LNhnH66zWhfoemg3Q4VJZSruzQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-android-arm-eabi/12.3.2-canary.40:
+ resolution: {integrity: sha512-8WVCejEFzPeEouLd6DMjNLMVvVbG+Pw6S7QWPqxNPl5cCI4yem9zl+Niv5SI/DAQu6yBsRXBA50in/vx7NWKUA==}
+ engines: {node: '>= 10'}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-android-arm64/12.3.1:
+ resolution: {integrity: sha512-CmgU2ZNyBP0rkugOOqLnjl3+eRpXBzB/I2sjwcGZ7/Z6RcUJXK5Evz+N0ucOxqE4cZ3gkTeXtSzRrMK2mGYV8Q==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-android-arm64/12.3.2-canary.40:
+ resolution: {integrity: sha512-IG044VjmSwXV+zIgRFqgx9wX24M4IIhJgSnTwnTyE5fsbL0eA3VJ2s2Skb40/2y3PTG4EwNZDkpOzpNRWJ8o1A==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-darwin-arm64/12.3.1:
+ resolution: {integrity: sha512-hT/EBGNcu0ITiuWDYU9ur57Oa4LybD5DOQp4f22T6zLfpoBMfBibPtR8XktXmOyFHrL/6FC2p9ojdLZhWhvBHg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-darwin-arm64/12.3.2-canary.40:
+ resolution: {integrity: sha512-P3BrKMqSm2t330VbpdIKHnMjMrxGPEvjosYDh5boQu8+4KgdCcTEHhdrTRwf7hXVZB8ais9I4+YDFe92WY6sqQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-darwin-x64/12.3.1:
+ resolution: {integrity: sha512-9S6EVueCVCyGf2vuiLiGEHZCJcPAxglyckTZcEwLdJwozLqN0gtS0Eq0bQlGS3dH49Py/rQYpZ3KVWZ9BUf/WA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-darwin-x64/12.3.2-canary.40:
+ resolution: {integrity: sha512-3l2LNNrB/elk12ij7J6/SQHgpdWnrCZQgk501Hrtw7MoRW4Gu8Gee2FwubYGoL3dDe8cloVW04XlHrSAStS/Pg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-freebsd-x64/12.3.1:
+ resolution: {integrity: sha512-qcuUQkaBZWqzM0F1N4AkAh88lLzzpfE6ImOcI1P6YeyJSsBmpBIV8o70zV+Wxpc26yV9vpzb+e5gCyxNjKJg5Q==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-freebsd-x64/12.3.2-canary.40:
+ resolution: {integrity: sha512-ImJje/zx/07rreE6+MwKsSlYr0j+8MSIBWbHrKZ7Y2kUVA5bAIYPVj+BPLj1ckt9ezf1n4aDt7BSzbEc3mXMBw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [freebsd]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-arm-gnueabihf/12.3.1:
+ resolution: {integrity: sha512-diL9MSYrEI5nY2wc/h/DBewEDUzr/DqBjIgHJ3RUNtETAOB3spMNHvJk2XKUDjnQuluLmFMloet9tpEqU2TT9w==}
+ engines: {node: '>= 10'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-arm-gnueabihf/12.3.2-canary.40:
+ resolution: {integrity: sha512-7D80PEpsfYg0Cmjd530p0s2ald0p7u+jmgcZ3rCkW3uDWr27ve95vm/MnY2sC/DD8Lo7obFc9NQraKYtR8l9tg==}
+ engines: {node: '>= 10'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-arm64-gnu/12.3.1:
+ resolution: {integrity: sha512-o/xB2nztoaC7jnXU3Q36vGgOolJpsGG8ETNjxM1VAPxRwM7FyGCPHOMk1XavG88QZSQf+1r+POBW0tLxQOJ9DQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-arm64-gnu/12.3.2-canary.40:
+ resolution: {integrity: sha512-xu7dNJdJj4R61j5uHK/AGaQorLCD9CGq/SM2eKoXHvVHqffelKVAjflqXL2HzP6yQpHAIz4zIY20B/vIyIWHBA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-arm64-musl/12.3.1:
+ resolution: {integrity: sha512-2WEasRxJzgAmP43glFNhADpe8zB7kJofhEAVNbDJZANp+H4+wq+/cW1CdDi8DqjkShPEA6/ejJw+xnEyDID2jg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-arm64-musl/12.3.2-canary.40:
+ resolution: {integrity: sha512-eIqCjajoHAQAerQFiH0jMXjcDLcvL4a685JwKg1zr72eVLf/y0WVjLOtV43WmjcxPu369IJIztN8Y/5gti5wzg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-x64-gnu/12.3.1:
+ resolution: {integrity: sha512-JWEaMyvNrXuM3dyy9Pp5cFPuSSvG82+yABqsWugjWlvfmnlnx9HOQZY23bFq3cNghy5V/t0iPb6cffzRWylgsA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-x64-gnu/12.3.2-canary.40:
+ resolution: {integrity: sha512-yVdX9ZVfhHQ9ltsL4t2MllWyk0/RPg0rsCwx49df8eD56Q0PwHcsjfr7/+6RAOMVqDvek22u0QpedINTzSDH/g==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-x64-musl/12.3.1:
+ resolution: {integrity: sha512-xoEWQQ71waWc4BZcOjmatuvPUXKTv6MbIFzpm4LFeCHsg2iwai0ILmNXf81rJR+L1Wb9ifEke2sQpZSPNz1Iyg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-linux-x64-musl/12.3.2-canary.40:
+ resolution: {integrity: sha512-49WG2OIPT+FD8wc0junhRBvGAMLIKjwBf7Hrb0cX4Iev+Z/SIseXrASO8l5ADHM/DsGrb1tcVLjpQ/gPCdT48Q==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-win32-arm64-msvc/12.3.1:
+ resolution: {integrity: sha512-hswVFYQYIeGHE2JYaBVtvqmBQ1CppplQbZJS/JgrVI3x2CurNhEkmds/yqvDONfwfbttTtH4+q9Dzf/WVl3Opw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-win32-arm64-msvc/12.3.2-canary.40:
+ resolution: {integrity: sha512-8tLK6AjioExFX67BJ8lPQF7Rr+uqnMSIzAnQElDsBPGNORcrix6QMwNhiMCiqsPBwza3InAZ4qbz5E6bV1Y/fA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-win32-ia32-msvc/12.3.1:
+ resolution: {integrity: sha512-Kny5JBehkTbKPmqulr5i+iKntO5YMP+bVM8Hf8UAmjSMVo3wehyLVc9IZkNmcbxi+vwETnQvJaT5ynYBkJ9dWA==}
+ engines: {node: '>= 10'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-win32-ia32-msvc/12.3.2-canary.40:
+ resolution: {integrity: sha512-FCjSpNzKuH8LV0BuG49P9OoR7Yd+Tr1dgKv5zSEYqBgLuCmNEPcFZxcGMd7EidmeAh2Oz1IELk18pwgeNeW9IA==}
+ engines: {node: '>= 10'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-win32-x64-msvc/12.3.1:
+ resolution: {integrity: sha512-W1ijvzzg+kPEX6LAc+50EYYSEo0FVu7dmTE+t+DM4iOLqgGHoW9uYSz9wCVdkXOEEMP9xhXfGpcSxsfDucyPkA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@next/swc-win32-x64-msvc/12.3.2-canary.40:
+ resolution: {integrity: sha512-SNFJcSDvWq5p+3g0TqC7PPfpLIOwP5pBLBNg1i9LSEeULULMWzdnquPBnlEjKwgdqj7B34gHzTK8rApVJ1obVQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: false
+ optional: true
+
+ /@nodelib/fs.scandir/2.1.5:
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+ dev: false
+
+ /@nodelib/fs.stat/2.0.5:
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+ dev: false
+
+ /@nodelib/fs.walk/1.2.8:
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.13.0
+ dev: false
+
+ /@rushstack/eslint-patch/1.2.0:
+ resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==}
+ dev: false
+
+ /@swc/helpers/0.4.11:
+ resolution: {integrity: sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==}
+ dependencies:
+ tslib: 2.4.0
+ dev: false
+
+ /@tanstack/query-core/4.13.0:
+ resolution: {integrity: sha512-PzmLQcEgC4rl2OzkiPHYPC9O79DFcMGaKsOzDEP+U4PJ+tbkcEP+Z+FQDlfvX8mCwYC7UNH7hXrQ5EdkGlJjVg==}
+ dev: false
+
+ /@tanstack/react-query/4.13.0_biqbaboplfbrettd7655fr4n2y:
+ resolution: {integrity: sha512-dI/5hJ/pGQ74P5hxBLC9h6K0/Cap2T3k0ZjjjFLBCNnohDYgl7LNmMopzrRzBHk2mMjf2hgXHIzcKNG8GOZ5hg==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-native: '*'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+ dependencies:
+ '@tanstack/query-core': 4.13.0
+ react: 18.2.0
+ react-dom: 18.2.0_react@18.2.0
+ use-sync-external-store: 1.2.0_react@18.2.0
+ dev: false
+
+ /@types/body-parser/1.19.2:
+ resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==}
+ dependencies:
+ '@types/connect': 3.4.35
+ '@types/node': 17.0.45
+ dev: false
+
+ /@types/connect/3.4.35:
+ resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==}
+ dependencies:
+ '@types/node': 17.0.45
+ dev: false
+
+ /@types/express-serve-static-core/4.17.31:
+ resolution: {integrity: sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==}
+ dependencies:
+ '@types/node': 17.0.45
+ '@types/qs': 6.9.7
+ '@types/range-parser': 1.2.4
+ dev: false
+
+ /@types/express/4.17.14:
+ resolution: {integrity: sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==}
+ dependencies:
+ '@types/body-parser': 1.19.2
+ '@types/express-serve-static-core': 4.17.31
+ '@types/qs': 6.9.7
+ '@types/serve-static': 1.15.0
+ dev: false
+
+ /@types/json5/0.0.29:
+ resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
+ dev: false
+
+ /@types/mime/3.0.1:
+ resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==}
+ dev: false
+
+ /@types/node/17.0.45:
+ resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
+
+ /@types/prop-types/15.7.5:
+ resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
+ dev: true
+
+ /@types/qs/6.9.7:
+ resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
+ dev: false
+
+ /@types/range-parser/1.2.4:
+ resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==}
+ dev: false
+
+ /@types/react-dom/18.0.8:
+ resolution: {integrity: sha512-C3GYO0HLaOkk9dDAz3Dl4sbe4AKUGTCfFIZsz3n/82dPNN8Du533HzKatDxeUYWu24wJgMP1xICqkWk1YOLOIw==}
+ dependencies:
+ '@types/react': 18.0.24
+ dev: true
+
+ /@types/react/18.0.24:
+ resolution: {integrity: sha512-wRJWT6ouziGUy+9uX0aW4YOJxAY0bG6/AOk5AW5QSvZqI7dk6VBIbXvcVgIw/W5Jrl24f77df98GEKTJGOLx7Q==}
+ dependencies:
+ '@types/prop-types': 15.7.5
+ '@types/scheduler': 0.16.2
+ csstype: 3.1.1
+ dev: true
+
+ /@types/scheduler/0.16.2:
+ resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
+ dev: true
+
+ /@types/serve-static/1.15.0:
+ resolution: {integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==}
+ dependencies:
+ '@types/mime': 3.0.1
+ '@types/node': 17.0.45
+ dev: false
+
+ /@typescript-eslint/parser/5.41.0_3rubbgt5ekhqrcgx4uwls3neim:
+ resolution: {integrity: sha512-HQVfix4+RL5YRWZboMD1pUfFN8MpRH4laziWkkAzyO1fvNOY/uinZcvo3QiFJVS/siNHupV8E5+xSwQZrl6PZA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/scope-manager': 5.41.0
+ '@typescript-eslint/types': 5.41.0
+ '@typescript-eslint/typescript-estree': 5.41.0_typescript@4.8.4
+ debug: 4.3.4
+ eslint: 7.32.0
+ typescript: 4.8.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /@typescript-eslint/scope-manager/5.41.0:
+ resolution: {integrity: sha512-xOxPJCnuktUkY2xoEZBKXO5DBCugFzjrVndKdUnyQr3+9aDWZReKq9MhaoVnbL+maVwWJu/N0SEtrtEUNb62QQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ '@typescript-eslint/types': 5.41.0
+ '@typescript-eslint/visitor-keys': 5.41.0
+ dev: false
+
+ /@typescript-eslint/types/5.41.0:
+ resolution: {integrity: sha512-5BejraMXMC+2UjefDvrH0Fo/eLwZRV6859SXRg+FgbhA0R0l6lDqDGAQYhKbXhPN2ofk2kY5sgGyLNL907UXpA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: false
+
+ /@typescript-eslint/typescript-estree/5.41.0_typescript@4.8.4:
+ resolution: {integrity: sha512-SlzFYRwFSvswzDSQ/zPkIWcHv8O5y42YUskko9c4ki+fV6HATsTODUPbRbcGDFYP86gaJL5xohUEytvyNNcXWg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@typescript-eslint/types': 5.41.0
+ '@typescript-eslint/visitor-keys': 5.41.0
+ debug: 4.3.4
+ globby: 11.1.0
+ is-glob: 4.0.3
+ semver: 7.3.8
+ tsutils: 3.21.0_typescript@4.8.4
+ typescript: 4.8.4
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /@typescript-eslint/visitor-keys/5.41.0:
+ resolution: {integrity: sha512-vilqeHj267v8uzzakbm13HkPMl7cbYpKVjgFWZPIOHIJHZtinvypUhJ5xBXfWYg4eFKqztbMMpOgFpT9Gfx4fw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dependencies:
+ '@typescript-eslint/types': 5.41.0
+ eslint-visitor-keys: 3.3.0
+ dev: false
+
+ /@zodios/core/10.4.3_axios@1.1.3+zod@3.19.1:
+ resolution: {integrity: sha512-ejXyMMX8lOELFOlfsCpuHYhAE37UhCYKXBi75ifaWtObvdxuO2kcex5X2B6UOi6wmUKpcKOgbwlSZ96uZP53Fg==}
+ peerDependencies:
+ axios: ^0.x || ^1.0.0
+ zod: ^3.x
+ dependencies:
+ axios: 1.1.3
+ zod: 3.19.1
+ dev: false
+
+ /@zodios/express/10.4.2_za6leqvtaqdjr5gzlbrsemzpwi:
+ resolution: {integrity: sha512-s8hxGlVQZHpArPKFbnXbecj/HqTnbOOnYRIHgKBFbZouq9jhh41rmw9hxmTqjnMI6nK6U5gVkkN8u36OPBsyRQ==}
+ peerDependencies:
+ '@zodios/core': ^10.x
+ express: 4.x
+ zod: ^3.x
+ dependencies:
+ '@zodios/core': 10.4.3_axios@1.1.3+zod@3.19.1
+ express: 4.18.2
+ zod: 3.19.1
+ dev: false
+
+ /@zodios/react/10.3.3_tbpsitbqmenqxmwimr6kvnccvq:
+ resolution: {integrity: sha512-QAnlZVowIlSa0ezQtjr5wI84lJK7HifBtMTxmaEUiwrlOespdsz39IuojwUB+3G66kGTSbZLQcOhBPsiFPCvpQ==}
+ peerDependencies:
+ '@tanstack/react-query': 4.x
+ '@zodios/core': '>=10.2.0 <11.0.0'
+ react: '>=16.8.0'
+ dependencies:
+ '@tanstack/react-query': 4.13.0_biqbaboplfbrettd7655fr4n2y
+ '@zodios/core': 10.4.3_axios@1.1.3+zod@3.19.1
+ react: 18.2.0
+ dev: false
+
+ /accepts/1.3.8:
+ resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ mime-types: 2.1.35
+ negotiator: 0.6.3
+ dev: false
+
+ /acorn-jsx/5.3.2_acorn@7.4.1:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+ dependencies:
+ acorn: 7.4.1
+
+ /acorn/7.4.1:
+ resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ /ajv/6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
+ /ajv/8.11.0:
+ resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==}
+ dependencies:
+ fast-deep-equal: 3.1.3
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+ uri-js: 4.4.1
+
+ /ansi-colors/4.1.3:
+ resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
+ engines: {node: '>=6'}
+
+ /ansi-regex/5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ /ansi-styles/3.2.1:
+ resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
+ engines: {node: '>=4'}
+ dependencies:
+ color-convert: 1.9.3
+
+ /ansi-styles/4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+ dependencies:
+ color-convert: 2.0.1
+
+ /argparse/1.0.10:
+ resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+ dependencies:
+ sprintf-js: 1.0.3
+
+ /aria-query/4.2.2:
+ resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==}
+ engines: {node: '>=6.0'}
+ dependencies:
+ '@babel/runtime': 7.20.0
+ '@babel/runtime-corejs3': 7.20.0
+ dev: false
+
+ /array-flatten/1.1.1:
+ resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==}
+ dev: false
+
+ /array-includes/3.1.5:
+ resolution: {integrity: sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ get-intrinsic: 1.1.3
+ is-string: 1.0.7
+ dev: false
+
+ /array-union/2.1.0:
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /array.prototype.flat/1.3.0:
+ resolution: {integrity: sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ es-shim-unscopables: 1.0.0
+ dev: false
+
+ /array.prototype.flatmap/1.3.0:
+ resolution: {integrity: sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ es-shim-unscopables: 1.0.0
+ dev: false
+
+ /ast-types-flow/0.0.7:
+ resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==}
+ dev: false
+
+ /astral-regex/2.0.0:
+ resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
+ engines: {node: '>=8'}
+
+ /asynckit/0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+ dev: false
+
+ /axe-core/4.5.0:
+ resolution: {integrity: sha512-4+rr8eQ7+XXS5nZrKcMO/AikHL0hVqy+lHWAnE3xdHl+aguag8SOQ6eEqLexwLNWgXIMfunGuD3ON1/6Kyet0A==}
+ engines: {node: '>=4'}
+ dev: false
+
+ /axios/1.1.3:
+ resolution: {integrity: sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==}
+ dependencies:
+ follow-redirects: 1.15.2
+ form-data: 4.0.0
+ proxy-from-env: 1.1.0
+ transitivePeerDependencies:
+ - debug
+ dev: false
+
+ /axobject-query/2.2.0:
+ resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==}
+ dev: false
+
+ /balanced-match/1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ /body-parser/1.20.1:
+ resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==}
+ engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+ dependencies:
+ bytes: 3.1.2
+ content-type: 1.0.4
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
+ http-errors: 2.0.0
+ iconv-lite: 0.4.24
+ on-finished: 2.4.1
+ qs: 6.11.0
+ raw-body: 2.5.1
+ type-is: 1.6.18
+ unpipe: 1.0.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /brace-expansion/1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
+ /braces/3.0.2:
+ resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+ engines: {node: '>=8'}
+ dependencies:
+ fill-range: 7.0.1
+ dev: false
+
+ /browserslist/4.21.4:
+ resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+ dependencies:
+ caniuse-lite: 1.0.30001426
+ electron-to-chromium: 1.4.284
+ node-releases: 2.0.6
+ update-browserslist-db: 1.0.10_browserslist@4.21.4
+
+ /bytes/3.1.2:
+ resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
+ engines: {node: '>= 0.8'}
+ dev: false
+
+ /call-bind/1.0.2:
+ resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
+ dependencies:
+ function-bind: 1.1.1
+ get-intrinsic: 1.1.3
+ dev: false
+
+ /callsites/3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+
+ /caniuse-lite/1.0.30001426:
+ resolution: {integrity: sha512-n7cosrHLl8AWt0wwZw/PJZgUg3lV0gk9LMI7ikGJwhyhgsd2Nb65vKvmSexCqq/J7rbH3mFG6yZZiPR5dLPW5A==}
+
+ /chalk/2.4.2:
+ resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
+ engines: {node: '>=4'}
+ dependencies:
+ ansi-styles: 3.2.1
+ escape-string-regexp: 1.0.5
+ supports-color: 5.5.0
+
+ /chalk/4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ /client-only/0.0.1:
+ resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
+ dev: false
+
+ /color-convert/1.9.3:
+ resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+ dependencies:
+ color-name: 1.1.3
+
+ /color-convert/2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+ dependencies:
+ color-name: 1.1.4
+
+ /color-name/1.1.3:
+ resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+
+ /color-name/1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ /combined-stream/1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ delayed-stream: 1.0.0
+ dev: false
+
+ /concat-map/0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ /content-disposition/0.5.4:
+ resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ safe-buffer: 5.2.1
+ dev: false
+
+ /content-type/1.0.4:
+ resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /convert-source-map/1.9.0:
+ resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
+
+ /cookie-signature/1.0.6:
+ resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
+ dev: false
+
+ /cookie/0.5.0:
+ resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /core-js-pure/3.26.0:
+ resolution: {integrity: sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==}
+ requiresBuild: true
+ dev: false
+
+ /cross-spawn/7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ /csstype/3.1.1:
+ resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==}
+ dev: true
+
+ /damerau-levenshtein/1.0.8:
+ resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
+ dev: false
+
+ /debug/2.6.9:
+ resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.0.0
+ dev: false
+
+ /debug/3.2.7:
+ resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.3
+ dev: false
+
+ /debug/4.3.4:
+ resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+ dependencies:
+ ms: 2.1.2
+
+ /deep-is/0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ /define-properties/1.1.4:
+ resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-property-descriptors: 1.0.0
+ object-keys: 1.1.1
+ dev: false
+
+ /delayed-stream/1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+ dev: false
+
+ /depd/2.0.0:
+ resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
+ engines: {node: '>= 0.8'}
+ dev: false
+
+ /destroy/1.2.0:
+ resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
+ engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
+ dev: false
+
+ /dir-glob/3.0.1:
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
+ engines: {node: '>=8'}
+ dependencies:
+ path-type: 4.0.0
+ dev: false
+
+ /doctrine/2.1.0:
+ resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ esutils: 2.0.3
+ dev: false
+
+ /doctrine/3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
+ dependencies:
+ esutils: 2.0.3
+
+ /ee-first/1.1.1:
+ resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
+ dev: false
+
+ /electron-to-chromium/1.4.284:
+ resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==}
+
+ /emoji-regex/8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ /emoji-regex/9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+ dev: false
+
+ /encodeurl/1.0.2:
+ resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
+ engines: {node: '>= 0.8'}
+ dev: false
+
+ /enquirer/2.3.6:
+ resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==}
+ engines: {node: '>=8.6'}
+ dependencies:
+ ansi-colors: 4.1.3
+
+ /es-abstract/1.20.4:
+ resolution: {integrity: sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ es-to-primitive: 1.2.1
+ function-bind: 1.1.1
+ function.prototype.name: 1.1.5
+ get-intrinsic: 1.1.3
+ get-symbol-description: 1.0.0
+ has: 1.0.3
+ has-property-descriptors: 1.0.0
+ has-symbols: 1.0.3
+ internal-slot: 1.0.3
+ is-callable: 1.2.7
+ is-negative-zero: 2.0.2
+ is-regex: 1.1.4
+ is-shared-array-buffer: 1.0.2
+ is-string: 1.0.7
+ is-weakref: 1.0.2
+ object-inspect: 1.12.2
+ object-keys: 1.1.1
+ object.assign: 4.1.4
+ regexp.prototype.flags: 1.4.3
+ safe-regex-test: 1.0.0
+ string.prototype.trimend: 1.0.5
+ string.prototype.trimstart: 1.0.5
+ unbox-primitive: 1.0.2
+ dev: false
+
+ /es-shim-unscopables/1.0.0:
+ resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==}
+ dependencies:
+ has: 1.0.3
+ dev: false
+
+ /es-to-primitive/1.2.1:
+ resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ is-callable: 1.2.7
+ is-date-object: 1.0.5
+ is-symbol: 1.0.4
+ dev: false
+
+ /escalade/3.1.1:
+ resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
+ engines: {node: '>=6'}
+
+ /escape-html/1.0.3:
+ resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
+ dev: false
+
+ /escape-string-regexp/1.0.5:
+ resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+ engines: {node: '>=0.8.0'}
+
+ /escape-string-regexp/4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ /eslint-config-next/12.3.1_3rubbgt5ekhqrcgx4uwls3neim:
+ resolution: {integrity: sha512-EN/xwKPU6jz1G0Qi6Bd/BqMnHLyRAL0VsaQaWA7F3KkjAgZHi4f1uL1JKGWNxdQpHTW/sdGONBd0bzxUka/DJg==}
+ peerDependencies:
+ eslint: ^7.23.0 || ^8.0.0
+ typescript: '>=3.3.1'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ dependencies:
+ '@next/eslint-plugin-next': 12.3.1
+ '@rushstack/eslint-patch': 1.2.0
+ '@typescript-eslint/parser': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim
+ eslint: 7.32.0
+ eslint-import-resolver-node: 0.3.6
+ eslint-import-resolver-typescript: 2.7.1_hpmu7kn6tcn2vnxpfzvv33bxmy
+ eslint-plugin-import: 2.26.0_r6mdt2nwtavxychxvtdgpnclqq
+ eslint-plugin-jsx-a11y: 6.6.1_eslint@7.32.0
+ eslint-plugin-react: 7.31.8_eslint@7.32.0
+ eslint-plugin-react-hooks: 4.6.0_eslint@7.32.0
+ typescript: 4.8.4
+ transitivePeerDependencies:
+ - eslint-import-resolver-webpack
+ - supports-color
+ dev: false
+
+ /eslint-config-prettier/8.5.0_eslint@7.32.0:
+ resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==}
+ hasBin: true
+ peerDependencies:
+ eslint: '>=7.0.0'
+ dependencies:
+ eslint: 7.32.0
+ dev: false
+
+ /eslint-config-turbo/0.0.4_eslint@7.32.0:
+ resolution: {integrity: sha512-HErPS/wfWkSdV9Yd2dDkhZt3W2B78Ih/aWPFfaHmCMjzPalh+5KxRRGTf8MOBQLCebcWJX0lP1Zvc1rZIHlXGg==}
+ peerDependencies:
+ eslint: ^7.23.0 || ^8.0.0
+ dependencies:
+ eslint: 7.32.0
+ eslint-plugin-turbo: 0.0.4_eslint@7.32.0
+ dev: false
+
+ /eslint-import-resolver-node/0.3.6:
+ resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==}
+ dependencies:
+ debug: 3.2.7
+ resolve: 1.22.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /eslint-import-resolver-typescript/2.7.1_hpmu7kn6tcn2vnxpfzvv33bxmy:
+ resolution: {integrity: sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ eslint: '*'
+ eslint-plugin-import: '*'
+ dependencies:
+ debug: 4.3.4
+ eslint: 7.32.0
+ eslint-plugin-import: 2.26.0_r6mdt2nwtavxychxvtdgpnclqq
+ glob: 7.2.3
+ is-glob: 4.0.3
+ resolve: 1.22.1
+ tsconfig-paths: 3.14.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /eslint-module-utils/2.7.4_hc2d46adw36jouofggb76llgoi:
+ resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: '*'
+ eslint-import-resolver-node: '*'
+ eslint-import-resolver-typescript: '*'
+ eslint-import-resolver-webpack: '*'
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ eslint:
+ optional: true
+ eslint-import-resolver-node:
+ optional: true
+ eslint-import-resolver-typescript:
+ optional: true
+ eslint-import-resolver-webpack:
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim
+ debug: 3.2.7
+ eslint: 7.32.0
+ eslint-import-resolver-node: 0.3.6
+ eslint-import-resolver-typescript: 2.7.1_hpmu7kn6tcn2vnxpfzvv33bxmy
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /eslint-plugin-import/2.26.0_r6mdt2nwtavxychxvtdgpnclqq:
+ resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ '@typescript-eslint/parser': '*'
+ eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8
+ peerDependenciesMeta:
+ '@typescript-eslint/parser':
+ optional: true
+ dependencies:
+ '@typescript-eslint/parser': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim
+ array-includes: 3.1.5
+ array.prototype.flat: 1.3.0
+ debug: 2.6.9
+ doctrine: 2.1.0
+ eslint: 7.32.0
+ eslint-import-resolver-node: 0.3.6
+ eslint-module-utils: 2.7.4_hc2d46adw36jouofggb76llgoi
+ has: 1.0.3
+ is-core-module: 2.11.0
+ is-glob: 4.0.3
+ minimatch: 3.1.2
+ object.values: 1.1.5
+ resolve: 1.22.1
+ tsconfig-paths: 3.14.1
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
+ dev: false
+
+ /eslint-plugin-jsx-a11y/6.6.1_eslint@7.32.0:
+ resolution: {integrity: sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+ dependencies:
+ '@babel/runtime': 7.20.0
+ aria-query: 4.2.2
+ array-includes: 3.1.5
+ ast-types-flow: 0.0.7
+ axe-core: 4.5.0
+ axobject-query: 2.2.0
+ damerau-levenshtein: 1.0.8
+ emoji-regex: 9.2.2
+ eslint: 7.32.0
+ has: 1.0.3
+ jsx-ast-utils: 3.3.3
+ language-tags: 1.0.5
+ minimatch: 3.1.2
+ semver: 6.3.0
+ dev: false
+
+ /eslint-plugin-react-hooks/4.6.0_eslint@7.32.0:
+ resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
+ dependencies:
+ eslint: 7.32.0
+ dev: false
+
+ /eslint-plugin-react/7.31.8_eslint@7.32.0:
+ resolution: {integrity: sha512-5lBTZmgQmARLLSYiwI71tiGVTLUuqXantZM6vlSY39OaDSV0M7+32K5DnLkmFrwTe+Ksz0ffuLUC91RUviVZfw==}
+ engines: {node: '>=4'}
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
+ dependencies:
+ array-includes: 3.1.5
+ array.prototype.flatmap: 1.3.0
+ doctrine: 2.1.0
+ eslint: 7.32.0
+ estraverse: 5.3.0
+ jsx-ast-utils: 3.3.3
+ minimatch: 3.1.2
+ object.entries: 1.1.5
+ object.fromentries: 2.0.5
+ object.hasown: 1.1.1
+ object.values: 1.1.5
+ prop-types: 15.8.1
+ resolve: 2.0.0-next.4
+ semver: 6.3.0
+ string.prototype.matchall: 4.0.7
+ dev: false
+
+ /eslint-plugin-turbo/0.0.4_eslint@7.32.0:
+ resolution: {integrity: sha512-dfmYE/iPvoJInQq+5E/0mj140y/rYwKtzZkn3uVK8+nvwC5zmWKQ6ehMWrL4bYBkGzSgpOndZM+jOXhPQ2m8Cg==}
+ peerDependencies:
+ eslint: ^7.23.0 || ^8.0.0
+ dependencies:
+ eslint: 7.32.0
+ dev: false
+
+ /eslint-scope/5.1.1:
+ resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
+ engines: {node: '>=8.0.0'}
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 4.3.0
+
+ /eslint-utils/2.1.0:
+ resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==}
+ engines: {node: '>=6'}
+ dependencies:
+ eslint-visitor-keys: 1.3.0
+
+ /eslint-visitor-keys/1.3.0:
+ resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==}
+ engines: {node: '>=4'}
+
+ /eslint-visitor-keys/2.1.0:
+ resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
+ engines: {node: '>=10'}
+
+ /eslint-visitor-keys/3.3.0:
+ resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ dev: false
+
+ /eslint/7.32.0:
+ resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ hasBin: true
+ dependencies:
+ '@babel/code-frame': 7.12.11
+ '@eslint/eslintrc': 0.4.3
+ '@humanwhocodes/config-array': 0.5.0
+ ajv: 6.12.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.3
+ debug: 4.3.4
+ doctrine: 3.0.0
+ enquirer: 2.3.6
+ escape-string-regexp: 4.0.0
+ eslint-scope: 5.1.1
+ eslint-utils: 2.1.0
+ eslint-visitor-keys: 2.1.0
+ espree: 7.3.1
+ esquery: 1.4.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 6.0.1
+ functional-red-black-tree: 1.0.1
+ glob-parent: 5.1.2
+ globals: 13.17.0
+ ignore: 4.0.6
+ import-fresh: 3.3.0
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ js-yaml: 3.14.1
+ json-stable-stringify-without-jsonify: 1.0.1
+ levn: 0.4.1
+ lodash.merge: 4.6.2
+ minimatch: 3.1.2
+ natural-compare: 1.4.0
+ optionator: 0.9.1
+ progress: 2.0.3
+ regexpp: 3.2.0
+ semver: 7.3.8
+ strip-ansi: 6.0.1
+ strip-json-comments: 3.1.1
+ table: 6.8.0
+ text-table: 0.2.0
+ v8-compile-cache: 2.3.0
+ transitivePeerDependencies:
+ - supports-color
+
+ /espree/7.3.1:
+ resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ acorn: 7.4.1
+ acorn-jsx: 5.3.2_acorn@7.4.1
+ eslint-visitor-keys: 1.3.0
+
+ /esprima/4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ /esquery/1.4.0:
+ resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
+ engines: {node: '>=0.10'}
+ dependencies:
+ estraverse: 5.3.0
+
+ /esrecurse/4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+ dependencies:
+ estraverse: 5.3.0
+
+ /estraverse/4.3.0:
+ resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
+ engines: {node: '>=4.0'}
+
+ /estraverse/5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ /esutils/2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+
+ /etag/1.8.1:
+ resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /express/4.18.2:
+ resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==}
+ engines: {node: '>= 0.10.0'}
+ dependencies:
+ accepts: 1.3.8
+ array-flatten: 1.1.1
+ body-parser: 1.20.1
+ content-disposition: 0.5.4
+ content-type: 1.0.4
+ cookie: 0.5.0
+ cookie-signature: 1.0.6
+ debug: 2.6.9
+ depd: 2.0.0
+ encodeurl: 1.0.2
+ escape-html: 1.0.3
+ etag: 1.8.1
+ finalhandler: 1.2.0
+ fresh: 0.5.2
+ http-errors: 2.0.0
+ merge-descriptors: 1.0.1
+ methods: 1.1.2
+ on-finished: 2.4.1
+ parseurl: 1.3.3
+ path-to-regexp: 0.1.7
+ proxy-addr: 2.0.7
+ qs: 6.11.0
+ range-parser: 1.2.1
+ safe-buffer: 5.2.1
+ send: 0.18.0
+ serve-static: 1.15.0
+ setprototypeof: 1.2.0
+ statuses: 2.0.1
+ type-is: 1.6.18
+ utils-merge: 1.0.1
+ vary: 1.1.2
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /fast-deep-equal/3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ /fast-glob/3.2.12:
+ resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==}
+ engines: {node: '>=8.6.0'}
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.5
+ dev: false
+
+ /fast-json-stable-stringify/2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ /fast-levenshtein/2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ /fastq/1.13.0:
+ resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
+ dependencies:
+ reusify: 1.0.4
+ dev: false
+
+ /file-entry-cache/6.0.1:
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flat-cache: 3.0.4
+
+ /fill-range/7.0.1:
+ resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+ engines: {node: '>=8'}
+ dependencies:
+ to-regex-range: 5.0.1
+ dev: false
+
+ /finalhandler/1.2.0:
+ resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ debug: 2.6.9
+ encodeurl: 1.0.2
+ escape-html: 1.0.3
+ on-finished: 2.4.1
+ parseurl: 1.3.3
+ statuses: 2.0.1
+ unpipe: 1.0.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /flat-cache/3.0.4:
+ resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
+ dependencies:
+ flatted: 3.2.7
+ rimraf: 3.0.2
+
+ /flatted/3.2.7:
+ resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
+
+ /follow-redirects/1.15.2:
+ resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+ dev: false
+
+ /form-data/4.0.0:
+ resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
+ engines: {node: '>= 6'}
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ mime-types: 2.1.35
+ dev: false
+
+ /forwarded/0.2.0:
+ resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /fresh/0.5.2:
+ resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /fs.realpath/1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+
+ /function-bind/1.1.1:
+ resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+ dev: false
+
+ /function.prototype.name/1.1.5:
+ resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ functions-have-names: 1.2.3
+ dev: false
+
+ /functional-red-black-tree/1.0.1:
+ resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==}
+
+ /functions-have-names/1.2.3:
+ resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+ dev: false
+
+ /gensync/1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+
+ /get-intrinsic/1.1.3:
+ resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==}
+ dependencies:
+ function-bind: 1.1.1
+ has: 1.0.3
+ has-symbols: 1.0.3
+ dev: false
+
+ /get-symbol-description/1.0.0:
+ resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.1.3
+ dev: false
+
+ /glob-parent/5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+ dependencies:
+ is-glob: 4.0.3
+
+ /glob/7.1.7:
+ resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==}
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+ dev: false
+
+ /glob/7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ dependencies:
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
+
+ /globals/11.12.0:
+ resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+ engines: {node: '>=4'}
+
+ /globals/13.17.0:
+ resolution: {integrity: sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==}
+ engines: {node: '>=8'}
+ dependencies:
+ type-fest: 0.20.2
+
+ /globby/11.1.0:
+ resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
+ engines: {node: '>=10'}
+ dependencies:
+ array-union: 2.1.0
+ dir-glob: 3.0.1
+ fast-glob: 3.2.12
+ ignore: 5.2.0
+ merge2: 1.4.1
+ slash: 3.0.0
+ dev: false
+
+ /has-bigints/1.0.2:
+ resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
+ dev: false
+
+ /has-flag/3.0.0:
+ resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
+ engines: {node: '>=4'}
+
+ /has-flag/4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ /has-property-descriptors/1.0.0:
+ resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
+ dependencies:
+ get-intrinsic: 1.1.3
+ dev: false
+
+ /has-symbols/1.0.3:
+ resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /has-tostringtag/1.0.0:
+ resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: false
+
+ /has/1.0.3:
+ resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+ engines: {node: '>= 0.4.0'}
+ dependencies:
+ function-bind: 1.1.1
+ dev: false
+
+ /http-errors/2.0.0:
+ resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ depd: 2.0.0
+ inherits: 2.0.4
+ setprototypeof: 1.2.0
+ statuses: 2.0.1
+ toidentifier: 1.0.1
+ dev: false
+
+ /iconv-lite/0.4.24:
+ resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ safer-buffer: 2.1.2
+ dev: false
+
+ /ignore/4.0.6:
+ resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==}
+ engines: {node: '>= 4'}
+
+ /ignore/5.2.0:
+ resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==}
+ engines: {node: '>= 4'}
+ dev: false
+
+ /import-fresh/3.3.0:
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+ engines: {node: '>=6'}
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+
+ /imurmurhash/0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ /inflight/1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ dependencies:
+ once: 1.4.0
+ wrappy: 1.0.2
+
+ /inherits/2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ /internal-slot/1.0.3:
+ resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ get-intrinsic: 1.1.3
+ has: 1.0.3
+ side-channel: 1.0.4
+ dev: false
+
+ /ipaddr.js/1.9.1:
+ resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
+ engines: {node: '>= 0.10'}
+ dev: false
+
+ /is-bigint/1.0.4:
+ resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
+ dependencies:
+ has-bigints: 1.0.2
+ dev: false
+
+ /is-boolean-object/1.1.2:
+ resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: false
+
+ /is-callable/1.2.7:
+ resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-core-module/2.11.0:
+ resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==}
+ dependencies:
+ has: 1.0.3
+ dev: false
+
+ /is-date-object/1.0.5:
+ resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: false
+
+ /is-extglob/2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ /is-fullwidth-code-point/3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ /is-glob/4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ is-extglob: 2.1.1
+
+ /is-negative-zero/2.0.2:
+ resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /is-number-object/1.0.7:
+ resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: false
+
+ /is-number/7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+ dev: false
+
+ /is-regex/1.1.4:
+ resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ has-tostringtag: 1.0.0
+ dev: false
+
+ /is-shared-array-buffer/1.0.2:
+ resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==}
+ dependencies:
+ call-bind: 1.0.2
+ dev: false
+
+ /is-string/1.0.7:
+ resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-tostringtag: 1.0.0
+ dev: false
+
+ /is-symbol/1.0.4:
+ resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ has-symbols: 1.0.3
+ dev: false
+
+ /is-weakref/1.0.2:
+ resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+ dependencies:
+ call-bind: 1.0.2
+ dev: false
+
+ /isexe/2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ /js-tokens/4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ /js-yaml/3.14.1:
+ resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
+ hasBin: true
+ dependencies:
+ argparse: 1.0.10
+ esprima: 4.0.1
+
+ /jsesc/2.5.2:
+ resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ /json-schema-traverse/0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ /json-schema-traverse/1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ /json-stable-stringify-without-jsonify/1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ /json5/1.0.1:
+ resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==}
+ hasBin: true
+ dependencies:
+ minimist: 1.2.7
+ dev: false
+
+ /json5/2.2.1:
+ resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ /jsx-ast-utils/3.3.3:
+ resolution: {integrity: sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==}
+ engines: {node: '>=4.0'}
+ dependencies:
+ array-includes: 3.1.5
+ object.assign: 4.1.4
+ dev: false
+
+ /language-subtag-registry/0.3.22:
+ resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==}
+ dev: false
+
+ /language-tags/1.0.5:
+ resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==}
+ dependencies:
+ language-subtag-registry: 0.3.22
+ dev: false
+
+ /levn/0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+
+ /lodash.merge/4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
+ /lodash.truncate/4.4.2:
+ resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==}
+
+ /loose-envify/1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+ dependencies:
+ js-tokens: 4.0.0
+
+ /lru-cache/6.0.0:
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
+ engines: {node: '>=10'}
+ dependencies:
+ yallist: 4.0.0
+
+ /media-typer/0.3.0:
+ resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /merge-descriptors/1.0.1:
+ resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==}
+ dev: false
+
+ /merge2/1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+ dev: false
+
+ /methods/1.1.2:
+ resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /micromatch/4.0.5:
+ resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+ engines: {node: '>=8.6'}
+ dependencies:
+ braces: 3.0.2
+ picomatch: 2.3.1
+ dev: false
+
+ /mime-db/1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /mime-types/2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ mime-db: 1.52.0
+ dev: false
+
+ /mime/1.6.0:
+ resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==}
+ engines: {node: '>=4'}
+ hasBin: true
+ dev: false
+
+ /minimatch/3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+ dependencies:
+ brace-expansion: 1.1.11
+
+ /minimist/1.2.7:
+ resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==}
+ dev: false
+
+ /ms/2.0.0:
+ resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+ dev: false
+
+ /ms/2.1.2:
+ resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+
+ /ms/2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ dev: false
+
+ /nanoid/3.3.4:
+ resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+ dev: false
+
+ /natural-compare/1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ /negotiator/0.6.3:
+ resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /next/12.3.1_qtpcxnaaarbm4ws7ughq6oxfve:
+ resolution: {integrity: sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw==}
+ engines: {node: '>=12.22.0'}
+ hasBin: true
+ peerDependencies:
+ fibers: '>= 3.1.0'
+ node-sass: ^6.0.0 || ^7.0.0
+ react: ^17.0.2 || ^18.0.0-0
+ react-dom: ^17.0.2 || ^18.0.0-0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ fibers:
+ optional: true
+ node-sass:
+ optional: true
+ sass:
+ optional: true
+ dependencies:
+ '@next/env': 12.3.1
+ '@swc/helpers': 0.4.11
+ caniuse-lite: 1.0.30001426
+ postcss: 8.4.14
+ react: 18.2.0
+ react-dom: 18.2.0_react@18.2.0
+ styled-jsx: 5.0.7_otspjrsspon4ofp37rshhlhp2y
+ use-sync-external-store: 1.2.0_react@18.2.0
+ optionalDependencies:
+ '@next/swc-android-arm-eabi': 12.3.1
+ '@next/swc-android-arm64': 12.3.1
+ '@next/swc-darwin-arm64': 12.3.1
+ '@next/swc-darwin-x64': 12.3.1
+ '@next/swc-freebsd-x64': 12.3.1
+ '@next/swc-linux-arm-gnueabihf': 12.3.1
+ '@next/swc-linux-arm64-gnu': 12.3.1
+ '@next/swc-linux-arm64-musl': 12.3.1
+ '@next/swc-linux-x64-gnu': 12.3.1
+ '@next/swc-linux-x64-musl': 12.3.1
+ '@next/swc-win32-arm64-msvc': 12.3.1
+ '@next/swc-win32-ia32-msvc': 12.3.1
+ '@next/swc-win32-x64-msvc': 12.3.1
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+ dev: false
+
+ /next/12.3.2-canary.40_qtpcxnaaarbm4ws7ughq6oxfve:
+ resolution: {integrity: sha512-TDIosDIpEC3IaRwwUuQ8ypUxYG7zyIGEN14UW0Y77/gpO20BwbR/0q3ZzHt+4W5JRF7vXZly62xTMMH1hVJHFA==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+ peerDependencies:
+ fibers: '>= 3.1.0'
+ node-sass: ^6.0.0 || ^7.0.0
+ react: ^18.0.0-0
+ react-dom: ^18.0.0-0
+ sass: ^1.3.0
+ peerDependenciesMeta:
+ fibers:
+ optional: true
+ node-sass:
+ optional: true
+ sass:
+ optional: true
+ dependencies:
+ '@next/env': 12.3.2-canary.40
+ '@swc/helpers': 0.4.11
+ caniuse-lite: 1.0.30001426
+ postcss: 8.4.14
+ react: 18.2.0
+ react-dom: 18.2.0_react@18.2.0
+ styled-jsx: 5.1.0_otspjrsspon4ofp37rshhlhp2y
+ use-sync-external-store: 1.2.0_react@18.2.0
+ optionalDependencies:
+ '@next/swc-android-arm-eabi': 12.3.2-canary.40
+ '@next/swc-android-arm64': 12.3.2-canary.40
+ '@next/swc-darwin-arm64': 12.3.2-canary.40
+ '@next/swc-darwin-x64': 12.3.2-canary.40
+ '@next/swc-freebsd-x64': 12.3.2-canary.40
+ '@next/swc-linux-arm-gnueabihf': 12.3.2-canary.40
+ '@next/swc-linux-arm64-gnu': 12.3.2-canary.40
+ '@next/swc-linux-arm64-musl': 12.3.2-canary.40
+ '@next/swc-linux-x64-gnu': 12.3.2-canary.40
+ '@next/swc-linux-x64-musl': 12.3.2-canary.40
+ '@next/swc-win32-arm64-msvc': 12.3.2-canary.40
+ '@next/swc-win32-ia32-msvc': 12.3.2-canary.40
+ '@next/swc-win32-x64-msvc': 12.3.2-canary.40
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+ dev: false
+
+ /node-releases/2.0.6:
+ resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==}
+
+ /object-assign/4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /object-inspect/1.12.2:
+ resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==}
+ dev: false
+
+ /object-keys/1.1.1:
+ resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /object.assign/4.1.4:
+ resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ has-symbols: 1.0.3
+ object-keys: 1.1.1
+ dev: false
+
+ /object.entries/1.1.5:
+ resolution: {integrity: sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ dev: false
+
+ /object.fromentries/2.0.5:
+ resolution: {integrity: sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ dev: false
+
+ /object.hasown/1.1.1:
+ resolution: {integrity: sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==}
+ dependencies:
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ dev: false
+
+ /object.values/1.1.5:
+ resolution: {integrity: sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ dev: false
+
+ /on-finished/2.4.1:
+ resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ ee-first: 1.1.1
+ dev: false
+
+ /once/1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+ dependencies:
+ wrappy: 1.0.2
+
+ /optionator/0.9.1:
+ resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ word-wrap: 1.2.3
+
+ /parent-module/1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+ dependencies:
+ callsites: 3.1.0
+
+ /parseurl/1.3.3:
+ resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
+ engines: {node: '>= 0.8'}
+ dev: false
+
+ /path-is-absolute/1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+
+ /path-key/3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ /path-parse/1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+ dev: false
+
+ /path-to-regexp/0.1.7:
+ resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
+ dev: false
+
+ /path-type/4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /picocolors/1.0.0:
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+
+ /picomatch/2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+ dev: false
+
+ /postcss/8.4.14:
+ resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==}
+ engines: {node: ^10 || ^12 || >=14}
+ dependencies:
+ nanoid: 3.3.4
+ picocolors: 1.0.0
+ source-map-js: 1.0.2
+ dev: false
+
+ /prelude-ls/1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ /prettier/2.7.1:
+ resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+ dev: true
+
+ /progress/2.0.3:
+ resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
+ engines: {node: '>=0.4.0'}
+
+ /prop-types/15.8.1:
+ resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
+ dependencies:
+ loose-envify: 1.4.0
+ object-assign: 4.1.1
+ react-is: 16.13.1
+ dev: false
+
+ /proxy-addr/2.0.7:
+ resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
+ engines: {node: '>= 0.10'}
+ dependencies:
+ forwarded: 0.2.0
+ ipaddr.js: 1.9.1
+ dev: false
+
+ /proxy-from-env/1.1.0:
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+ dev: false
+
+ /punycode/2.1.1:
+ resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
+ engines: {node: '>=6'}
+
+ /qs/6.11.0:
+ resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
+ engines: {node: '>=0.6'}
+ dependencies:
+ side-channel: 1.0.4
+ dev: false
+
+ /queue-microtask/1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ dev: false
+
+ /range-parser/1.2.1:
+ resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
+ engines: {node: '>= 0.6'}
+ dev: false
+
+ /raw-body/2.5.1:
+ resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==}
+ engines: {node: '>= 0.8'}
+ dependencies:
+ bytes: 3.1.2
+ http-errors: 2.0.0
+ iconv-lite: 0.4.24
+ unpipe: 1.0.0
+ dev: false
+
+ /react-dom/18.2.0_react@18.2.0:
+ resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
+ peerDependencies:
+ react: ^18.2.0
+ dependencies:
+ loose-envify: 1.4.0
+ react: 18.2.0
+ scheduler: 0.23.0
+ dev: false
+
+ /react-is/16.13.1:
+ resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+ dev: false
+
+ /react/18.2.0:
+ resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
+ engines: {node: '>=0.10.0'}
+ dependencies:
+ loose-envify: 1.4.0
+
+ /regenerator-runtime/0.13.10:
+ resolution: {integrity: sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==}
+ dev: false
+
+ /regexp.prototype.flags/1.4.3:
+ resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==}
+ engines: {node: '>= 0.4'}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ functions-have-names: 1.2.3
+ dev: false
+
+ /regexpp/3.2.0:
+ resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
+ engines: {node: '>=8'}
+
+ /require-from-string/2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ /resolve-from/4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ /resolve/1.22.1:
+ resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
+ hasBin: true
+ dependencies:
+ is-core-module: 2.11.0
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+ dev: false
+
+ /resolve/2.0.0-next.4:
+ resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==}
+ hasBin: true
+ dependencies:
+ is-core-module: 2.11.0
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+ dev: false
+
+ /reusify/1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+ dev: false
+
+ /rimraf/3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ hasBin: true
+ dependencies:
+ glob: 7.2.3
+
+ /run-parallel/1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ dependencies:
+ queue-microtask: 1.2.3
+ dev: false
+
+ /safe-buffer/5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+ dev: false
+
+ /safe-regex-test/1.0.0:
+ resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.1.3
+ is-regex: 1.1.4
+ dev: false
+
+ /safer-buffer/2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+ dev: false
+
+ /scheduler/0.23.0:
+ resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
+ dependencies:
+ loose-envify: 1.4.0
+ dev: false
+
+ /semver/6.3.0:
+ resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
+ hasBin: true
+
+ /semver/7.3.8:
+ resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
+ engines: {node: '>=10'}
+ hasBin: true
+ dependencies:
+ lru-cache: 6.0.0
+
+ /send/0.18.0:
+ resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ debug: 2.6.9
+ depd: 2.0.0
+ destroy: 1.2.0
+ encodeurl: 1.0.2
+ escape-html: 1.0.3
+ etag: 1.8.1
+ fresh: 0.5.2
+ http-errors: 2.0.0
+ mime: 1.6.0
+ ms: 2.1.3
+ on-finished: 2.4.1
+ range-parser: 1.2.1
+ statuses: 2.0.1
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /serve-static/1.15.0:
+ resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ encodeurl: 1.0.2
+ escape-html: 1.0.3
+ parseurl: 1.3.3
+ send: 0.18.0
+ transitivePeerDependencies:
+ - supports-color
+ dev: false
+
+ /setprototypeof/1.2.0:
+ resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
+ dev: false
+
+ /shebang-command/2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+ dependencies:
+ shebang-regex: 3.0.0
+
+ /shebang-regex/3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ /side-channel/1.0.4:
+ resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
+ dependencies:
+ call-bind: 1.0.2
+ get-intrinsic: 1.1.3
+ object-inspect: 1.12.2
+ dev: false
+
+ /slash/3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+ dev: false
+
+ /slice-ansi/4.0.0:
+ resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
+ engines: {node: '>=10'}
+ dependencies:
+ ansi-styles: 4.3.0
+ astral-regex: 2.0.0
+ is-fullwidth-code-point: 3.0.0
+
+ /source-map-js/1.0.2:
+ resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
+ engines: {node: '>=0.10.0'}
+ dev: false
+
+ /sprintf-js/1.0.3:
+ resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+
+ /statuses/2.0.1:
+ resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
+ engines: {node: '>= 0.8'}
+ dev: false
+
+ /string-width/4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ /string.prototype.matchall/4.0.7:
+ resolution: {integrity: sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ get-intrinsic: 1.1.3
+ has-symbols: 1.0.3
+ internal-slot: 1.0.3
+ regexp.prototype.flags: 1.4.3
+ side-channel: 1.0.4
+ dev: false
+
+ /string.prototype.trimend/1.0.5:
+ resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ dev: false
+
+ /string.prototype.trimstart/1.0.5:
+ resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==}
+ dependencies:
+ call-bind: 1.0.2
+ define-properties: 1.1.4
+ es-abstract: 1.20.4
+ dev: false
+
+ /strip-ansi/6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+ dependencies:
+ ansi-regex: 5.0.1
+
+ /strip-bom/3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+ dev: false
+
+ /strip-json-comments/3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ /styled-jsx/5.0.7_otspjrsspon4ofp37rshhlhp2y:
+ resolution: {integrity: sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+ dependencies:
+ '@babel/core': 7.19.6
+ react: 18.2.0
+ dev: false
+
+ /styled-jsx/5.1.0_otspjrsspon4ofp37rshhlhp2y:
+ resolution: {integrity: sha512-/iHaRJt9U7T+5tp6TRelLnqBqiaIT0HsO0+vgyj8hK2KUk7aejFqRrumqPUlAqDwAj8IbS/1hk3IhBAAK/FCUQ==}
+ engines: {node: '>= 12.0.0'}
+ peerDependencies:
+ '@babel/core': '*'
+ babel-plugin-macros: '*'
+ react: '>= 16.8.0 || 17.x.x || ^18.0.0-0'
+ peerDependenciesMeta:
+ '@babel/core':
+ optional: true
+ babel-plugin-macros:
+ optional: true
+ dependencies:
+ '@babel/core': 7.19.6
+ client-only: 0.0.1
+ react: 18.2.0
+ dev: false
+
+ /supports-color/5.5.0:
+ resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
+ engines: {node: '>=4'}
+ dependencies:
+ has-flag: 3.0.0
+
+ /supports-color/7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+ dependencies:
+ has-flag: 4.0.0
+
+ /supports-preserve-symlinks-flag/1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+ dev: false
+
+ /table/6.8.0:
+ resolution: {integrity: sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==}
+ engines: {node: '>=10.0.0'}
+ dependencies:
+ ajv: 8.11.0
+ lodash.truncate: 4.4.2
+ slice-ansi: 4.0.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ /text-table/0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+
+ /to-fast-properties/2.0.0:
+ resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
+ engines: {node: '>=4'}
+
+ /to-regex-range/5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+ dependencies:
+ is-number: 7.0.0
+ dev: false
+
+ /toidentifier/1.0.1:
+ resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
+ engines: {node: '>=0.6'}
+ dev: false
+
+ /tsconfig-paths/3.14.1:
+ resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==}
+ dependencies:
+ '@types/json5': 0.0.29
+ json5: 1.0.1
+ minimist: 1.2.7
+ strip-bom: 3.0.0
+ dev: false
+
+ /tslib/1.14.1:
+ resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
+ dev: false
+
+ /tslib/2.4.0:
+ resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
+ dev: false
+
+ /tsutils/3.21.0_typescript@4.8.4:
+ resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
+ engines: {node: '>= 6'}
+ peerDependencies:
+ typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
+ dependencies:
+ tslib: 1.14.1
+ typescript: 4.8.4
+ dev: false
+
+ /turbo-darwin-64/1.6.2:
+ resolution: {integrity: sha512-qzqVdJZcVeu1d0mzeSxffgeOToSgM+Hl1y9yDiJQ4QQjiR/WGCzS9FtydLnk0ori8T1j/lxiiQz2sHjHYfLCTg==}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /turbo-darwin-arm64/1.6.2:
+ resolution: {integrity: sha512-EJvgWSjLwzJbAsqRuqeaYSdXNKwyiUfOfEOPerYCvwxC+ILiqpladjteMCzzF/z2OmIbPzuqZpyik30TfpIC9A==}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /turbo-linux-64/1.6.2:
+ resolution: {integrity: sha512-SJ5ThDApOyOavjvkYb6a1MKJbOvX4JEvSYxoZv+ZpN8g7A7x1SE9b7EnxFl26S4eyy0J4+r+YJBDBZ7sFkqRWQ==}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /turbo-linux-arm64/1.6.2:
+ resolution: {integrity: sha512-0vHojVlvAelsYZo6p/xE9H9Dg8spNjXx+PO5RwP12ui8GuEqHb3Vomdb7AKDnWkIH7bpysNb9GbKEk7awQpGSg==}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /turbo-windows-64/1.6.2:
+ resolution: {integrity: sha512-j4mJmY5pEt7OaBXDM99BpDnJuSpiLVbVbUl4Ezp8w3gyIcGuxy3wAfLbQyZSLu8ke6R9SdmXIBAM2Y0MjS/Z1g==}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /turbo-windows-arm64/1.6.2:
+ resolution: {integrity: sha512-AlDYjxPU21YSefP3qMl/Zys5spglXtaBt2ZF5N2+OWcjiJZ/0mIIc69oFdzuAuiyoYkyWMdkoCSGwuljtl31vg==}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ dev: true
+ optional: true
+
+ /turbo/1.6.2:
+ resolution: {integrity: sha512-a6UM9HaAjM5ai+vxDFI/z0l4Bf6zWjf7wCf9Ip2iyd4XZkZZnhRtM6FpaUWzorjz9Dsqnfwu3nkWY3wPdH02IQ==}
+ hasBin: true
+ requiresBuild: true
+ optionalDependencies:
+ turbo-darwin-64: 1.6.2
+ turbo-darwin-arm64: 1.6.2
+ turbo-linux-64: 1.6.2
+ turbo-linux-arm64: 1.6.2
+ turbo-windows-64: 1.6.2
+ turbo-windows-arm64: 1.6.2
+ dev: true
+
+ /type-check/0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+ dependencies:
+ prelude-ls: 1.2.1
+
+ /type-fest/0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
+ engines: {node: '>=10'}
+
+ /type-is/1.6.18:
+ resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
+ engines: {node: '>= 0.6'}
+ dependencies:
+ media-typer: 0.3.0
+ mime-types: 2.1.35
+ dev: false
+
+ /typescript/4.8.4:
+ resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==}
+ engines: {node: '>=4.2.0'}
+ hasBin: true
+
+ /unbox-primitive/1.0.2:
+ resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
+ dependencies:
+ call-bind: 1.0.2
+ has-bigints: 1.0.2
+ has-symbols: 1.0.3
+ which-boxed-primitive: 1.0.2
+ dev: false
+
+ /unpipe/1.0.0:
+ resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
+ engines: {node: '>= 0.8'}
+ dev: false
+
+ /update-browserslist-db/1.0.10_browserslist@4.21.4:
+ resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+ dependencies:
+ browserslist: 4.21.4
+ escalade: 3.1.1
+ picocolors: 1.0.0
+
+ /uri-js/4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ dependencies:
+ punycode: 2.1.1
+
+ /use-sync-external-store/1.2.0_react@18.2.0:
+ resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ dependencies:
+ react: 18.2.0
+ dev: false
+
+ /utils-merge/1.0.1:
+ resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
+ engines: {node: '>= 0.4.0'}
+ dev: false
+
+ /v8-compile-cache/2.3.0:
+ resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
+
+ /vary/1.1.2:
+ resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
+ engines: {node: '>= 0.8'}
+ dev: false
+
+ /which-boxed-primitive/1.0.2:
+ resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
+ dependencies:
+ is-bigint: 1.0.4
+ is-boolean-object: 1.1.2
+ is-number-object: 1.0.7
+ is-string: 1.0.7
+ is-symbol: 1.0.4
+ dev: false
+
+ /which/2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+ dependencies:
+ isexe: 2.0.0
+
+ /word-wrap/1.2.3:
+ resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
+ engines: {node: '>=0.10.0'}
+
+ /wrappy/1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ /yallist/4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+
+ /zod/3.19.1:
+ resolution: {integrity: sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA==}
+ dev: false
diff --git a/examples/next-turbo/pnpm-workspace.yaml b/examples/next-turbo/pnpm-workspace.yaml
new file mode 100644
index 00000000..3ff5faaa
--- /dev/null
+++ b/examples/next-turbo/pnpm-workspace.yaml
@@ -0,0 +1,3 @@
+packages:
+ - "apps/*"
+ - "packages/*"
diff --git a/examples/next-turbo/turbo.json b/examples/next-turbo/turbo.json
new file mode 100644
index 00000000..c2601a49
--- /dev/null
+++ b/examples/next-turbo/turbo.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "https://turborepo.org/schema.json",
+ "pipeline": {
+ "build": {
+ "dependsOn": ["^build"],
+ "outputs": ["dist/**", ".next/**"]
+ },
+ "lint": {
+ "outputs": []
+ },
+ "dev": {
+ "cache": false
+ }
+ }
+}
diff --git a/examples/next/.eslintrc.json b/examples/next/.eslintrc.json
new file mode 100644
index 00000000..bffb357a
--- /dev/null
+++ b/examples/next/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "next/core-web-vitals"
+}
diff --git a/examples/next/.gitignore b/examples/next/.gitignore
new file mode 100644
index 00000000..c87c9b39
--- /dev/null
+++ b/examples/next/.gitignore
@@ -0,0 +1,36 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+.pnpm-debug.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/examples/next/README.md b/examples/next/README.md
new file mode 100644
index 00000000..c87e0421
--- /dev/null
+++ b/examples/next/README.md
@@ -0,0 +1,34 @@
+This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
+
+## Getting Started
+
+First, run the development server:
+
+```bash
+npm run dev
+# or
+yarn dev
+```
+
+Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
+
+You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
+
+[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
+
+The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
+
+## Learn More
+
+To learn more about Next.js, take a look at the following resources:
+
+- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
+- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
+
+You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
+
+## Deploy on Vercel
+
+The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
diff --git a/examples/next/client/api.ts b/examples/next/client/api.ts
new file mode 100644
index 00000000..4e1032d7
--- /dev/null
+++ b/examples/next/client/api.ts
@@ -0,0 +1,6 @@
+import { Zodios } from "@zodios/core";
+import { ZodiosHooks } from "@zodios/react";
+import { userApi } from "../common/api";
+
+export const userClientApi = new Zodios("/api", userApi);
+export const userClientHooks = new ZodiosHooks("users", userClientApi);
diff --git a/examples/next/common/api.ts b/examples/next/common/api.ts
new file mode 100644
index 00000000..1297ee2f
--- /dev/null
+++ b/examples/next/common/api.ts
@@ -0,0 +1,55 @@
+import z from "zod";
+import { makeApi } from "@zodios/core";
+
+const user = z.object({
+ id: z.number(),
+ name: z.string(),
+ age: z.number().positive(),
+ email: z.string().email(),
+});
+
+export const userApi = makeApi([
+ {
+ method: "get",
+ path: "/users",
+ alias: "getUsers",
+ response: z.array(user),
+ },
+ {
+ method: "get",
+ path: "/users/:id",
+ alias: "getUser",
+ parameters: [
+ {
+ name: "id",
+ type: "Path",
+ schema: z.number().positive(),
+ },
+ ],
+ response: user,
+ errors: [
+ {
+ status: "default",
+ schema: z.object({
+ error: z.object({
+ code: z.number(),
+ message: z.string(),
+ }),
+ }),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/users",
+ alias: "createUser",
+ parameters: [
+ {
+ name: "user",
+ type: "Body",
+ schema: user.omit({ id: true }),
+ },
+ ],
+ response: user,
+ },
+]);
diff --git a/examples/next/next.config.js b/examples/next/next.config.js
new file mode 100644
index 00000000..3d3bc999
--- /dev/null
+++ b/examples/next/next.config.js
@@ -0,0 +1,7 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ reactStrictMode: true,
+ swcMinify: true,
+};
+
+module.exports = nextConfig;
diff --git a/examples/next/package.json b/examples/next/package.json
new file mode 100644
index 00000000..5b20c79b
--- /dev/null
+++ b/examples/next/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "zodios-next-app",
+ "version": "0.1.0",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start",
+ "lint": "next lint"
+ },
+ "dependencies": {
+ "@tanstack/react-query": "4.13.0",
+ "@zodios/core": "10.7.3",
+ "@zodios/express": "10.4.4",
+ "@zodios/react": "10.4.3",
+ "axios": "1.2.6",
+ "express": "4.18.2",
+ "next": "12.2.5",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "zod": "3.20.2"
+ },
+ "devDependencies": {
+ "@types/express": "4.17.16",
+ "@types/node": "18.11.18",
+ "@types/react": "18.0.27",
+ "@types/react-dom": "18.0.10",
+ "eslint": "8.32.0",
+ "eslint-config-next": "12.2.5",
+ "typescript": "5.0.2"
+ }
+}
diff --git a/examples/next/pages/_app.tsx b/examples/next/pages/_app.tsx
new file mode 100644
index 00000000..efb90d6a
--- /dev/null
+++ b/examples/next/pages/_app.tsx
@@ -0,0 +1,15 @@
+import "../styles/globals.css";
+import type { AppProps } from "next/app";
+import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
+
+const queryClient = new QueryClient();
+
+function MyApp({ Component, pageProps }: AppProps) {
+ return (
+
+
+
+ );
+}
+
+export default MyApp;
diff --git a/examples/next/pages/api/[...zodios].ts b/examples/next/pages/api/[...zodios].ts
new file mode 100644
index 00000000..0d172f46
--- /dev/null
+++ b/examples/next/pages/api/[...zodios].ts
@@ -0,0 +1,3 @@
+import { app } from "../../server/routers/app";
+
+export default app;
diff --git a/examples/next/pages/index.tsx b/examples/next/pages/index.tsx
new file mode 100644
index 00000000..143fa8e4
--- /dev/null
+++ b/examples/next/pages/index.tsx
@@ -0,0 +1,62 @@
+import type { NextPage } from "next";
+import { useState } from "react";
+import Head from "next/head";
+import styles from "../styles/Home.module.css";
+import { userClientHooks } from "../client/api";
+
+const Users = () => {
+ const [count, setCount] = useState(1);
+ const {
+ data: users,
+ error,
+ isLoading,
+ invalidate,
+ } = userClientHooks.useGetUsers();
+ const { mutate } = userClientHooks.useMutation("post", "/users", undefined, {
+ onSuccess: () => invalidate(),
+ });
+ if (isLoading) {
+ return Loading...
;
+ }
+ if (error) {
+ return {JSON.stringify(error)}
;
+ }
+
+ return (
+
+
+ {users?.map((user) => (
+
+ {user.name} - {user.email}
+
+ ))}
+
+ );
+};
+
+const Home: NextPage = () => {
+ return (
+
+
+
Zodios Example App
+
+
+
+ Users
+
+
+ );
+};
+
+export default Home;
diff --git a/examples/next/public/favicon.ico b/examples/next/public/favicon.ico
new file mode 100644
index 00000000..718d6fea
Binary files /dev/null and b/examples/next/public/favicon.ico differ
diff --git a/examples/next/public/vercel.svg b/examples/next/public/vercel.svg
new file mode 100644
index 00000000..fbf0e25a
--- /dev/null
+++ b/examples/next/public/vercel.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/examples/next/server/context.ts b/examples/next/server/context.ts
new file mode 100644
index 00000000..0fa7e09d
--- /dev/null
+++ b/examples/next/server/context.ts
@@ -0,0 +1,10 @@
+import { zodiosContext } from "@zodios/express";
+import z from "zod";
+
+const user = z.object({
+ id: z.number(),
+ name: z.string(),
+ email: z.string().email(),
+});
+
+export const ctx = zodiosContext(z.object({ user }));
diff --git a/examples/next/server/routers/app.ts b/examples/next/server/routers/app.ts
new file mode 100644
index 00000000..cf8a07b2
--- /dev/null
+++ b/examples/next/server/routers/app.ts
@@ -0,0 +1,5 @@
+import { ctx } from "../context";
+import { userRouter } from "./users";
+
+export const app = ctx.nextApp();
+app.use("/api", userRouter);
diff --git a/examples/next/server/routers/users.ts b/examples/next/server/routers/users.ts
new file mode 100644
index 00000000..6929bd1b
--- /dev/null
+++ b/examples/next/server/routers/users.ts
@@ -0,0 +1,37 @@
+import { ctx } from "../context";
+import { userApi } from "../../common/api";
+
+const users = [
+ {
+ id: 1,
+ name: "John Doe",
+ age: 30,
+ email: "john.doe@test.com",
+ },
+];
+
+export const userRouter = ctx.router(userApi);
+
+userRouter.get("/users", (req, res) => {
+ return res.status(200).json(users);
+});
+
+userRouter.get("/users/:id", (req, res) => {
+ const user = users.find((u) => u.id === req.params.id);
+ if (!user) {
+ return res.status(404).json({
+ error: {
+ code: 404,
+ message: "User not found",
+ },
+ });
+ }
+ return res.status(200).json(user);
+});
+
+userRouter.post("/users", (req, res) => {
+ const id = users.length + 1;
+ const user = { ...req.body, id };
+ users.push(user);
+ return res.status(201).json(user);
+});
diff --git a/examples/next/styles/Home.module.css b/examples/next/styles/Home.module.css
new file mode 100644
index 00000000..bd50f42f
--- /dev/null
+++ b/examples/next/styles/Home.module.css
@@ -0,0 +1,129 @@
+.container {
+ padding: 0 2rem;
+}
+
+.main {
+ min-height: 100vh;
+ padding: 4rem 0;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.footer {
+ display: flex;
+ flex: 1;
+ padding: 2rem 0;
+ border-top: 1px solid #eaeaea;
+ justify-content: center;
+ align-items: center;
+}
+
+.footer a {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-grow: 1;
+}
+
+.title a {
+ color: #0070f3;
+ text-decoration: none;
+}
+
+.title a:hover,
+.title a:focus,
+.title a:active {
+ text-decoration: underline;
+}
+
+.title {
+ margin: 0;
+ line-height: 1.15;
+ font-size: 4rem;
+}
+
+.title,
+.description {
+ text-align: center;
+}
+
+.description {
+ margin: 4rem 0;
+ line-height: 1.5;
+ font-size: 1.5rem;
+}
+
+.code {
+ background: #fafafa;
+ border-radius: 5px;
+ padding: 0.75rem;
+ font-size: 1.1rem;
+ font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
+ Bitstream Vera Sans Mono, Courier New, monospace;
+}
+
+.grid {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-wrap: wrap;
+ max-width: 800px;
+}
+
+.card {
+ margin: 1rem;
+ padding: 1.5rem;
+ text-align: left;
+ color: inherit;
+ text-decoration: none;
+ border: 1px solid #eaeaea;
+ border-radius: 10px;
+ transition: color 0.15s ease, border-color 0.15s ease;
+ max-width: 300px;
+}
+
+.card:hover,
+.card:focus,
+.card:active {
+ color: #0070f3;
+ border-color: #0070f3;
+}
+
+.card h2 {
+ margin: 0 0 1rem 0;
+ font-size: 1.5rem;
+}
+
+.card p {
+ margin: 0;
+ font-size: 1.25rem;
+ line-height: 1.5;
+}
+
+.logo {
+ height: 1em;
+ margin-left: 0.5rem;
+}
+
+@media (max-width: 600px) {
+ .grid {
+ width: 100%;
+ flex-direction: column;
+ }
+}
+
+@media (prefers-color-scheme: dark) {
+ .card,
+ .footer {
+ border-color: #222;
+ }
+ .code {
+ background: #111;
+ }
+ .logo img {
+ filter: invert(1);
+ }
+}
diff --git a/examples/next/styles/globals.css b/examples/next/styles/globals.css
new file mode 100644
index 00000000..4f184216
--- /dev/null
+++ b/examples/next/styles/globals.css
@@ -0,0 +1,26 @@
+html,
+body {
+ padding: 0;
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
+ Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+
+* {
+ box-sizing: border-box;
+}
+
+@media (prefers-color-scheme: dark) {
+ html {
+ color-scheme: dark;
+ }
+ body {
+ color: white;
+ background: black;
+ }
+}
diff --git a/examples/next/tsconfig.json b/examples/next/tsconfig.json
new file mode 100644
index 00000000..99710e85
--- /dev/null
+++ b/examples/next/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}
diff --git a/examples/next/yarn.lock b/examples/next/yarn.lock
new file mode 100644
index 00000000..449d1523
--- /dev/null
+++ b/examples/next/yarn.lock
@@ -0,0 +1,2225 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@babel/runtime-corejs3@^7.10.2":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.18.9.tgz#7bacecd1cb2dd694eacd32a91fcf7021c20770ae"
+ integrity sha512-qZEWeccZCrHA2Au4/X05QW5CMdm4VjUDCrGq5gf1ZDcM4hRqreKrtwAn7yci9zfgAS9apvnsFXiGBHBAxZdK9A==
+ dependencies:
+ core-js-pure "^3.20.2"
+ regenerator-runtime "^0.13.4"
+
+"@babel/runtime@^7.10.2", "@babel/runtime@^7.18.9":
+ version "7.18.9"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"
+ integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
+"@eslint/eslintrc@^1.4.1":
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz#af58772019a2d271b7e2d4c23ff4ddcba3ccfb3e"
+ integrity sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==
+ dependencies:
+ ajv "^6.12.4"
+ debug "^4.3.2"
+ espree "^9.4.0"
+ globals "^13.19.0"
+ ignore "^5.2.0"
+ import-fresh "^3.2.1"
+ js-yaml "^4.1.0"
+ minimatch "^3.1.2"
+ strip-json-comments "^3.1.1"
+
+"@humanwhocodes/config-array@^0.11.8":
+ version "0.11.8"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9"
+ integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==
+ dependencies:
+ "@humanwhocodes/object-schema" "^1.2.1"
+ debug "^4.1.1"
+ minimatch "^3.0.5"
+
+"@humanwhocodes/module-importer@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
+ integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
+
+"@humanwhocodes/object-schema@^1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
+ integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
+
+"@next/env@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/env/-/env-12.2.5.tgz#d908c57b35262b94db3e431e869b72ac3e1ad3e3"
+ integrity sha512-vLPLV3cpPGjUPT3PjgRj7e3nio9t6USkuew3JE/jMeon/9Mvp1WyR18v3iwnCuX7eUAm1HmAbJHHLAbcu/EJcw==
+
+"@next/eslint-plugin-next@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-12.2.5.tgz#4f3acccd2ed4f9300fbf9fd480cc8a0b261889a8"
+ integrity sha512-VBjVbmqEzGiOTBq4+wpeVXt/KgknnGB6ahvC/AxiIGnN93/RCSyXhFRI4uSfftM2Ba3w7ZO7076bfKasZsA0fw==
+ dependencies:
+ glob "7.1.7"
+
+"@next/swc-android-arm-eabi@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.2.5.tgz#903a5479ab4c2705d9c08d080907475f7bacf94d"
+ integrity sha512-cPWClKxGhgn2dLWnspW+7psl3MoLQUcNqJqOHk2BhNcou9ARDtC0IjQkKe5qcn9qg7I7U83Gp1yh2aesZfZJMA==
+
+"@next/swc-android-arm64@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.2.5.tgz#2f9a98ec4166c7860510963b31bda1f57a77c792"
+ integrity sha512-vMj0efliXmC5b7p+wfcQCX0AfU8IypjkzT64GiKJD9PgiA3IILNiGJr1fw2lyUDHkjeWx/5HMlMEpLnTsQslwg==
+
+"@next/swc-darwin-arm64@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.2.5.tgz#31b1c3c659d54be546120c488a1e1bad21c24a1d"
+ integrity sha512-VOPWbO5EFr6snla/WcxUKtvzGVShfs302TEMOtzYyWni6f9zuOetijJvVh9CCTzInnXAZMtHyNhefijA4HMYLg==
+
+"@next/swc-darwin-x64@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.2.5.tgz#2e44dd82b2b7fef88238d1bc4d3bead5884cedfd"
+ integrity sha512-5o8bTCgAmtYOgauO/Xd27vW52G2/m3i5PX7MUYePquxXAnX73AAtqA3WgPXBRitEB60plSKZgOTkcpqrsh546A==
+
+"@next/swc-freebsd-x64@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.2.5.tgz#e24e75d8c2581bfebc75e4f08f6ddbd116ce9dbd"
+ integrity sha512-yYUbyup1JnznMtEBRkK4LT56N0lfK5qNTzr6/DEyDw5TbFVwnuy2hhLBzwCBkScFVjpFdfiC6SQAX3FrAZzuuw==
+
+"@next/swc-linux-arm-gnueabihf@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.2.5.tgz#46d8c514d834d2b5f67086013f0bd5e3081e10b9"
+ integrity sha512-2ZE2/G921Acks7UopJZVMgKLdm4vN4U0yuzvAMJ6KBavPzqESA2yHJlm85TV/K9gIjKhSk5BVtauIUntFRP8cg==
+
+"@next/swc-linux-arm64-gnu@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.2.5.tgz#91f725ac217d3a1f4f9f53b553615ba582fd3d9f"
+ integrity sha512-/I6+PWVlz2wkTdWqhlSYYJ1pWWgUVva6SgX353oqTh8njNQp1SdFQuWDqk8LnM6ulheVfSsgkDzxrDaAQZnzjQ==
+
+"@next/swc-linux-arm64-musl@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.2.5.tgz#e627e8c867920995810250303cd9b8e963598383"
+ integrity sha512-LPQRelfX6asXyVr59p5sTpx5l+0yh2Vjp/R8Wi4X9pnqcayqT4CUJLiHqCvZuLin3IsFdisJL0rKHMoaZLRfmg==
+
+"@next/swc-linux-x64-gnu@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.2.5.tgz#83a5e224fbc4d119ef2e0f29d0d79c40cc43887e"
+ integrity sha512-0szyAo8jMCClkjNK0hknjhmAngUppoRekW6OAezbEYwHXN/VNtsXbfzgYOqjKWxEx3OoAzrT3jLwAF0HdX2MEw==
+
+"@next/swc-linux-x64-musl@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.2.5.tgz#be700d48471baac1ec2e9539396625584a317e95"
+ integrity sha512-zg/Y6oBar1yVnW6Il1I/08/2ukWtOG6s3acdJdEyIdsCzyQi4RLxbbhkD/EGQyhqBvd3QrC6ZXQEXighQUAZ0g==
+
+"@next/swc-win32-arm64-msvc@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.2.5.tgz#a93e958133ad3310373fda33a79aa10af2a0aa97"
+ integrity sha512-3/90DRNSqeeSRMMEhj4gHHQlLhhKg5SCCoYfE3kBjGpE63EfnblYUqsszGGZ9ekpKL/R4/SGB40iCQr8tR5Jiw==
+
+"@next/swc-win32-ia32-msvc@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.2.5.tgz#4f5f7ba0a98ff89a883625d4af0125baed8b2e19"
+ integrity sha512-hGLc0ZRAwnaPL4ulwpp4D2RxmkHQLuI8CFOEEHdzZpS63/hMVzv81g8jzYA0UXbb9pus/iTc3VRbVbAM03SRrw==
+
+"@next/swc-win32-x64-msvc@12.2.5":
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.2.5.tgz#20fed129b04a0d3f632c6d0de135345bb623b1e4"
+ integrity sha512-7h5/ahY7NeaO2xygqVrSG/Y8Vs4cdjxIjowTZ5W6CKoTKn7tmnuxlUc2h74x06FKmbhAd9agOjr/AOKyxYYm9Q==
+
+"@nodelib/fs.scandir@2.1.5":
+ version "2.1.5"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
+ integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
+ dependencies:
+ "@nodelib/fs.stat" "2.0.5"
+ run-parallel "^1.1.9"
+
+"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
+ integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
+
+"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8":
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
+ integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
+ dependencies:
+ "@nodelib/fs.scandir" "2.1.5"
+ fastq "^1.6.0"
+
+"@rushstack/eslint-patch@^1.1.3":
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz#0c8b74c50f29ee44f423f7416829c0bf8bb5eb27"
+ integrity sha512-LwzQKA4vzIct1zNZzBmRKI9QuNpLgTQMEjsQLf3BXuGYb3QPTP4Yjf6mkdX+X1mYttZ808QpOwAzZjv28kq7DA==
+
+"@swc/helpers@0.4.3":
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.3.tgz#16593dfc248c53b699d4b5026040f88ddb497012"
+ integrity sha512-6JrF+fdUK2zbGpJIlN7G3v966PQjyx/dPt1T9km2wj+EUBqgrxCk3uX4Kct16MIm9gGxfKRcfax2hVf5jvlTzA==
+ dependencies:
+ tslib "^2.4.0"
+
+"@tanstack/query-core@4.13.0":
+ version "4.13.0"
+ resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.13.0.tgz#89153096d1fce42c0294fa1d1ae4b3e72aa5353b"
+ integrity sha512-PzmLQcEgC4rl2OzkiPHYPC9O79DFcMGaKsOzDEP+U4PJ+tbkcEP+Z+FQDlfvX8mCwYC7UNH7hXrQ5EdkGlJjVg==
+
+"@tanstack/react-query@4.13.0":
+ version "4.13.0"
+ resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.13.0.tgz#13797d590a6c0708545881e38aea5eb39b960c28"
+ integrity sha512-dI/5hJ/pGQ74P5hxBLC9h6K0/Cap2T3k0ZjjjFLBCNnohDYgl7LNmMopzrRzBHk2mMjf2hgXHIzcKNG8GOZ5hg==
+ dependencies:
+ "@tanstack/query-core" "4.13.0"
+ use-sync-external-store "^1.2.0"
+
+"@types/body-parser@*":
+ version "1.19.2"
+ resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0"
+ integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==
+ dependencies:
+ "@types/connect" "*"
+ "@types/node" "*"
+
+"@types/connect@*":
+ version "3.4.35"
+ resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1"
+ integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==
+ dependencies:
+ "@types/node" "*"
+
+"@types/express-serve-static-core@^4.17.31":
+ version "4.17.33"
+ resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz#de35d30a9d637dc1450ad18dd583d75d5733d543"
+ integrity sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==
+ dependencies:
+ "@types/node" "*"
+ "@types/qs" "*"
+ "@types/range-parser" "*"
+
+"@types/express@4.17.16":
+ version "4.17.16"
+ resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.16.tgz#986caf0b4b850611254505355daa24e1b8323de8"
+ integrity sha512-LkKpqRZ7zqXJuvoELakaFYuETHjZkSol8EV6cNnyishutDBCCdv6+dsKPbKkCcIk57qRphOLY5sEgClw1bO3gA==
+ dependencies:
+ "@types/body-parser" "*"
+ "@types/express-serve-static-core" "^4.17.31"
+ "@types/qs" "*"
+ "@types/serve-static" "*"
+
+"@types/json5@^0.0.29":
+ version "0.0.29"
+ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
+ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
+
+"@types/mime@*":
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
+ integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==
+
+"@types/node@*":
+ version "18.7.13"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.13.tgz#23e6c5168333480d454243378b69e861ab5c011a"
+ integrity sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==
+
+"@types/node@18.11.18":
+ version "18.11.18"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
+ integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==
+
+"@types/prop-types@*":
+ version "15.7.5"
+ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
+ integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
+
+"@types/qs@*":
+ version "6.9.7"
+ resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb"
+ integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==
+
+"@types/range-parser@*":
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc"
+ integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==
+
+"@types/react-dom@18.0.10":
+ version "18.0.10"
+ resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.10.tgz#3b66dec56aa0f16a6cc26da9e9ca96c35c0b4352"
+ integrity sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==
+ dependencies:
+ "@types/react" "*"
+
+"@types/react@*":
+ version "18.0.17"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.17.tgz#4583d9c322d67efe4b39a935d223edcc7050ccf4"
+ integrity sha512-38ETy4tL+rn4uQQi7mB81G7V1g0u2ryquNmsVIOKUAEIDK+3CUjZ6rSRpdvS99dNBnkLFL83qfmtLacGOTIhwQ==
+ dependencies:
+ "@types/prop-types" "*"
+ "@types/scheduler" "*"
+ csstype "^3.0.2"
+
+"@types/react@18.0.27":
+ version "18.0.27"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.27.tgz#d9425abe187a00f8a5ec182b010d4fd9da703b71"
+ integrity sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==
+ dependencies:
+ "@types/prop-types" "*"
+ "@types/scheduler" "*"
+ csstype "^3.0.2"
+
+"@types/scheduler@*":
+ version "0.16.2"
+ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
+ integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
+
+"@types/serve-static@*":
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155"
+ integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==
+ dependencies:
+ "@types/mime" "*"
+ "@types/node" "*"
+
+"@typescript-eslint/parser@^5.21.0":
+ version "5.35.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.35.1.tgz#bf2ee2ebeaa0a0567213748243fb4eec2857f04f"
+ integrity sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg==
+ dependencies:
+ "@typescript-eslint/scope-manager" "5.35.1"
+ "@typescript-eslint/types" "5.35.1"
+ "@typescript-eslint/typescript-estree" "5.35.1"
+ debug "^4.3.4"
+
+"@typescript-eslint/scope-manager@5.35.1":
+ version "5.35.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.35.1.tgz#ccb69d54b7fd0f2d0226a11a75a8f311f525ff9e"
+ integrity sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q==
+ dependencies:
+ "@typescript-eslint/types" "5.35.1"
+ "@typescript-eslint/visitor-keys" "5.35.1"
+
+"@typescript-eslint/types@5.35.1":
+ version "5.35.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.35.1.tgz#af355fe52a0cc88301e889bc4ada72f279b63d61"
+ integrity sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==
+
+"@typescript-eslint/typescript-estree@5.35.1":
+ version "5.35.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.35.1.tgz#db878a39a0dbdc9bb133f11cdad451770bfba211"
+ integrity sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==
+ dependencies:
+ "@typescript-eslint/types" "5.35.1"
+ "@typescript-eslint/visitor-keys" "5.35.1"
+ debug "^4.3.4"
+ globby "^11.1.0"
+ is-glob "^4.0.3"
+ semver "^7.3.7"
+ tsutils "^3.21.0"
+
+"@typescript-eslint/visitor-keys@5.35.1":
+ version "5.35.1"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.35.1.tgz#285e9e34aed7c876f16ff646a3984010035898e6"
+ integrity sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g==
+ dependencies:
+ "@typescript-eslint/types" "5.35.1"
+ eslint-visitor-keys "^3.3.0"
+
+"@zodios/core@10.7.3":
+ version "10.7.3"
+ resolved "https://registry.yarnpkg.com/@zodios/core/-/core-10.7.3.tgz#813f3c27d42f00ece960941b61626b8d47317554"
+ integrity sha512-O28q7FbamQP6vkdRH1rRh1JEDGVilDmFBW4HAJKs2DNt/Q25yZHqsegb+plfAMcbVuvU7rfnS0e0pK0LLAOT+g==
+
+"@zodios/express@10.4.4":
+ version "10.4.4"
+ resolved "https://registry.yarnpkg.com/@zodios/express/-/express-10.4.4.tgz#dc21666bb99d1cc18ddcfa97f37767040c0d1590"
+ integrity sha512-hOVkorK/ORQ5yHQdflhI9mvNG+Pzhp1ZJuL9C39FE8qiIVz0orFAzUAYdBLVAwFptg77bAFcIF2RUx5OuetqKw==
+
+"@zodios/react@10.4.3":
+ version "10.4.3"
+ resolved "https://registry.yarnpkg.com/@zodios/react/-/react-10.4.3.tgz#08c346c859a635a39c9f59bbcc607959aeccbfc6"
+ integrity sha512-J3Rgnlhr5p+Hv3EFUgeLhg4/YQta3+yMLU+bHw1CH+7tECmVvn1In5Q9Z4TDzczLMArINIGevjAuiNQ/Dwbwfw==
+
+accepts@~1.3.8:
+ version "1.3.8"
+ resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
+ integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
+ dependencies:
+ mime-types "~2.1.34"
+ negotiator "0.6.3"
+
+acorn-jsx@^5.3.2:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
+ integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
+
+acorn@^8.8.0:
+ version "8.8.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
+ integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
+
+ajv@^6.10.0, ajv@^6.12.4:
+ version "6.12.6"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
+ integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
+ 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"
+
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
+ansi-styles@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+ integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+ dependencies:
+ color-convert "^2.0.1"
+
+argparse@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
+ integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+
+aria-query@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b"
+ integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==
+ dependencies:
+ "@babel/runtime" "^7.10.2"
+ "@babel/runtime-corejs3" "^7.10.2"
+
+array-flatten@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
+ integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
+
+array-includes@^3.1.4, array-includes@^3.1.5:
+ version "3.1.5"
+ resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb"
+ integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.19.5"
+ get-intrinsic "^1.1.1"
+ is-string "^1.0.7"
+
+array-union@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
+ integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
+
+array.prototype.flat@^1.2.5:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b"
+ integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.2"
+ es-shim-unscopables "^1.0.0"
+
+array.prototype.flatmap@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f"
+ integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.2"
+ es-shim-unscopables "^1.0.0"
+
+ast-types-flow@^0.0.7:
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
+ integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==
+
+asynckit@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+ integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
+
+axe-core@^4.4.3:
+ version "4.4.3"
+ resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f"
+ integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==
+
+axios@1.2.6:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.2.6.tgz#eacb6d065baa11bad5959e7ffa0cb6745c65f392"
+ integrity sha512-rC/7F08XxZwjMV4iuWv+JpD3E0Ksqg9nac4IIg6RwNuF0JTeWoCo/mBNG54+tNhhI11G3/VDRbdDQTs9hGp4pQ==
+ dependencies:
+ follow-redirects "^1.15.0"
+ form-data "^4.0.0"
+ proxy-from-env "^1.1.0"
+
+axobject-query@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
+ integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==
+
+balanced-match@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
+ integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+
+body-parser@1.20.1:
+ version "1.20.1"
+ resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
+ integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==
+ dependencies:
+ bytes "3.1.2"
+ content-type "~1.0.4"
+ debug "2.6.9"
+ depd "2.0.0"
+ destroy "1.2.0"
+ http-errors "2.0.0"
+ iconv-lite "0.4.24"
+ on-finished "2.4.1"
+ qs "6.11.0"
+ raw-body "2.5.1"
+ type-is "~1.6.18"
+ unpipe "1.0.0"
+
+brace-expansion@^1.1.7:
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
+ integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
+ dependencies:
+ balanced-match "^1.0.0"
+ concat-map "0.0.1"
+
+braces@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
+ integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+ dependencies:
+ fill-range "^7.0.1"
+
+bytes@3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
+ integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
+
+call-bind@^1.0.0, call-bind@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
+ integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
+ dependencies:
+ function-bind "^1.1.1"
+ get-intrinsic "^1.0.2"
+
+callsites@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
+ integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
+
+caniuse-lite@^1.0.30001332:
+ version "1.0.30001383"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001383.tgz#aecf317ccd940690725ae3ae4f28293c5fb8050e"
+ integrity sha512-swMpEoTp5vDoGBZsYZX7L7nXHe6dsHxi9o6/LKf/f0LukVtnrxly5GVb/fWdCDTqi/yw6Km6tiJ0pmBacm0gbg==
+
+chalk@^4.0.0:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
+ integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
+color-convert@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+ integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+ dependencies:
+ color-name "~1.1.4"
+
+color-name@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+ integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+combined-stream@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
+ integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
+ dependencies:
+ delayed-stream "~1.0.0"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+ integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
+
+content-disposition@0.5.4:
+ version "0.5.4"
+ resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
+ integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
+ dependencies:
+ safe-buffer "5.2.1"
+
+content-type@~1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
+ integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
+
+cookie-signature@1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
+ integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
+
+cookie@0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b"
+ integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==
+
+core-js-pure@^3.20.2:
+ version "3.25.0"
+ resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.25.0.tgz#f8d1f176ff29abbfeb610110de891d5ae5a361d4"
+ integrity sha512-IeHpLwk3uoci37yoI2Laty59+YqH9x5uR65/yiA0ARAJrTrN4YU0rmauLWfvqOuk77SlNJXj2rM6oT/dBD87+A==
+
+cross-spawn@^7.0.2:
+ version "7.0.3"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
+ integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
+ dependencies:
+ path-key "^3.1.0"
+ shebang-command "^2.0.0"
+ which "^2.0.1"
+
+csstype@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2"
+ integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==
+
+damerau-levenshtein@^1.0.8:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
+ integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==
+
+debug@2.6.9, debug@^2.6.9:
+ version "2.6.9"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
+ integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
+ dependencies:
+ ms "2.0.0"
+
+debug@^3.2.7:
+ version "3.2.7"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
+ integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
+ dependencies:
+ ms "^2.1.1"
+
+debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
+ integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
+ dependencies:
+ ms "2.1.2"
+
+deep-is@^0.1.3:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
+ integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
+
+define-properties@^1.1.3, define-properties@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1"
+ integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==
+ dependencies:
+ has-property-descriptors "^1.0.0"
+ object-keys "^1.1.1"
+
+delayed-stream@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+ integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
+
+depd@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
+ integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
+
+destroy@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
+ integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
+
+dir-glob@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
+ integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
+ dependencies:
+ path-type "^4.0.0"
+
+doctrine@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
+ integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
+ dependencies:
+ esutils "^2.0.2"
+
+doctrine@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961"
+ integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
+ dependencies:
+ esutils "^2.0.2"
+
+ee-first@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
+ integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
+
+emoji-regex@^9.2.2:
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
+ integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
+
+encodeurl@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
+ integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
+
+es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5:
+ version "1.20.1"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814"
+ integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==
+ dependencies:
+ call-bind "^1.0.2"
+ es-to-primitive "^1.2.1"
+ function-bind "^1.1.1"
+ function.prototype.name "^1.1.5"
+ get-intrinsic "^1.1.1"
+ get-symbol-description "^1.0.0"
+ has "^1.0.3"
+ has-property-descriptors "^1.0.0"
+ has-symbols "^1.0.3"
+ internal-slot "^1.0.3"
+ is-callable "^1.2.4"
+ is-negative-zero "^2.0.2"
+ is-regex "^1.1.4"
+ is-shared-array-buffer "^1.0.2"
+ is-string "^1.0.7"
+ is-weakref "^1.0.2"
+ object-inspect "^1.12.0"
+ object-keys "^1.1.1"
+ object.assign "^4.1.2"
+ regexp.prototype.flags "^1.4.3"
+ string.prototype.trimend "^1.0.5"
+ string.prototype.trimstart "^1.0.5"
+ unbox-primitive "^1.0.2"
+
+es-shim-unscopables@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241"
+ integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==
+ dependencies:
+ has "^1.0.3"
+
+es-to-primitive@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
+ integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
+ dependencies:
+ is-callable "^1.1.4"
+ is-date-object "^1.0.1"
+ is-symbol "^1.0.2"
+
+escape-html@~1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
+ integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
+
+escape-string-regexp@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
+ integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+
+eslint-config-next@12.2.5:
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-12.2.5.tgz#76ce83f18cc02f6f42ed407a127f83db54fabd3c"
+ integrity sha512-SOowilkqPzW6DxKp3a3SYlrfPi5Ajs9MIzp9gVfUDxxH9QFM5ElkR1hX5m/iICJuvCbWgQqFBiA3mCMozluniw==
+ dependencies:
+ "@next/eslint-plugin-next" "12.2.5"
+ "@rushstack/eslint-patch" "^1.1.3"
+ "@typescript-eslint/parser" "^5.21.0"
+ eslint-import-resolver-node "^0.3.6"
+ eslint-import-resolver-typescript "^2.7.1"
+ eslint-plugin-import "^2.26.0"
+ eslint-plugin-jsx-a11y "^6.5.1"
+ eslint-plugin-react "^7.29.4"
+ eslint-plugin-react-hooks "^4.5.0"
+
+eslint-import-resolver-node@^0.3.6:
+ version "0.3.6"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd"
+ integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==
+ dependencies:
+ debug "^3.2.7"
+ resolve "^1.20.0"
+
+eslint-import-resolver-typescript@^2.7.1:
+ version "2.7.1"
+ resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz#a90a4a1c80da8d632df25994c4c5fdcdd02b8751"
+ integrity sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==
+ dependencies:
+ debug "^4.3.4"
+ glob "^7.2.0"
+ is-glob "^4.0.3"
+ resolve "^1.22.0"
+ tsconfig-paths "^3.14.1"
+
+eslint-module-utils@^2.7.3:
+ version "2.7.4"
+ resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974"
+ integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==
+ dependencies:
+ debug "^3.2.7"
+
+eslint-plugin-import@^2.26.0:
+ version "2.26.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b"
+ integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==
+ dependencies:
+ array-includes "^3.1.4"
+ array.prototype.flat "^1.2.5"
+ debug "^2.6.9"
+ doctrine "^2.1.0"
+ eslint-import-resolver-node "^0.3.6"
+ eslint-module-utils "^2.7.3"
+ has "^1.0.3"
+ is-core-module "^2.8.1"
+ is-glob "^4.0.3"
+ minimatch "^3.1.2"
+ object.values "^1.1.5"
+ resolve "^1.22.0"
+ tsconfig-paths "^3.14.1"
+
+eslint-plugin-jsx-a11y@^6.5.1:
+ version "6.6.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz#93736fc91b83fdc38cc8d115deedfc3091aef1ff"
+ integrity sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==
+ dependencies:
+ "@babel/runtime" "^7.18.9"
+ aria-query "^4.2.2"
+ array-includes "^3.1.5"
+ ast-types-flow "^0.0.7"
+ axe-core "^4.4.3"
+ axobject-query "^2.2.0"
+ damerau-levenshtein "^1.0.8"
+ emoji-regex "^9.2.2"
+ has "^1.0.3"
+ jsx-ast-utils "^3.3.2"
+ language-tags "^1.0.5"
+ minimatch "^3.1.2"
+ semver "^6.3.0"
+
+eslint-plugin-react-hooks@^4.5.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3"
+ integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==
+
+eslint-plugin-react@^7.29.4:
+ version "7.31.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.1.tgz#d29793ed27743f3ed8a473c347b1bf5a0a8fb9af"
+ integrity sha512-j4/2xWqt/R7AZzG8CakGHA6Xa/u7iR8Q3xCxY+AUghdT92bnIDOBEefV456OeH0QvBcroVc0eyvrrLSyQGYIfg==
+ dependencies:
+ array-includes "^3.1.5"
+ array.prototype.flatmap "^1.3.0"
+ doctrine "^2.1.0"
+ estraverse "^5.3.0"
+ jsx-ast-utils "^2.4.1 || ^3.0.0"
+ minimatch "^3.1.2"
+ object.entries "^1.1.5"
+ object.fromentries "^2.0.5"
+ object.hasown "^1.1.1"
+ object.values "^1.1.5"
+ prop-types "^15.8.1"
+ resolve "^2.0.0-next.3"
+ semver "^6.3.0"
+ string.prototype.matchall "^4.0.7"
+
+eslint-scope@^7.1.1:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642"
+ integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==
+ dependencies:
+ esrecurse "^4.3.0"
+ estraverse "^5.2.0"
+
+eslint-utils@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672"
+ integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==
+ dependencies:
+ eslint-visitor-keys "^2.0.0"
+
+eslint-visitor-keys@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
+ integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
+
+eslint-visitor-keys@^3.3.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
+ integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
+
+eslint@8.32.0:
+ version "8.32.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.32.0.tgz#d9690056bb6f1a302bd991e7090f5b68fbaea861"
+ integrity sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==
+ dependencies:
+ "@eslint/eslintrc" "^1.4.1"
+ "@humanwhocodes/config-array" "^0.11.8"
+ "@humanwhocodes/module-importer" "^1.0.1"
+ "@nodelib/fs.walk" "^1.2.8"
+ ajv "^6.10.0"
+ chalk "^4.0.0"
+ cross-spawn "^7.0.2"
+ debug "^4.3.2"
+ doctrine "^3.0.0"
+ escape-string-regexp "^4.0.0"
+ eslint-scope "^7.1.1"
+ eslint-utils "^3.0.0"
+ eslint-visitor-keys "^3.3.0"
+ espree "^9.4.0"
+ esquery "^1.4.0"
+ esutils "^2.0.2"
+ fast-deep-equal "^3.1.3"
+ file-entry-cache "^6.0.1"
+ find-up "^5.0.0"
+ glob-parent "^6.0.2"
+ globals "^13.19.0"
+ grapheme-splitter "^1.0.4"
+ ignore "^5.2.0"
+ import-fresh "^3.0.0"
+ imurmurhash "^0.1.4"
+ is-glob "^4.0.0"
+ is-path-inside "^3.0.3"
+ js-sdsl "^4.1.4"
+ js-yaml "^4.1.0"
+ json-stable-stringify-without-jsonify "^1.0.1"
+ levn "^0.4.1"
+ lodash.merge "^4.6.2"
+ minimatch "^3.1.2"
+ natural-compare "^1.4.0"
+ optionator "^0.9.1"
+ regexpp "^3.2.0"
+ strip-ansi "^6.0.1"
+ strip-json-comments "^3.1.0"
+ text-table "^0.2.0"
+
+espree@^9.4.0:
+ version "9.4.0"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a"
+ integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==
+ dependencies:
+ acorn "^8.8.0"
+ acorn-jsx "^5.3.2"
+ eslint-visitor-keys "^3.3.0"
+
+esquery@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5"
+ integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==
+ dependencies:
+ estraverse "^5.1.0"
+
+esrecurse@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
+ integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
+ dependencies:
+ estraverse "^5.2.0"
+
+estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
+ integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
+
+esutils@^2.0.2:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
+ integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+
+etag@~1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
+ integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
+
+express@4.18.2:
+ version "4.18.2"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59"
+ integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==
+ dependencies:
+ accepts "~1.3.8"
+ array-flatten "1.1.1"
+ body-parser "1.20.1"
+ content-disposition "0.5.4"
+ content-type "~1.0.4"
+ cookie "0.5.0"
+ cookie-signature "1.0.6"
+ debug "2.6.9"
+ depd "2.0.0"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ etag "~1.8.1"
+ finalhandler "1.2.0"
+ fresh "0.5.2"
+ http-errors "2.0.0"
+ merge-descriptors "1.0.1"
+ methods "~1.1.2"
+ on-finished "2.4.1"
+ parseurl "~1.3.3"
+ path-to-regexp "0.1.7"
+ proxy-addr "~2.0.7"
+ qs "6.11.0"
+ range-parser "~1.2.1"
+ safe-buffer "5.2.1"
+ send "0.18.0"
+ serve-static "1.15.0"
+ setprototypeof "1.2.0"
+ statuses "2.0.1"
+ type-is "~1.6.18"
+ utils-merge "1.0.1"
+ vary "~1.1.2"
+
+fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
+ integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+
+fast-glob@^3.2.9:
+ version "3.2.11"
+ resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
+ integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
+ 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.4"
+
+fast-json-stable-stringify@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
+ integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
+
+fast-levenshtein@^2.0.6:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
+ integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
+
+fastq@^1.6.0:
+ version "1.13.0"
+ resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
+ integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==
+ dependencies:
+ reusify "^1.0.4"
+
+file-entry-cache@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
+ integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
+ dependencies:
+ flat-cache "^3.0.4"
+
+fill-range@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
+ integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
+ dependencies:
+ to-regex-range "^5.0.1"
+
+finalhandler@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
+ integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
+ dependencies:
+ debug "2.6.9"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ on-finished "2.4.1"
+ parseurl "~1.3.3"
+ statuses "2.0.1"
+ unpipe "~1.0.0"
+
+find-up@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
+ integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
+ dependencies:
+ locate-path "^6.0.0"
+ path-exists "^4.0.0"
+
+flat-cache@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
+ integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==
+ dependencies:
+ flatted "^3.1.0"
+ rimraf "^3.0.2"
+
+flatted@^3.1.0:
+ version "3.2.7"
+ resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
+ integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
+
+follow-redirects@^1.15.0:
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
+ integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
+
+form-data@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
+ integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
+ dependencies:
+ asynckit "^0.4.0"
+ combined-stream "^1.0.8"
+ mime-types "^2.1.12"
+
+forwarded@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
+ integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
+
+fresh@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
+ integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+ integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
+
+function-bind@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
+ integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+
+function.prototype.name@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621"
+ integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.0"
+ functions-have-names "^1.2.2"
+
+functions-have-names@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
+ integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
+
+get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598"
+ integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==
+ dependencies:
+ function-bind "^1.1.1"
+ has "^1.0.3"
+ has-symbols "^1.0.3"
+
+get-symbol-description@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6"
+ integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==
+ dependencies:
+ call-bind "^1.0.2"
+ get-intrinsic "^1.1.1"
+
+glob-parent@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
+ integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
+ dependencies:
+ is-glob "^4.0.1"
+
+glob-parent@^6.0.2:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
+ integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
+ dependencies:
+ is-glob "^4.0.3"
+
+glob@7.1.7:
+ version "7.1.7"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
+ integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.4"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+glob@^7.1.3, glob@^7.2.0:
+ version "7.2.3"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
+ integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
+ 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"
+
+globals@^13.19.0:
+ version "13.20.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82"
+ integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==
+ dependencies:
+ type-fest "^0.20.2"
+
+globby@^11.1.0:
+ version "11.1.0"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
+ integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
+ 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"
+
+grapheme-splitter@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
+ integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
+
+has-bigints@^1.0.1, has-bigints@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
+ integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
+
+has-flag@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
+ integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+
+has-property-descriptors@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861"
+ integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==
+ dependencies:
+ get-intrinsic "^1.1.1"
+
+has-symbols@^1.0.2, has-symbols@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
+ integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
+
+has-tostringtag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25"
+ integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==
+ dependencies:
+ has-symbols "^1.0.2"
+
+has@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
+ integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
+ dependencies:
+ function-bind "^1.1.1"
+
+http-errors@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
+ integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
+ dependencies:
+ depd "2.0.0"
+ inherits "2.0.4"
+ setprototypeof "1.2.0"
+ statuses "2.0.1"
+ toidentifier "1.0.1"
+
+iconv-lite@0.4.24:
+ version "0.4.24"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
+ integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3"
+
+ignore@^5.2.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
+ integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
+
+import-fresh@^3.0.0, import-fresh@^3.2.1:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
+ integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
+ dependencies:
+ parent-module "^1.0.0"
+ resolve-from "^4.0.0"
+
+imurmurhash@^0.1.4:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
+ integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2, inherits@2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
+ integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+
+internal-slot@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
+ integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==
+ dependencies:
+ get-intrinsic "^1.1.0"
+ has "^1.0.3"
+ side-channel "^1.0.4"
+
+ipaddr.js@1.9.1:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
+ integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
+
+is-bigint@^1.0.1:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
+ integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==
+ dependencies:
+ has-bigints "^1.0.1"
+
+is-boolean-object@^1.1.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
+ integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==
+ dependencies:
+ call-bind "^1.0.2"
+ has-tostringtag "^1.0.0"
+
+is-callable@^1.1.4, is-callable@^1.2.4:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
+ integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
+
+is-core-module@^2.8.1, is-core-module@^2.9.0:
+ version "2.10.0"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed"
+ integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==
+ dependencies:
+ has "^1.0.3"
+
+is-date-object@^1.0.1:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f"
+ integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-extglob@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
+ integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
+
+is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
+ integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
+ dependencies:
+ is-extglob "^2.1.1"
+
+is-negative-zero@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
+ integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
+
+is-number-object@^1.0.4:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc"
+ integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-number@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
+ integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+is-path-inside@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
+ integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
+
+is-regex@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
+ integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
+ dependencies:
+ call-bind "^1.0.2"
+ has-tostringtag "^1.0.0"
+
+is-shared-array-buffer@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
+ integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
+ dependencies:
+ call-bind "^1.0.2"
+
+is-string@^1.0.5, is-string@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
+ integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==
+ dependencies:
+ has-tostringtag "^1.0.0"
+
+is-symbol@^1.0.2, is-symbol@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c"
+ integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==
+ dependencies:
+ has-symbols "^1.0.2"
+
+is-weakref@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
+ integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
+ dependencies:
+ call-bind "^1.0.2"
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+ integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+
+js-sdsl@^4.1.4:
+ version "4.1.5"
+ resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a"
+ integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==
+
+"js-tokens@^3.0.0 || ^4.0.0":
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
+js-yaml@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
+ integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
+ dependencies:
+ argparse "^2.0.1"
+
+json-schema-traverse@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
+ integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
+
+json-stable-stringify-without-jsonify@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
+ integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
+
+json5@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
+ integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==
+ dependencies:
+ minimist "^1.2.0"
+
+"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.2:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea"
+ integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==
+ dependencies:
+ array-includes "^3.1.5"
+ object.assign "^4.1.3"
+
+language-subtag-registry@~0.3.2:
+ version "0.3.22"
+ resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d"
+ integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==
+
+language-tags@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a"
+ integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==
+ dependencies:
+ language-subtag-registry "~0.3.2"
+
+levn@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
+ integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
+ dependencies:
+ prelude-ls "^1.2.1"
+ type-check "~0.4.0"
+
+locate-path@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
+ integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
+ dependencies:
+ p-locate "^5.0.0"
+
+lodash.merge@^4.6.2:
+ version "4.6.2"
+ resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
+ integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
+
+loose-envify@^1.1.0, loose-envify@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
+ integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
+ dependencies:
+ js-tokens "^3.0.0 || ^4.0.0"
+
+lru-cache@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
+ integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
+ dependencies:
+ yallist "^4.0.0"
+
+media-typer@0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
+ integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
+
+merge-descriptors@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
+ integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
+
+merge2@^1.3.0, merge2@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
+ integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
+
+methods@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
+ integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
+
+micromatch@^4.0.4:
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
+ integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
+ dependencies:
+ braces "^3.0.2"
+ picomatch "^2.3.1"
+
+mime-db@1.52.0:
+ version "1.52.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
+ integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
+
+mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34:
+ version "2.1.35"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
+ integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
+ dependencies:
+ mime-db "1.52.0"
+
+mime@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
+ integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
+
+minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
+ integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
+ dependencies:
+ brace-expansion "^1.1.7"
+
+minimist@^1.2.0, minimist@^1.2.6:
+ version "1.2.6"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
+ integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
+
+ms@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
+ integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
+
+ms@2.1.2:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
+ integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+
+ms@2.1.3, ms@^2.1.1:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+nanoid@^3.3.4:
+ version "3.3.4"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
+ integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
+
+natural-compare@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
+ integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
+
+negotiator@0.6.3:
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
+ integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
+
+next@12.2.5:
+ version "12.2.5"
+ resolved "https://registry.yarnpkg.com/next/-/next-12.2.5.tgz#14fb5975e8841fad09553b8ef41fe1393602b717"
+ integrity sha512-tBdjqX5XC/oFs/6gxrZhjmiq90YWizUYU6qOWAfat7zJwrwapJ+BYgX2PmiacunXMaRpeVT4vz5MSPSLgNkrpA==
+ dependencies:
+ "@next/env" "12.2.5"
+ "@swc/helpers" "0.4.3"
+ caniuse-lite "^1.0.30001332"
+ postcss "8.4.14"
+ styled-jsx "5.0.4"
+ use-sync-external-store "1.2.0"
+ optionalDependencies:
+ "@next/swc-android-arm-eabi" "12.2.5"
+ "@next/swc-android-arm64" "12.2.5"
+ "@next/swc-darwin-arm64" "12.2.5"
+ "@next/swc-darwin-x64" "12.2.5"
+ "@next/swc-freebsd-x64" "12.2.5"
+ "@next/swc-linux-arm-gnueabihf" "12.2.5"
+ "@next/swc-linux-arm64-gnu" "12.2.5"
+ "@next/swc-linux-arm64-musl" "12.2.5"
+ "@next/swc-linux-x64-gnu" "12.2.5"
+ "@next/swc-linux-x64-musl" "12.2.5"
+ "@next/swc-win32-arm64-msvc" "12.2.5"
+ "@next/swc-win32-ia32-msvc" "12.2.5"
+ "@next/swc-win32-x64-msvc" "12.2.5"
+
+object-assign@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+ integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
+
+object-inspect@^1.12.0, object-inspect@^1.9.0:
+ version "1.12.2"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
+ integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
+
+object-keys@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
+ integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
+
+object.assign@^4.1.2, object.assign@^4.1.3:
+ version "4.1.4"
+ resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f"
+ integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ has-symbols "^1.0.3"
+ object-keys "^1.1.1"
+
+object.entries@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
+ integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+
+object.fromentries@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251"
+ integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+
+object.hasown@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.1.tgz#ad1eecc60d03f49460600430d97f23882cf592a3"
+ integrity sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==
+ dependencies:
+ define-properties "^1.1.4"
+ es-abstract "^1.19.5"
+
+object.values@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
+ integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+
+on-finished@2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
+ integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
+ dependencies:
+ ee-first "1.1.1"
+
+once@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
+ dependencies:
+ wrappy "1"
+
+optionator@^0.9.1:
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
+ integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==
+ 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.3"
+
+p-limit@^3.0.2:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
+ integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
+ dependencies:
+ yocto-queue "^0.1.0"
+
+p-locate@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
+ integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
+ dependencies:
+ p-limit "^3.0.2"
+
+parent-module@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
+ integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
+ dependencies:
+ callsites "^3.0.0"
+
+parseurl@~1.3.3:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
+ integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
+
+path-exists@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
+ integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+ integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
+
+path-key@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
+ integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+
+path-parse@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
+ integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
+
+path-to-regexp@0.1.7:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
+ integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
+
+path-type@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
+ integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+
+picocolors@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
+ integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
+
+picomatch@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
+ integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+
+postcss@8.4.14:
+ version "8.4.14"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf"
+ integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==
+ dependencies:
+ nanoid "^3.3.4"
+ picocolors "^1.0.0"
+ source-map-js "^1.0.2"
+
+prelude-ls@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
+ integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
+
+prop-types@^15.8.1:
+ version "15.8.1"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
+ integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
+ dependencies:
+ loose-envify "^1.4.0"
+ object-assign "^4.1.1"
+ react-is "^16.13.1"
+
+proxy-addr@~2.0.7:
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
+ integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
+ dependencies:
+ forwarded "0.2.0"
+ ipaddr.js "1.9.1"
+
+proxy-from-env@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
+ integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
+
+punycode@^2.1.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
+ integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+
+qs@6.11.0:
+ version "6.11.0"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a"
+ integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
+ dependencies:
+ side-channel "^1.0.4"
+
+queue-microtask@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
+ integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+
+range-parser@~1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
+ integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
+
+raw-body@2.5.1:
+ version "2.5.1"
+ resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857"
+ integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==
+ dependencies:
+ bytes "3.1.2"
+ http-errors "2.0.0"
+ iconv-lite "0.4.24"
+ unpipe "1.0.0"
+
+react-dom@18.2.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
+ integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
+ dependencies:
+ loose-envify "^1.1.0"
+ scheduler "^0.23.0"
+
+react-is@^16.13.1:
+ version "16.13.1"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
+ integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
+
+react@18.2.0:
+ version "18.2.0"
+ resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
+ integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
+ dependencies:
+ loose-envify "^1.1.0"
+
+regenerator-runtime@^0.13.4:
+ version "0.13.9"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
+ integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
+
+regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3:
+ version "1.4.3"
+ resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
+ integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ functions-have-names "^1.2.2"
+
+regexpp@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
+ integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
+
+resolve-from@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
+ integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
+
+resolve@^1.20.0, resolve@^1.22.0:
+ version "1.22.1"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
+ integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
+ dependencies:
+ is-core-module "^2.9.0"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
+
+resolve@^2.0.0-next.3:
+ version "2.0.0-next.4"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660"
+ integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==
+ dependencies:
+ is-core-module "^2.9.0"
+ path-parse "^1.0.7"
+ supports-preserve-symlinks-flag "^1.0.0"
+
+reusify@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
+ integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
+
+rimraf@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
+ integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
+ dependencies:
+ glob "^7.1.3"
+
+run-parallel@^1.1.9:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
+ integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
+ dependencies:
+ queue-microtask "^1.2.2"
+
+safe-buffer@5.2.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
+"safer-buffer@>= 2.1.2 < 3":
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
+ integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
+
+scheduler@^0.23.0:
+ version "0.23.0"
+ resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
+ integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
+ dependencies:
+ loose-envify "^1.1.0"
+
+semver@^6.3.0:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
+ integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+
+semver@^7.3.7:
+ version "7.3.7"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
+ integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
+ dependencies:
+ lru-cache "^6.0.0"
+
+send@0.18.0:
+ version "0.18.0"
+ resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
+ integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
+ dependencies:
+ debug "2.6.9"
+ depd "2.0.0"
+ destroy "1.2.0"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ etag "~1.8.1"
+ fresh "0.5.2"
+ http-errors "2.0.0"
+ mime "1.6.0"
+ ms "2.1.3"
+ on-finished "2.4.1"
+ range-parser "~1.2.1"
+ statuses "2.0.1"
+
+serve-static@1.15.0:
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
+ integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
+ dependencies:
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ parseurl "~1.3.3"
+ send "0.18.0"
+
+setprototypeof@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
+ integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
+
+shebang-command@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
+ integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
+ dependencies:
+ shebang-regex "^3.0.0"
+
+shebang-regex@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
+ integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+
+side-channel@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
+ integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
+ dependencies:
+ call-bind "^1.0.0"
+ get-intrinsic "^1.0.2"
+ object-inspect "^1.9.0"
+
+slash@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
+ integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+
+source-map-js@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
+ integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
+
+statuses@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
+ integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
+
+string.prototype.matchall@^4.0.7:
+ version "4.0.7"
+ resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d"
+ integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+ get-intrinsic "^1.1.1"
+ has-symbols "^1.0.3"
+ internal-slot "^1.0.3"
+ regexp.prototype.flags "^1.4.1"
+ side-channel "^1.0.4"
+
+string.prototype.trimend@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0"
+ integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.19.5"
+
+string.prototype.trimstart@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef"
+ integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==
+ dependencies:
+ call-bind "^1.0.2"
+ define-properties "^1.1.4"
+ es-abstract "^1.19.5"
+
+strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
+strip-bom@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+ integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
+
+strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
+ integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+
+styled-jsx@5.0.4:
+ version "5.0.4"
+ resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.4.tgz#5b1bd0b9ab44caae3dd1361295559706e044aa53"
+ integrity sha512-sDFWLbg4zR+UkNzfk5lPilyIgtpddfxXEULxhujorr5jtePTUqiPDc5BC0v1NRqTr/WaFBGQQUoYToGlF4B2KQ==
+
+supports-color@^7.1.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+ integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+ dependencies:
+ has-flag "^4.0.0"
+
+supports-preserve-symlinks-flag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
+ integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+
+text-table@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
+ integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
+
+to-regex-range@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
+ integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+ dependencies:
+ is-number "^7.0.0"
+
+toidentifier@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
+ integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
+
+tsconfig-paths@^3.14.1:
+ version "3.14.1"
+ resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"
+ integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==
+ dependencies:
+ "@types/json5" "^0.0.29"
+ json5 "^1.0.1"
+ minimist "^1.2.6"
+ strip-bom "^3.0.0"
+
+tslib@^1.8.1:
+ version "1.14.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
+ integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
+
+tslib@^2.4.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
+ integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
+
+tsutils@^3.21.0:
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"
+ integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
+ dependencies:
+ tslib "^1.8.1"
+
+type-check@^0.4.0, type-check@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
+ integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
+ dependencies:
+ prelude-ls "^1.2.1"
+
+type-fest@^0.20.2:
+ version "0.20.2"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
+ integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
+
+type-is@~1.6.18:
+ version "1.6.18"
+ resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
+ integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
+ dependencies:
+ media-typer "0.3.0"
+ mime-types "~2.1.24"
+
+typescript@4.9.4:
+ version "4.9.4"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78"
+ integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==
+
+unbox-primitive@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
+ integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==
+ dependencies:
+ call-bind "^1.0.2"
+ has-bigints "^1.0.2"
+ has-symbols "^1.0.3"
+ which-boxed-primitive "^1.0.2"
+
+unpipe@1.0.0, unpipe@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
+ integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
+
+uri-js@^4.2.2:
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
+ integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
+ dependencies:
+ punycode "^2.1.0"
+
+use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
+ integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
+
+utils-merge@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
+ integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
+
+vary@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
+ integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
+
+which-boxed-primitive@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
+ integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==
+ dependencies:
+ is-bigint "^1.0.1"
+ is-boolean-object "^1.1.0"
+ is-number-object "^1.0.4"
+ is-string "^1.0.5"
+ is-symbol "^1.0.3"
+
+which@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
+ integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
+ dependencies:
+ isexe "^2.0.0"
+
+word-wrap@^1.2.3:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
+ integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+ integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
+
+yallist@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
+ integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
+
+yocto-queue@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
+ integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+
+zod@3.20.2:
+ version "3.20.2"
+ resolved "https://registry.yarnpkg.com/zod/-/zod-3.20.2.tgz#068606642c8f51b3333981f91c0a8ab37dfc2807"
+ integrity sha512-1MzNQdAvO+54H+EaK5YpyEy0T+Ejo/7YLHS93G3RnYWh5gaotGHwGeN/ZO687qEDU2y4CdStQYXVHIgrUl5UVQ==
diff --git a/examples/server.ts b/examples/server.ts
new file mode 100644
index 00000000..13d7f51a
--- /dev/null
+++ b/examples/server.ts
@@ -0,0 +1,41 @@
+import { makeApi } from "@zodios/core";
+import { zodiosApp } from "../packages/express/src/index";
+import { z } from "zod";
+
+const userApi = makeApi([
+ {
+ method: "get",
+ path: "/users/:id",
+ alias: "getUser",
+ description: "Get a user",
+ parameters: [
+ {
+ name: "id",
+ type: "Path",
+ schema: z.number(),
+ },
+ {
+ name: "filter",
+ type: "Query",
+ schema: z.string().array().default([]),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string().nullable(),
+ }),
+ },
+]);
+
+const app = zodiosApp(userApi);
+
+app.get("/users/:id", async (req, res) => {
+ const { id } = req.params;
+ // ^?
+ const { filter } = req.query;
+ // ^?
+ return res.json({
+ id: req.params.id,
+ name: "example",
+ });
+});
diff --git a/package.json b/package.json
index ef9682cc..f1389263 100644
--- a/package.json
+++ b/package.json
@@ -1,74 +1,22 @@
{
- "name": "@zodios/core",
- "description": "Typescript API client with autocompletion and zod validations",
- "version": "10.9.0",
- "main": "lib/index.js",
- "module": "lib/index.mjs",
- "typings": "lib/index.d.ts",
- "exports": {
- ".": {
- "import": "./lib/index.mjs",
- "require": "./lib/index.js",
- "types": "./lib/index.d.ts"
- },
- "./lib/*.types": {
- "import": "./lib/*.types.mjs",
- "require": "./lib/*.types.js",
- "types": "./lib/*.types.d.ts"
- },
- "./package.json": "./package.json"
- },
- "files": [
- "lib"
- ],
- "author": {
- "name": "ecyrbe",
- "email": "ecyrbe@gmail.com"
- },
- "homepage": "https://github.com/ecyrbe/zodios",
- "repository": {
- "type": "git",
- "url": "https://github.com/ecyrbe/zodios.git"
- },
- "license": "MIT",
- "keywords": [
- "axios",
- "openapi",
- "zod",
- "autocomplete",
- "validation"
- ],
+ "name": "zodios",
+ "version": "11.0.0-rc.0",
"scripts": {
- "prebuild": "rimraf lib",
- "example": "ts-node examples/jsonplaceholder.ts",
- "example:dev.to": "ts-node examples/dev.to/example.ts",
- "major-rc": "npm version premajor --preid=rc",
- "minor-rc": "npm version preminor --preid=rc",
- "patch-rc": "npm version prepatch --preid=rc",
- "rc": "npm version prerelease --preid=rc",
- "build": "tsup",
- "test": "jest --coverage"
- },
- "peerDependencies": {
- "axios": "^0.x || ^1.0.0",
- "zod": "^3.x"
+ "build": "turbo run build",
+ "test": "turbo run test",
+ "dev": "turbo run dev",
+ "lint": "turbo run lint",
+ "pub": "turbo run build test && changeset version && changeset publish"
},
+ "private": true,
"devDependencies": {
- "@jest/types": "29.5.0",
- "@types/express": "4.17.17",
- "@types/jest": "29.5.0",
- "@types/multer": "1.4.7",
- "@types/node": "18.15.11",
- "axios": "1.3.5",
- "express": "4.18.2",
- "form-data": "4.0.0",
- "jest": "29.5.0",
- "multer": "1.4.5-lts.1",
- "rimraf": "5.0.0",
- "ts-jest": "29.1.0",
- "ts-node": "10.9.1",
- "tsup": "6.3.0",
- "typescript": "5.0.4",
- "zod": "3.21.4"
+ "@changesets/cli": "2.26.1",
+ "turbo": "1.8.8",
+ "typescript": "5.0.4"
+ },
+ "pnpm": {
+ "overrides": {
+ "esbuild": "0.17.14"
+ }
}
-}
\ No newline at end of file
+}
diff --git a/packages/axios/.gitignore b/packages/axios/.gitignore
new file mode 100644
index 00000000..9aadc156
--- /dev/null
+++ b/packages/axios/.gitignore
@@ -0,0 +1,105 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# TypeScript v1 declaration files
+typings/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+.env.test
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+
+# Next.js build output
+.next
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+lib
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and *not* Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port
diff --git a/.npmignore b/packages/axios/.npmignore
similarity index 100%
rename from .npmignore
rename to packages/axios/.npmignore
diff --git a/packages/axios/CHANGELOG.md b/packages/axios/CHANGELOG.md
new file mode 100644
index 00000000..eb55e9c1
--- /dev/null
+++ b/packages/axios/CHANGELOG.md
@@ -0,0 +1,227 @@
+# @zodios/core
+
+## 11.0.0-beta.19
+
+### Major Changes
+
+- 583775e: feat(openapi): add openapi
+
+### Patch Changes
+
+- Updated dependencies [583775e]
+ - @zodios/core@11.0.0-beta.19
+
+## 11.0.0-beta.18
+
+### Major Changes
+
+- 58016f5: migrate to typescript v11
+
+### Patch Changes
+
+- Updated dependencies [58016f5]
+ - @zodios/core@11.0.0-beta.18
+
+## 11.0.0-beta.17
+
+### Major Changes
+
+- 48a20cc: fix(react): do not double fetch if react-query signal is not used
+- 8303e57: feat(plugin): add new zodios plugin system
+
+### Patch Changes
+
+- Updated dependencies [48a20cc]
+- Updated dependencies [8303e57]
+ - @zodios/core@11.0.0-beta.17
+
+## 11.0.0-beta.16
+
+### Major Changes
+
+- f1b38f4: feat: improve typings
+- cb56d43: feat: improve typings
+
+### Patch Changes
+
+- Updated dependencies [f1b38f4]
+- Updated dependencies [cb56d43]
+ - @zodios/core@11.0.0-beta.16
+
+## 11.0.0-beta.15
+
+### Major Changes
+
+- eaf8e45: feat(fetcher): change fetcher model to factory
+- faaec6f: chore(deps): update zod
+- f161353: chore(deps): update fp-ts
+- 5115eaa: chore(deps): update typescript
+- 4ac4921: feat(react): simplify exported instance
+
+### Patch Changes
+
+- Updated dependencies [eaf8e45]
+- Updated dependencies [faaec6f]
+- Updated dependencies [f161353]
+- Updated dependencies [5115eaa]
+- Updated dependencies [4ac4921]
+ - @zodios/core@11.0.0-beta.15
+
+## 11.0.0-beta.14
+
+### Major Changes
+
+- 422221b: refactor: factor http verbs
+- 13247c6: chore: fix type exports for nodenext
+
+### Patch Changes
+
+- Updated dependencies [422221b]
+- Updated dependencies [13247c6]
+ - @zodios/core@11.0.0-beta.14
+
+## 11.0.0-beta.13
+
+### Major Changes
+
+- 2745e1a: feat(react): migrate react to v11
+- 98433a9: fix(react): bump version
+
+### Patch Changes
+
+- Updated dependencies [2745e1a]
+- Updated dependencies [98433a9]
+ - @zodios/core@11.0.0-beta.13
+
+## 11.0.0-beta.12
+
+### Major Changes
+
+- 29dcf47: fix(testing): safely export hooks
+
+### Patch Changes
+
+- Updated dependencies [29dcf47]
+ - @zodios/core@11.0.0-beta.12
+
+## 11.0.0-beta.11
+
+### Major Changes
+
+- a753f07: fix(testing): import types from core instead of relaive directory
+- 33b5de0: refactor(testing): move base hooks to testing
+
+### Patch Changes
+
+- Updated dependencies [a753f07]
+- Updated dependencies [33b5de0]
+ - @zodios/core@11.0.0-beta.11
+
+## 11.0.0-beta.10
+
+### Major Changes
+
+- c360c52: feat(testing): add response testing handlers
+
+### Patch Changes
+
+- Updated dependencies [c360c52]
+ - @zodios/core@11.0.0-beta.10
+
+## 11.0.0-beta.9
+
+### Major Changes
+
+- c4c00a1: chore(deps): upgrade axios
+- c6a4d0e: feat(testing): add testing package
+
+### Patch Changes
+
+- Updated dependencies [c4c00a1]
+- Updated dependencies [c6a4d0e]
+ - @zodios/core@11.0.0-beta.9
+
+## 11.0.0-beta.8
+
+### Major Changes
+
+- e67fa49: feat(fetch): remove qs dependency
+- 731e399: tests(core): fix tests
+
+### Patch Changes
+
+- Updated dependencies [e67fa49]
+- Updated dependencies [731e399]
+ - @zodios/core@11.0.0-beta.8
+
+## 11.0.0-beta.7
+
+### Major Changes
+
+- 7dcbb0c: chore(fetch): fix deps
+
+### Patch Changes
+
+- Updated dependencies [7dcbb0c]
+ - @zodios/core@11.0.0-beta.7
+
+## 11.0.0-beta.6
+
+### Major Changes
+
+- da4ddab: add fetch package
+- 535c76b: add basic mocks helpers
+
+### Patch Changes
+
+- Updated dependencies [da4ddab]
+- Updated dependencies [535c76b]
+ - @zodios/core@11.0.0-beta.6
+
+## 11.0.0-beta.5
+
+### Major Changes
+
+- 1b67309: fix axios tests
+- c7c03bc: sync axios and core versions
+
+### Patch Changes
+
+- Updated dependencies [1b67309]
+- Updated dependencies [c7c03bc]
+ - @zodios/core@11.0.0-beta.5
+
+## 11.0.0-beta.4
+
+### Major Changes
+
+- 679a267: update axios
+
+### Patch Changes
+
+- Updated dependencies [14ce00b]
+- Updated dependencies [c9cae0a]
+- Updated dependencies [3ac25a1]
+- Updated dependencies [6c10dc2]
+- Updated dependencies [679a267]
+- Updated dependencies [90108a5]
+ - @zodios/core@11.0.0-beta.4
+
+## 11.0.0-beta.3
+
+### Patch Changes
+
+- add publish script
+- 5575e28: add tests for type providers
+
+## 11.0.0-beta.2
+
+### Patch Changes
+
+- remove publish action from ci
+
+## 11.0.0-beta.1
+
+### Patch Changes
+
+- migrate to monorepo
diff --git a/packages/axios/LICENSE b/packages/axios/LICENSE
new file mode 100644
index 00000000..e5dea986
--- /dev/null
+++ b/packages/axios/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 ecyrbe
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/packages/axios/README.md b/packages/axios/README.md
new file mode 100644
index 00000000..31105cd4
--- /dev/null
+++ b/packages/axios/README.md
@@ -0,0 +1,198 @@
+ Zodios
+
+
+
+
+
+
+ Zodios is a typescript api client and an optional api server with auto-completion features backed by axios and zod and express
+
+ Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+https://user-images.githubusercontent.com/633115/185851987-554f5686-cb78-4096-8ff5-c8d61b645608.mp4
+
+# What is it ?
+
+It's an axios compatible API client and an optional expressJS compatible API server with the following features:
+
+- really simple centralized API declaration
+- typescript autocompletion in your favorite IDE for URL and parameters
+- typescript response types
+- parameters and responses schema thanks to zod
+- response schema validation
+- powerfull plugins like `fetch` adapter or `auth` automatic injection
+- all axios features available
+- `@tanstack/query` wrappers for react and solid (vue, svelte, etc, soon)
+- all expressJS features available (middlewares, etc.)
+
+
+**Table of contents:**
+
+- [What is it ?](#what-is-it-)
+- [Install](#install)
+ - [Client and api definitions :](#client-and-api-definitions-)
+ - [Server :](#server-)
+- [How to use it on client side ?](#how-to-use-it-on-client-side-)
+ - [Declare your API with zodios](#declare-your-api-with-zodios)
+ - [API definition format](#api-definition-format)
+- [Full documentation](#full-documentation)
+- [Ecosystem](#ecosystem)
+- [Roadmap](#roadmap)
+- [Dependencies](#dependencies)
+
+# Install
+
+## Client and api definitions :
+
+```bash
+> npm install @zodios/core
+```
+
+or
+
+```bash
+> yarn add @zodios/core
+```
+
+## Server :
+
+```bash
+> npm install @zodios/core @zodios/express
+```
+
+or
+
+```bash
+> yarn add @zodios/core @zodios/express
+```
+
+# How to use it on client side ?
+
+For an almost complete example on how to use zodios and how to split your APIs declarations, take a look at [dev.to](examples/dev.to/) example.
+
+## Declare your API with zodios
+
+Here is an example of API declaration with Zodios.
+
+```typescript
+import { Zodios } from "@zodios/core";
+import { z } from "zod";
+
+const apiClient = new Zodios(
+ "https://jsonplaceholder.typicode.com",
+ // API definition
+ [
+ {
+ method: "get",
+ path: "/users/:id", // auto detect :id and ask for it in apiClient get params
+ alias: "getUser", // optionnal alias to call this endpoint with it
+ description: "Get a user",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+);
+```
+
+Calling this API is now easy and has builtin autocomplete features :
+
+```typescript
+// typed auto-complete path auto-complete params
+// â–¼ â–¼ â–¼
+const user = await apiClient.get("/users/:id", { params: { id: 7 } });
+console.log(user);
+```
+
+It should output
+
+```js
+{ id: 7, name: 'Kurtis Weissnat' }
+```
+You can also use aliases :
+
+```typescript
+// typed alias auto-complete params
+// â–¼ â–¼ â–¼
+const user = await apiClient.getUser({ params: { id: 7 } });
+console.log(user);
+```
+## API definition format
+
+```typescript
+type ZodiosEndpointDescriptions = Array<{
+ method: 'get'|'post'|'put'|'patch'|'delete';
+ path: string; // example: /posts/:postId/comments/:commentId
+ alias?: string; // example: getPostComments
+ immutable?: boolean; // flag a post request as immutable to allow it to be cached with react-query
+ description?: string;
+ requestFormat?: 'json'|'form-data'|'form-url'|'binary'|'text'; // default to json if not set
+ parameters?: Array<{
+ name: string;
+ description?: string;
+ type: 'Path'|'Query'|'Body'|'Header';
+ schema: ZodSchema; // you can use zod `transform` to transform the value of the parameter before sending it to the server
+ }>;
+ response: ZodSchema; // you can use zod `transform` to transform the value of the response before returning it
+ status?: number; // default to 200, you can use this to override the sucess status code of the response (only usefull for openapi and express)
+ responseDescription?: string; // optional response description of the endpoint
+ errors?: Array<{
+ status: number | 'default';
+ description?: string;
+ schema: ZodSchema; // transformations are not supported on error schemas
+ }>;
+}>;
+```
+# Full documentation
+
+Check out the [full documentation](https://www.zodios.org) or following shortcuts.
+
+- [API definition](https://www.zodios.org/docs/category/zodios-api-definition)
+- [Http client](https://www.zodios.org/docs/category/zodios-client)
+- [React hooks](https://www.zodios.org/docs/client/react)
+- [Solid hooks](https://www.zodios.org/docs/client/solid)
+- [API server](http://www.zodios.org/docs/category/zodios-server)
+- [Nextjs integration](http://www.zodios.org/docs/server/next)
+
+# Ecosystem
+
+- [openapi-zod-client](https://github.com/astahmer/openapi-zod-client): generate a zodios client from an openapi specification
+- [@zodios/express](https://github.com/ecyrbe/zodios-express): full end to end type safety like tRPC, but for REST APIs
+- [@zodios/plugins](https://github.com/ecyrbe/zodios-plugins) : some plugins for zodios
+- [@zodios/react](https://github.com/ecyrbe/zodios-react) : a react-query wrapper for zodios
+- [@zodios/solid](https://github.com/ecyrbe/zodios-solid) : a solid-query wrapper for zodios
+
+# Roadmap
+
+The following will need investigation to check if it's doable :
+- implement `@zodios/nestjs` to define your API endpoints with nestjs and share it with your frontend (like tRPC)
+- generate openAPI json from your API endpoints
+
+You have other ideas ? [Let me know !](https://github.com/ecyrbe/zodios/discussions)
+# Dependencies
+
+Zodios even when working in pure Javascript is better suited to be working with Typescript Language Server to handle autocompletion.
+So you should at least use the one provided by your IDE (vscode integrates a typescript language server)
+However, we will only support fixing bugs related to typings for versions of Typescript Language v4.5
+Earlier versions should work, but do not have TS tail recusion optimisation that impact the size of the API you can declare.
+
+Also note that Zodios do not embed any dependency. It's your Job to install the peer dependencies you need.
+
+Internally Zodios uses these libraries on all platforms :
+- zod
+- axios
diff --git a/packages/axios/SECURITY.md b/packages/axios/SECURITY.md
new file mode 100644
index 00000000..16be6051
--- /dev/null
+++ b/packages/axios/SECURITY.md
@@ -0,0 +1,20 @@
+# Security Policy
+
+## Supported Versions
+
+Use this section to tell people about which versions of your project are
+currently being supported with security updates.
+
+| Version | Supported |
+| --------- | ------------------ |
+| 10.x.y | :white_check_mark: |
+| < 10.0.0 | :x: |
+
+## Reporting a Vulnerability
+
+If you identify a vulnerability on zodios, please create an issue with a reproductible setup.
+Do not open an issue if you can't show a reproductible setup of if the vulnerability is on third party dependency.
+
+Indeed, a vulnerability on a peer dependency should be reported on the appropriate project:
+- zod
+- axios
diff --git a/examples/define-types.ts b/packages/axios/examples/define-types.ts
similarity index 100%
rename from examples/define-types.ts
rename to packages/axios/examples/define-types.ts
diff --git a/examples/dev.to/api-key-plugin.ts b/packages/axios/examples/dev.to/api-key-plugin.ts
similarity index 84%
rename from examples/dev.to/api-key-plugin.ts
rename to packages/axios/examples/dev.to/api-key-plugin.ts
index 27bd9e43..ba768056 100644
--- a/examples/dev.to/api-key-plugin.ts
+++ b/packages/axios/examples/dev.to/api-key-plugin.ts
@@ -1,5 +1,3 @@
-import { AxiosRequestConfig } from "axios";
-import { config } from "process";
import { ZodiosPlugin } from "../../src/index";
export interface ApiKeyPluginConfig {
diff --git a/examples/dev.to/articles.ts b/packages/axios/examples/dev.to/articles.ts
similarity index 100%
rename from examples/dev.to/articles.ts
rename to packages/axios/examples/dev.to/articles.ts
diff --git a/examples/dev.to/comments.ts b/packages/axios/examples/dev.to/comments.ts
similarity index 100%
rename from examples/dev.to/comments.ts
rename to packages/axios/examples/dev.to/comments.ts
diff --git a/examples/dev.to/example.ts b/packages/axios/examples/dev.to/example.ts
similarity index 100%
rename from examples/dev.to/example.ts
rename to packages/axios/examples/dev.to/example.ts
diff --git a/examples/dev.to/followers.ts b/packages/axios/examples/dev.to/followers.ts
similarity index 100%
rename from examples/dev.to/followers.ts
rename to packages/axios/examples/dev.to/followers.ts
diff --git a/examples/dev.to/follows.ts b/packages/axios/examples/dev.to/follows.ts
similarity index 100%
rename from examples/dev.to/follows.ts
rename to packages/axios/examples/dev.to/follows.ts
diff --git a/examples/dev.to/params.ts b/packages/axios/examples/dev.to/params.ts
similarity index 100%
rename from examples/dev.to/params.ts
rename to packages/axios/examples/dev.to/params.ts
diff --git a/examples/dev.to/users.ts b/packages/axios/examples/dev.to/users.ts
similarity index 100%
rename from examples/dev.to/users.ts
rename to packages/axios/examples/dev.to/users.ts
diff --git a/packages/axios/examples/io-ts-types.ts b/packages/axios/examples/io-ts-types.ts
new file mode 100644
index 00000000..a2d64de4
--- /dev/null
+++ b/packages/axios/examples/io-ts-types.ts
@@ -0,0 +1,78 @@
+import {
+ Zodios,
+ makeApi,
+ ApiOf,
+ TypeProviderOf,
+ FetcherProviderOf,
+ ioTsTypeProvider,
+} from "../src/index";
+import * as t from "io-ts";
+
+// you can define schema before declaring the API to get back the type
+
+// you can then get back the types
+type User = t.TypeOf;
+type Users = t.TypeOf;
+
+// you can also predefine your API
+const jsonplaceholderUrl = "https://jsonplaceholder.typicode.com";
+
+const userSchema = t.type({
+ id: t.number,
+ name: t.string,
+});
+
+const usersSchema = t.array(userSchema);
+
+const jsonplaceholderApi = makeApi([
+ {
+ method: "get",
+ path: "/users",
+ alias: "getUsers",
+ description: "Get all users",
+ parameters: [
+ {
+ name: "q",
+ description: "full text search",
+ type: "Query",
+ schema: t.string,
+ },
+ {
+ name: "page",
+ description: "page number",
+ type: "Query",
+ schema: t.union([t.number, t.undefined]),
+ },
+ ],
+ response: usersSchema,
+ },
+ {
+ method: "get",
+ path: "/users/:id",
+ description: "Get a user",
+ response: userSchema,
+ },
+]);
+
+async function bootstrap() {
+ const apiClient = new Zodios(jsonplaceholderUrl, jsonplaceholderApi, {
+ typeProvider: ioTsTypeProvider,
+ });
+
+ type Api = ApiOf;
+ // ^?
+ type Provider = TypeProviderOf;
+ // ^?
+ type FetcherProvider = FetcherProviderOf;
+ // ^?
+ const users = await apiClient.get("/users", { queries: { q: "Nicholas" } });
+ // ^?
+ const users2 = await apiClient.getUsers({ queries: { q: "Nicholas" } });
+ // ^?
+ console.log(users);
+ const user = await apiClient.get("/users/:id", { params: { id: 7 } });
+ // ^?
+ console.log(user);
+}
+
+bootstrap();
diff --git a/examples/jsonplaceholder.ts b/packages/axios/examples/jsonplaceholder.ts
similarity index 98%
rename from examples/jsonplaceholder.ts
rename to packages/axios/examples/jsonplaceholder.ts
index d4d08b20..5bd28b12 100644
--- a/examples/jsonplaceholder.ts
+++ b/packages/axios/examples/jsonplaceholder.ts
@@ -42,7 +42,7 @@ async function bootstrap() {
path: "/users/:id",
alias: "deleteUser",
description: "Delete a user",
- response: z.object({ }),
+ response: z.void(),
},
{
method: "post",
diff --git a/examples/types-from-definition.ts b/packages/axios/examples/types-from-definition.ts
similarity index 100%
rename from examples/types-from-definition.ts
rename to packages/axios/examples/types-from-definition.ts
diff --git a/packages/axios/examples/typescript-types.ts b/packages/axios/examples/typescript-types.ts
new file mode 100644
index 00000000..fdf8e533
--- /dev/null
+++ b/packages/axios/examples/typescript-types.ts
@@ -0,0 +1,77 @@
+import {
+ Zodios,
+ makeApi,
+ tsFnSchema,
+ ApiOf,
+ TypeProviderOf,
+ tsSchema,
+ tsTypeProvider,
+ FetcherProviderOf,
+} from "../src";
+
+// you can also predefine your API
+const jsonplaceholderUrl = "https://jsonplaceholder.typicode.com";
+
+type User = {
+ id: number;
+ name: string;
+};
+
+const userSchema = tsSchema();
+
+const usersSchema = tsSchema();
+
+const jsonplaceholderApi = makeApi([
+ {
+ method: "get",
+ path: "/users",
+ description: "Get all users",
+ parameters: [
+ {
+ name: "q",
+ description: "full text search",
+ type: "Query",
+ schema: tsFnSchema((data) => {
+ if (typeof data !== "string") {
+ throw new Error("not a string");
+ }
+ return data;
+ }),
+ },
+ {
+ name: "page",
+ description: "page number",
+ type: "Query",
+ schema: tsSchema(),
+ },
+ ],
+ response: usersSchema,
+ },
+ {
+ method: "get",
+ path: "/users/:id",
+ description: "Get a user",
+ response: userSchema,
+ },
+]);
+
+async function bootstrap() {
+ const apiClient = new Zodios(jsonplaceholderUrl, jsonplaceholderApi, {
+ typeProvider: tsTypeProvider,
+ });
+
+ type Api = ApiOf;
+ // ^?
+ type Provider = TypeProviderOf;
+ // ^?
+ type FetcherProvider = FetcherProviderOf;
+ // ^?
+ const users = await apiClient.get("/users", { queries: { q: "Nicholas" } });
+ // ^?
+ console.log(users);
+ const user = await apiClient.get("/users/:id", { params: { id: 7 } });
+ // ^?
+ console.log(user);
+}
+
+bootstrap();
diff --git a/jest.config.ts b/packages/axios/jest.config.ts
similarity index 100%
rename from jest.config.ts
rename to packages/axios/jest.config.ts
diff --git a/packages/axios/package.json b/packages/axios/package.json
new file mode 100644
index 00000000..d779b33d
--- /dev/null
+++ b/packages/axios/package.json
@@ -0,0 +1,82 @@
+{
+ "name": "@zodios/axios",
+ "description": "Typescript API client with axios",
+ "version": "11.0.0-beta.19",
+ "main": "lib/index.js",
+ "module": "lib/index.mjs",
+ "typings": "lib/index.d.ts",
+ "exports": {
+ ".": {
+ "import": "./lib/index.mjs",
+ "require": "./lib/index.js",
+ "types": "./lib/index.d.ts"
+ },
+ "./package.json": "./package.json"
+ },
+ "files": [
+ "lib"
+ ],
+ "author": {
+ "name": "ecyrbe",
+ "email": "ecyrbe@gmail.com"
+ },
+ "homepage": "https://github.com/ecyrbe/zodios",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/ecyrbe/zodios.git"
+ },
+ "license": "MIT",
+ "keywords": [
+ "axios",
+ "openapi",
+ "zod",
+ "autocomplete",
+ "validation"
+ ],
+ "scripts": {
+ "prebuild": "rimraf lib",
+ "example": "ts-node examples/jsonplaceholder.ts",
+ "example:dev.to": "ts-node examples/dev.to/example.ts",
+ "build": "tsup",
+ "test": "jest --coverage"
+ },
+ "peerDependencies": {
+ "@zodios/core": "11.0.0-beta.19",
+ "axios": "^0.x || ^1.0.0",
+ "fp-ts": "2.x",
+ "io-ts": "2.x",
+ "zod": "^3.x"
+ },
+ "peerDependenciesMeta": {
+ "zod": {
+ "optional": true
+ },
+ "fp-ts": {
+ "optional": true
+ },
+ "io-ts": {
+ "optional": true
+ }
+ },
+ "devDependencies": {
+ "@jest/globals": "29.5.0",
+ "@jest/types": "29.5.0",
+ "@types/express": "4.17.17",
+ "@types/jest": "29.5.0",
+ "@types/multer": "1.4.7",
+ "@types/node": "18.15.11",
+ "@zodios/core": "workspace:*",
+ "axios": "1.3.5",
+ "express": "4.18.2",
+ "fp-ts": "2.13.1",
+ "io-ts": "2.2.20",
+ "jest": "29.5.0",
+ "multer": "1.4.5-lts.1",
+ "rimraf": "4.4.1",
+ "ts-jest": "29.1.0",
+ "ts-node": "10.9.1",
+ "tsup": "6.7.0",
+ "typescript": "5.0.4",
+ "zod": "3.21.4"
+ }
+}
diff --git a/packages/axios/src/axios-provider.ts b/packages/axios/src/axios-provider.ts
new file mode 100644
index 00000000..1987337a
--- /dev/null
+++ b/packages/axios/src/axios-provider.ts
@@ -0,0 +1,67 @@
+import axios, { AxiosError, AxiosInstance, AxiosResponse } from "axios";
+import {
+ AnyZodiosRequestOptions,
+ AnyZodiosFetcherProvider,
+ ZodiosFetcherFactory,
+ ZodiosFetcher,
+} from "@zodios/core";
+import { Merge } from "@zodios/core/lib/utils.types";
+import { omit, replacePathParams } from "./utils";
+
+type AxiosErrorStatus = Merge<
+ Omit,
+ {
+ response: Merge<
+ AxiosError["response"],
+ {
+ status: Status extends "default" ? 0 & { error: "default" } : Status;
+ }
+ >;
+ }
+>;
+
+type AxiosRequestConfig = Parameters[0];
+type AxiosCreateConfig = Parameters[0];
+
+type AxiosProviderOptions = {
+ axiosInstance?: AxiosInstance;
+ axiosConfig?: AxiosCreateConfig;
+};
+
+export interface AxiosProvider extends AnyZodiosFetcherProvider {
+ options: AxiosProviderOptions;
+ config: Omit;
+ response: AxiosResponse;
+
+ // provider for TypeOfError
+ error: AxiosErrorStatus;
+}
+
+class Fetcher implements ZodiosFetcher {
+ instance: AxiosInstance;
+ constructor(
+ baseURL: string | undefined,
+ config: AxiosCreateConfig | undefined,
+ instance: AxiosInstance | undefined
+ ) {
+ this.instance = instance || axios.create(config);
+ if (baseURL) this.instance.defaults.baseURL = baseURL;
+ }
+
+ fetch(config: AnyZodiosRequestOptions) {
+ return this.instance.request({
+ ...omit(config, ["params", "queries", "body"]),
+ url: replacePathParams(config),
+ params: config.queries,
+ data: config.body,
+ });
+ }
+}
+
+export const axiosFactory: ZodiosFetcherFactory = (options) => {
+ return new Fetcher(
+ options?.baseURL,
+ options?.axiosConfig,
+ options?.axiosInstance
+ );
+};
diff --git a/packages/axios/src/index.ts b/packages/axios/src/index.ts
new file mode 100644
index 00000000..c1057dfb
--- /dev/null
+++ b/packages/axios/src/index.ts
@@ -0,0 +1,3 @@
+export { Zodios } from "./zodios";
+export type { AxiosProvider } from "./axios-provider";
+export * from "@zodios/core";
diff --git a/packages/axios/src/utils.ts b/packages/axios/src/utils.ts
new file mode 100644
index 00000000..b84e6338
--- /dev/null
+++ b/packages/axios/src/utils.ts
@@ -0,0 +1,33 @@
+import type { ReadonlyDeep } from "@zodios/core/lib/utils.types";
+
+/**
+ * omit properties from an object
+ * @param obj - the object to omit properties from
+ * @param keys - the keys to omit
+ * @returns the object with the omitted properties
+ */
+export function omit(
+ obj: T | undefined,
+ keys: K[]
+): Omit {
+ const ret = { ...obj } as T;
+ for (const key of keys) {
+ delete ret[key];
+ }
+ return ret;
+}
+
+const paramsRegExp = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
+
+export function replacePathParams(
+ config: ReadonlyDeep<{ url: string; params?: Record }>
+) {
+ let result: string = config.url;
+ const params = config.params;
+ if (params) {
+ result = result.replace(paramsRegExp, (match, key) =>
+ key in params ? `${params[key]}` : match
+ );
+ }
+ return result;
+}
diff --git a/packages/axios/src/zodios.test.ts b/packages/axios/src/zodios.test.ts
new file mode 100644
index 00000000..2c49d2d6
--- /dev/null
+++ b/packages/axios/src/zodios.test.ts
@@ -0,0 +1,958 @@
+///
+import { AxiosError } from "axios";
+import express from "express";
+import { AddressInfo } from "net";
+import { z, ZodError } from "zod";
+//if (globalThis.FormData === undefined) {
+globalThis.FormData = require("form-data");
+//}
+import { Zodios } from "./zodios";
+import {
+ ZodiosError,
+ AnyZodiosFetcherProvider,
+ ZodiosPlugin,
+ apiBuilder,
+} from "@zodios/core";
+import multer from "multer";
+import { Assert } from "@zodios/core/lib/utils.types";
+import { AxiosProvider } from "./axios-provider";
+
+const multipart = multer({ storage: multer.memoryStorage() });
+
+describe("Zodios", () => {
+ let app: express.Express;
+ let server: ReturnType;
+ let port: number;
+
+ beforeAll(async () => {
+ app = express();
+ app.use(express.json());
+ app.get("/token", (req, res) => {
+ res.status(200).json({ token: req.headers.authorization });
+ });
+ app.post("/token", (req, res) => {
+ res.status(200).json({ token: req.headers.authorization });
+ });
+ app.get("/error401", (req, res) => {
+ res.status(401).json({});
+ });
+ app.get("/error502", (req, res) => {
+ res.status(502).json({ error: { message: "bad gateway" } });
+ });
+ app.get("/queries", (req, res) => {
+ res.status(200).json({
+ queries: req.query.id,
+ });
+ });
+ app.get("/:id", (req, res) => {
+ res.status(200).json({ id: Number(req.params.id), name: "test" });
+ });
+ app.get("/path/:uuid", (req, res) => {
+ res.status(200).json({ uuid: req.params.uuid });
+ });
+ app.get("/:id/address/:address", (req, res) => {
+ res
+ .status(200)
+ .json({ id: Number(req.params.id), address: req.params.address });
+ });
+ app.post("/", (req, res) => {
+ res.status(200).json({ id: 3, name: req.body.name });
+ });
+ app.put("/", (req, res) => {
+ res.status(200).json({ id: req.body.id, name: req.body.name });
+ });
+ app.patch("/", (req, res) => {
+ res.status(200).json({ id: req.body.id, name: req.body.name });
+ });
+ app.delete("/:id", (req, res) => {
+ res.status(200).json({ id: Number(req.params.id) });
+ });
+ app.post("/form-data", multipart.none(), (req, res) => {
+ res.status(200).json(req.body);
+ });
+ app.post(
+ "/form-url",
+ express.urlencoded({ extended: false }),
+ (req, res) => {
+ res.status(200).json(req.body);
+ }
+ );
+ app.post("/text", express.text(), (req, res) => {
+ res.status(200).send(req.body);
+ });
+ server = app.listen(0);
+ port = (server.address() as AddressInfo).port;
+ });
+
+ afterAll(() => {
+ server.close();
+ });
+
+ it("should be defined", () => {
+ expect(Zodios).toBeDefined();
+ });
+
+ it("should throw if baseUrl is not provided", () => {
+ // @ts-ignore
+ expect(() => new Zodios(undefined, [])).toThrowError(
+ "Zodios: missing base url"
+ );
+ });
+
+ it("should throw if api is not provided", () => {
+ // @ts-ignore
+ expect(() => new Zodios()).toThrowError("Zodios: missing api description");
+ });
+
+ it("should throw if api is not an array", () => {
+ // @ts-ignore
+ expect(() => new Zodios({})).toThrowError("Zodios: api must be an array");
+ });
+
+ it("should create a new instance of Zodios", () => {
+ const zodios = new Zodios(`http://localhost:${port}`, []);
+ expect(zodios).toBeDefined();
+ });
+ it("should create a new instance when providing an api", () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ expect(zodios).toBeDefined();
+ });
+
+ it("should should throw with duplicate api endpoints", () => {
+ expect(
+ () =>
+ new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ])
+ ).toThrowError("Zodios: Duplicate path 'get /:id'");
+ });
+
+ it("should create a new instance whithout base URL", () => {
+ const zodios = new Zodios([
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ expect(zodios).toBeDefined();
+ });
+
+ it("should make an http request", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ {
+ method: "get",
+ path: "/users",
+ response: z.array(
+ z.object({
+ id: z.number(),
+ name: z.string(),
+ })
+ ),
+ },
+ ]);
+ const response = await zodios.request({
+ method: "get",
+ url: "/:id",
+ params: { id: 7 },
+ });
+ expect(response).toEqual({ id: 7, name: "test" });
+ });
+
+ it("should make an http get with standard query arrays", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/queries",
+ parameters: [
+ {
+ name: "id",
+ type: "Query",
+ schema: z.array(z.number()),
+ },
+ ],
+ response: z.object({
+ queries: z.array(z.string()),
+ }),
+ },
+ ]);
+ const response = await zodios.get("/queries", { queries: { id: [1, 2] } });
+ expect(response).toEqual({ queries: ["1", "2"] });
+ });
+
+ it("should make an http get with one path params", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.get("/:id", { params: { id: 7 } });
+ expect(response).toEqual({ id: 7, name: "test" });
+ });
+
+ it("should make an http alias request with one path params", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/:id",
+ alias: "getById",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.getById({ params: { id: 7 } });
+ expect(response).toEqual({ id: 7, name: "test" });
+ });
+
+ it("should work with api builder", async () => {
+ const api = apiBuilder({
+ method: "get",
+ path: "/:id",
+ alias: "getById",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ }).build();
+ const zodios = new Zodios(`http://localhost:${port}`, api);
+ const response = await zodios.getById({ params: { id: 7 } });
+ expect(response).toEqual({ id: 7, name: "test" });
+ });
+
+ it("should make a get request with forgotten params and get back a zod error", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ try {
+ // @ts-ignore
+ await zodios.get("/:id");
+ } catch (e) {
+ expect(e).toBeInstanceOf(ZodiosError);
+ }
+ });
+
+ it("should make an http get with multiples path params", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/:id/address/:address",
+ response: z.object({
+ id: z.number(),
+ address: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.get("/:id/address/:address", {
+ params: { id: 7, address: "address" },
+ });
+ expect(response).toEqual({ id: 7, address: "address" });
+ });
+
+ it("should make an http post with body param", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "post",
+ path: "/",
+ parameters: [
+ {
+ name: "name",
+ type: "Body",
+ schema: z.object({
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.post("/", { body: { name: "post" } });
+ expect(response).toEqual({ id: 3, name: "post" });
+ });
+
+ it("should make an http post with transformed body param", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "post",
+ path: "/",
+ parameters: [
+ {
+ name: "name",
+ type: "Body",
+ schema: z
+ .object({
+ firstname: z.string(),
+ lastname: z.string(),
+ })
+ .transform((data) => ({
+ name: `${data.firstname} ${data.lastname}`,
+ })),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const config = {
+ method: "post",
+ url: "/",
+ body: { firstname: "post", lastname: "test" },
+ } as const;
+ const response = await zodios.request(config);
+ expect(config).toEqual({
+ method: "post",
+ url: "/",
+ body: { firstname: "post", lastname: "test" },
+ });
+ expect(response).toEqual({ id: 3, name: "post test" });
+ });
+
+ it("should throw a zodios error if params are not correct", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "post",
+ path: "/",
+ parameters: [
+ {
+ name: "name",
+ type: "Body",
+ schema: z
+ .object({
+ email: z.string().email(),
+ })
+ .transform((data) => ({
+ name: `${data.email.split("@")[0]}`,
+ })),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ let response;
+ let error: ZodiosError | undefined;
+ try {
+ response = await zodios.post("/", {
+ body: {
+ email: "post",
+ },
+ });
+ } catch (err) {
+ error = err as ZodiosError;
+ }
+ expect(response).toBeUndefined();
+ expect(error).toBeInstanceOf(ZodiosError);
+ expect(error!.cause).toBeInstanceOf(ZodError);
+ expect(error!.message).toBe("Zodios: Invalid Body parameter 'name'");
+ });
+
+ it("should make an http mutation alias request with body param", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "post",
+ path: "/",
+ alias: "create",
+ parameters: [
+ {
+ name: "name",
+ type: "Body",
+ schema: z.object({
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.create({ body: { name: "post" } });
+ expect(response).toEqual({ id: 3, name: "post" });
+ });
+
+ it("should make an http put", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "put",
+ path: "/",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.put("/", { body: { id: 5, name: "put" } });
+ expect(response).toEqual({ id: 5, name: "put" });
+ });
+
+ it("should make an http put alias", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "put",
+ path: "/",
+ alias: "update",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.update({ body: { id: 5, name: "put" } });
+ expect(response).toEqual({ id: 5, name: "put" });
+ });
+
+ it("should make an http patch", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "patch",
+ path: "/",
+ parameters: [
+ {
+ name: "id",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.patch("/", {
+ body: { id: 4, name: "patch" },
+ });
+ expect(response).toEqual({ id: 4, name: "patch" });
+ });
+
+ it("should make an http patch alias", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "patch",
+ path: "/",
+ alias: "update",
+ parameters: [
+ {
+ name: "id",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.update({ body: { id: 4, name: "patch" } });
+ expect(response).toEqual({ id: 4, name: "patch" });
+ });
+
+ it("should make an http delete", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "delete",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ }),
+ },
+ ]);
+ const response = await zodios.delete("/:id", {
+ params: { id: 6 },
+ });
+ expect(response).toEqual({ id: 6 });
+ });
+
+ it("should make an http delete alias", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "delete",
+ path: "/:id",
+ alias: "remove",
+ response: z.object({
+ id: z.number(),
+ }),
+ },
+ ]);
+ const response = await zodios.remove({
+ params: { id: 6 },
+ });
+ expect(response).toEqual({ id: 6 });
+ });
+
+ it("should validate uuid in path params", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/path/:uuid",
+ parameters: [
+ {
+ name: "uuid",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ ],
+ response: z.object({
+ uuid: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.get("/path/:uuid", {
+ params: { uuid: "e9e09a1d-3967-4518-bc89-75a901aee128" },
+ });
+ expect(response).toEqual({
+ uuid: "e9e09a1d-3967-4518-bc89-75a901aee128",
+ });
+ });
+
+ it("should not validate bad path params", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/path/:uuid",
+ parameters: [
+ {
+ name: "uuid",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ ],
+ response: z.object({
+ uuid: z.string(),
+ }),
+ },
+ ]);
+ let error;
+ try {
+ await zodios.get("/path/:uuid", {
+ params: { uuid: "e9e09a1-3967-4518-bc89-75a901aee128" },
+ });
+ } catch (e) {
+ error = e;
+ }
+ expect(error).toBeInstanceOf(ZodiosError);
+ expect((error as ZodiosError).cause).toBeInstanceOf(ZodError);
+ expect((error as ZodiosError).message).toBe(
+ "Zodios: Invalid Path parameter 'uuid'"
+ );
+ });
+
+ it("should not validate bad formatted responses", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ more: z.string(),
+ }),
+ },
+ ]);
+ try {
+ await zodios.get("/:id", { params: { id: 1 } });
+ } catch (e) {
+ expect(e).toBeInstanceOf(ZodiosError);
+ expect((e as ZodiosError).cause).toBeInstanceOf(ZodError);
+ expect((e as ZodiosError).message)
+ .toBe(`Zodios: Invalid response from endpoint 'get /:id'
+status: 200 OK
+cause:
+[
+ {
+ "code": "invalid_type",
+ "expected": "string",
+ "received": "undefined",
+ "path": [
+ "more"
+ ],
+ "message": "Required"
+ }
+]
+received:
+{
+ "id": 1,
+ "name": "test"
+}`);
+ expect((e as ZodiosError).data).toEqual({
+ id: 1,
+ name: "test",
+ });
+ expect((e as ZodiosError).config).toEqual({
+ method: "get",
+ url: "/:id",
+ params: { id: 1 },
+ });
+ }
+ });
+
+ it("should match Expected error", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ alias: "getError502",
+ path: "/error502",
+ response: z.void(),
+ errors: [
+ {
+ status: 502,
+ schema: z.object({
+ error: z.object({
+ message: z.string(),
+ }),
+ }),
+ },
+ {
+ status: 401,
+ schema: z.object({
+ error: z.object({
+ message: z.string(),
+ _401: z.literal(true),
+ }),
+ }),
+ },
+ {
+ status: "default",
+ schema: z.object({
+ error: z.object({
+ message: z.string(),
+ _default: z.literal(true),
+ }),
+ }),
+ },
+ ],
+ },
+ ]);
+ let error;
+ try {
+ await zodios.get("/error502");
+ } catch (e) {
+ error = e;
+ }
+ expect(error).toBeInstanceOf(Error);
+ expect((error as AxiosError).response?.status).toBe(502);
+ if (zodios.isErrorFromPath("get", "/error502", error)) {
+ expect(error.response.status).toBe(502);
+ if (error.response.status === 502) {
+ const data = error.response.data;
+ const test: Assert = true;
+ }
+ expect(error.response?.data).toEqual({
+ error: { message: "bad gateway" },
+ });
+ }
+ if (zodios.isErrorFromAlias("getError502", error)) {
+ expect(error.response.status).toBe(502);
+ if (error.response.status === 502) {
+ const data = error.response.data;
+ // ^?
+ const test: Assert = true;
+ } else if (error.response.status === 401) {
+ const data = error.response.data;
+ // ^?
+ const test: Assert<
+ typeof data,
+ { error: { message: string; _401: true } }
+ > = true;
+ } else {
+ const testStatus = error.response.status;
+ // ^?
+ const data = error.response.data;
+ // ^?
+ const test: Assert<
+ typeof data,
+ { error: { message: string; _default: true } }
+ > = true;
+ }
+ expect(error.response?.data).toEqual({
+ error: { message: "bad gateway" },
+ });
+ }
+ });
+
+ it("should match Unexpected error", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ alias: "getError502",
+ path: "/error502",
+ response: z.void(),
+ },
+ ]);
+ let error;
+ try {
+ await zodios.get("/error502");
+ } catch (e) {
+ error = e;
+ }
+
+ expect(error).toBeInstanceOf(Error);
+ expect((error as AxiosError).response?.status).toBe(502);
+ expect(zodios.isErrorFromPath("get", "/error502", error)).toBe(false);
+ expect(zodios.isErrorFromAlias("getError502", error)).toBe(false);
+ });
+
+ it("should return response when disabling validation", async () => {
+ const zodios = new Zodios(
+ `http://localhost:${port}`,
+ [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ more: z.string(),
+ }),
+ },
+ ],
+ { validate: false }
+ );
+ const response = await zodios.get("/:id", { params: { id: 1 } });
+ expect(response).toEqual({
+ id: 1,
+ name: "test",
+ });
+ });
+
+ it("should trigger an axios error with error response", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "get",
+ path: "/error502",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ try {
+ await zodios.get("/error502");
+ } catch (e) {
+ expect((e as AxiosError).response?.data).toEqual({
+ error: {
+ message: "bad gateway",
+ },
+ });
+ }
+ });
+
+ it("should send a form data request", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "post",
+ path: "/form-data",
+ requestFormat: "form-data",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.string(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.post("/form-data", {
+ body: { id: 4, name: "post" },
+ });
+ expect(response).toEqual({ id: "4", name: "post" });
+ });
+
+ it("should not send an array as form data request", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "post",
+ path: "/form-data",
+ requestFormat: "form-data",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.array(z.string()),
+ },
+ ],
+ response: z.string(),
+ },
+ ]);
+ let error: Error | undefined;
+ let response: string | undefined;
+ try {
+ response = await zodios.post("/form-data", { body: ["test", "test2"] });
+ } catch (err) {
+ error = err as Error;
+ }
+ expect(response).toBeUndefined();
+ expect(error).toBeInstanceOf(ZodiosError);
+ expect((error as ZodiosError).message).toBe(
+ "Zodios: multipart/form-data body must be an object"
+ );
+ });
+
+ it("should send a form url request", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "post",
+ path: "/form-url",
+ requestFormat: "form-url",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.string(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ const response = await zodios.post("/form-url", {
+ body: { id: 4, name: "post" },
+ });
+ expect(response).toEqual({ id: "4", name: "post" });
+ });
+
+ it("should not send an array as form url request", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "post",
+ path: "/form-url",
+ requestFormat: "form-url",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.array(z.string()),
+ },
+ ],
+ response: z.string(),
+ },
+ ]);
+ let error: Error | undefined;
+ let response: string | undefined;
+ try {
+ response = await zodios.post("/form-url", { body: ["test", "test2"] });
+ } catch (err) {
+ error = err as Error;
+ }
+ expect(response).toBeUndefined();
+ expect(error).toBeInstanceOf(ZodiosError);
+ expect((error as ZodiosError).message).toBe(
+ "Zodios: application/x-www-form-urlencoded body must be an object"
+ );
+ });
+
+ it("should send a text request", async () => {
+ const zodios = new Zodios(`http://localhost:${port}`, [
+ {
+ method: "post",
+ path: "/text",
+ requestFormat: "text",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.string(),
+ },
+ ],
+ response: z.string(),
+ },
+ ]);
+ const response = await zodios.post("/text", { body: "test" });
+ expect(response).toEqual("test");
+ });
+});
diff --git a/packages/axios/src/zodios.ts b/packages/axios/src/zodios.ts
new file mode 100644
index 00000000..f01087ca
--- /dev/null
+++ b/packages/axios/src/zodios.ts
@@ -0,0 +1,61 @@
+import type {
+ ZodiosEndpointDefinition,
+ ZodiosOptions,
+ AnyZodiosTypeProvider,
+ TypeOfFetcherOptions,
+ ZodiosInstance,
+ ZodTypeProvider,
+} from "@zodios/core";
+import { ZodiosCore } from "@zodios/core";
+import { axiosFactory, AxiosProvider } from "./axios-provider";
+
+function isZodiosOptions(
+ lastArg: unknown
+): lastArg is ZodiosOptions {
+ return !Array.isArray(lastArg) && typeof lastArg === "object";
+}
+
+const ZodiosAxios = new Proxy(ZodiosCore, {
+ construct(target, args) {
+ if (args.length !== 0) {
+ let lastArg = args[args.length - 1];
+ if (isZodiosOptions(lastArg)) {
+ lastArg.fetcherFactory = axiosFactory;
+ } else {
+ args.push({ fetcherFactory: axiosFactory });
+ }
+ }
+ // @ts-ignore
+ return new target(...args);
+ },
+});
+
+export interface Zodios {
+ new <
+ const Api extends readonly ZodiosEndpointDefinition[] | ZodiosEndpointDefinition[],
+ TypeProvider extends AnyZodiosTypeProvider = ZodTypeProvider
+ >(
+ api: Api,
+ options?: Omit<
+ ZodiosOptions,
+ "fetcherFactory"
+ > &
+ TypeOfFetcherOptions
+ ): ZodiosInstance;
+ new <
+ const Api extends readonly ZodiosEndpointDefinition[] | ZodiosEndpointDefinition[],
+ TypeProvider extends AnyZodiosTypeProvider = ZodTypeProvider
+ >(
+ baseUrl: string,
+ api: Api,
+ options?: Omit<
+ ZodiosOptions,
+ "fetcherFactory"
+ > &
+ TypeOfFetcherOptions
+ ): ZodiosInstance;
+}
+
+const Zodios = ZodiosAxios as Zodios;
+
+export { Zodios };
diff --git a/tsconfig.build.json b/packages/axios/tsconfig.build.json
similarity index 100%
rename from tsconfig.build.json
rename to packages/axios/tsconfig.build.json
diff --git a/packages/axios/tsconfig.json b/packages/axios/tsconfig.json
new file mode 100644
index 00000000..4f66f56f
--- /dev/null
+++ b/packages/axios/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ // ts config for es 2021
+ "compilerOptions": {
+ "target": "ES2019",
+ "module": "CommonJS",
+ "moduleResolution": "Node",
+ "lib": ["ES2019"],
+ "outDir": "./lib",
+ "alwaysStrict": true,
+ "strict": true,
+ "esModuleInterop": true,
+ "sourceMap": true,
+ "declaration": true,
+ "jsx": "react-jsx",
+ "types": ["jest", "node"]
+ },
+ "exclude": ["node_modules", "lib"]
+}
diff --git a/packages/axios/tsup.config.js b/packages/axios/tsup.config.js
new file mode 100644
index 00000000..899d5e3f
--- /dev/null
+++ b/packages/axios/tsup.config.js
@@ -0,0 +1,14 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ clean: true,
+ dts: true,
+ entry: ["src/index.ts"],
+ outDir: "lib",
+ format: ["cjs", "esm"],
+ minify: true,
+ treeshake: true,
+ tsconfig: "tsconfig.build.json",
+ splitting: true,
+ sourcemap: false,
+});
diff --git a/packages/core/.gitignore b/packages/core/.gitignore
new file mode 100644
index 00000000..9aadc156
--- /dev/null
+++ b/packages/core/.gitignore
@@ -0,0 +1,105 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# TypeScript v1 declaration files
+typings/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+.env.test
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+
+# Next.js build output
+.next
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+lib
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and *not* Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port
diff --git a/packages/core/.npmignore b/packages/core/.npmignore
new file mode 100644
index 00000000..e09f31c9
--- /dev/null
+++ b/packages/core/.npmignore
@@ -0,0 +1,40 @@
+# compiled output
+!/lib
+/node_modules
+/src
+/examples
+/website
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+
+# OS
+.DS_Store
+
+# Tests
+/coverage
+/.nyc_output
+
+# IDEs and editors
+/.idea
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# IDE - VSCode
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+
+# ENV
+.env
diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md
new file mode 100644
index 00000000..3315087c
--- /dev/null
+++ b/packages/core/CHANGELOG.md
@@ -0,0 +1,137 @@
+# @zodios/core
+
+## 11.0.0-beta.19
+
+### Major Changes
+
+- 583775e: feat(openapi): add openapi
+
+## 11.0.0-beta.18
+
+### Major Changes
+
+- 58016f5: migrate to typescript v11
+
+## 11.0.0-beta.17
+
+### Major Changes
+
+- 48a20cc: fix(react): do not double fetch if react-query signal is not used
+- 8303e57: feat(plugin): add new zodios plugin system
+
+## 11.0.0-beta.16
+
+### Major Changes
+
+- f1b38f4: feat: improve typings
+- cb56d43: feat: improve typings
+
+## 11.0.0-beta.15
+
+### Major Changes
+
+- eaf8e45: feat(fetcher): change fetcher model to factory
+- faaec6f: chore(deps): update zod
+- f161353: chore(deps): update fp-ts
+- 5115eaa: chore(deps): update typescript
+- 4ac4921: feat(react): simplify exported instance
+
+## 11.0.0-beta.14
+
+### Major Changes
+
+- 422221b: refactor: factor http verbs
+- 13247c6: chore: fix type exports for nodenext
+
+## 11.0.0-beta.13
+
+### Major Changes
+
+- 2745e1a: feat(react): migrate react to v11
+- 98433a9: fix(react): bump version
+
+## 11.0.0-beta.12
+
+### Major Changes
+
+- 29dcf47: fix(testing): safely export hooks
+
+## 11.0.0-beta.11
+
+### Major Changes
+
+- a753f07: fix(testing): import types from core instead of relaive directory
+- 33b5de0: refactor(testing): move base hooks to testing
+
+## 11.0.0-beta.10
+
+### Major Changes
+
+- c360c52: feat(testing): add response testing handlers
+
+## 11.0.0-beta.9
+
+### Major Changes
+
+- c4c00a1: chore(deps): upgrade axios
+- c6a4d0e: feat(testing): add testing package
+
+## 11.0.0-beta.8
+
+### Major Changes
+
+- e67fa49: feat(fetch): remove qs dependency
+- 731e399: tests(core): fix tests
+
+## 11.0.0-beta.7
+
+### Major Changes
+
+- 7dcbb0c: chore(fetch): fix deps
+
+## 11.0.0-beta.6
+
+### Major Changes
+
+- da4ddab: add fetch package
+- 535c76b: add basic mocks helpers
+
+## 11.0.0-beta.5
+
+### Major Changes
+
+- 1b67309: fix axios tests
+- c7c03bc: sync axios and core versions
+
+## 11.0.0-beta.4
+
+### Major Changes
+
+- 6c10dc2: rename exports
+- 679a267: update axios
+
+### Patch Changes
+
+- 14ce00b: add fetch implementation
+- c9cae0a: autocommit on changesets
+- 3ac25a1: add fetcher provider and axios impl
+- 90108a5: body is now part of the config
+
+## 11.0.0-beta.3
+
+### Patch Changes
+
+- add publish script
+- 5575e28: add tests for type providers
+
+## 11.0.0-beta.2
+
+### Patch Changes
+
+- remove publish action from ci
+
+## 11.0.0-beta.1
+
+### Patch Changes
+
+- migrate to monorepo
diff --git a/packages/core/LICENSE b/packages/core/LICENSE
new file mode 100644
index 00000000..e5dea986
--- /dev/null
+++ b/packages/core/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 ecyrbe
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/packages/core/README.md b/packages/core/README.md
new file mode 100644
index 00000000..31105cd4
--- /dev/null
+++ b/packages/core/README.md
@@ -0,0 +1,198 @@
+ Zodios
+
+
+
+
+
+
+ Zodios is a typescript api client and an optional api server with auto-completion features backed by axios and zod and express
+
+ Documentation
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+https://user-images.githubusercontent.com/633115/185851987-554f5686-cb78-4096-8ff5-c8d61b645608.mp4
+
+# What is it ?
+
+It's an axios compatible API client and an optional expressJS compatible API server with the following features:
+
+- really simple centralized API declaration
+- typescript autocompletion in your favorite IDE for URL and parameters
+- typescript response types
+- parameters and responses schema thanks to zod
+- response schema validation
+- powerfull plugins like `fetch` adapter or `auth` automatic injection
+- all axios features available
+- `@tanstack/query` wrappers for react and solid (vue, svelte, etc, soon)
+- all expressJS features available (middlewares, etc.)
+
+
+**Table of contents:**
+
+- [What is it ?](#what-is-it-)
+- [Install](#install)
+ - [Client and api definitions :](#client-and-api-definitions-)
+ - [Server :](#server-)
+- [How to use it on client side ?](#how-to-use-it-on-client-side-)
+ - [Declare your API with zodios](#declare-your-api-with-zodios)
+ - [API definition format](#api-definition-format)
+- [Full documentation](#full-documentation)
+- [Ecosystem](#ecosystem)
+- [Roadmap](#roadmap)
+- [Dependencies](#dependencies)
+
+# Install
+
+## Client and api definitions :
+
+```bash
+> npm install @zodios/core
+```
+
+or
+
+```bash
+> yarn add @zodios/core
+```
+
+## Server :
+
+```bash
+> npm install @zodios/core @zodios/express
+```
+
+or
+
+```bash
+> yarn add @zodios/core @zodios/express
+```
+
+# How to use it on client side ?
+
+For an almost complete example on how to use zodios and how to split your APIs declarations, take a look at [dev.to](examples/dev.to/) example.
+
+## Declare your API with zodios
+
+Here is an example of API declaration with Zodios.
+
+```typescript
+import { Zodios } from "@zodios/core";
+import { z } from "zod";
+
+const apiClient = new Zodios(
+ "https://jsonplaceholder.typicode.com",
+ // API definition
+ [
+ {
+ method: "get",
+ path: "/users/:id", // auto detect :id and ask for it in apiClient get params
+ alias: "getUser", // optionnal alias to call this endpoint with it
+ description: "Get a user",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+);
+```
+
+Calling this API is now easy and has builtin autocomplete features :
+
+```typescript
+// typed auto-complete path auto-complete params
+// â–¼ â–¼ â–¼
+const user = await apiClient.get("/users/:id", { params: { id: 7 } });
+console.log(user);
+```
+
+It should output
+
+```js
+{ id: 7, name: 'Kurtis Weissnat' }
+```
+You can also use aliases :
+
+```typescript
+// typed alias auto-complete params
+// â–¼ â–¼ â–¼
+const user = await apiClient.getUser({ params: { id: 7 } });
+console.log(user);
+```
+## API definition format
+
+```typescript
+type ZodiosEndpointDescriptions = Array<{
+ method: 'get'|'post'|'put'|'patch'|'delete';
+ path: string; // example: /posts/:postId/comments/:commentId
+ alias?: string; // example: getPostComments
+ immutable?: boolean; // flag a post request as immutable to allow it to be cached with react-query
+ description?: string;
+ requestFormat?: 'json'|'form-data'|'form-url'|'binary'|'text'; // default to json if not set
+ parameters?: Array<{
+ name: string;
+ description?: string;
+ type: 'Path'|'Query'|'Body'|'Header';
+ schema: ZodSchema; // you can use zod `transform` to transform the value of the parameter before sending it to the server
+ }>;
+ response: ZodSchema; // you can use zod `transform` to transform the value of the response before returning it
+ status?: number; // default to 200, you can use this to override the sucess status code of the response (only usefull for openapi and express)
+ responseDescription?: string; // optional response description of the endpoint
+ errors?: Array<{
+ status: number | 'default';
+ description?: string;
+ schema: ZodSchema; // transformations are not supported on error schemas
+ }>;
+}>;
+```
+# Full documentation
+
+Check out the [full documentation](https://www.zodios.org) or following shortcuts.
+
+- [API definition](https://www.zodios.org/docs/category/zodios-api-definition)
+- [Http client](https://www.zodios.org/docs/category/zodios-client)
+- [React hooks](https://www.zodios.org/docs/client/react)
+- [Solid hooks](https://www.zodios.org/docs/client/solid)
+- [API server](http://www.zodios.org/docs/category/zodios-server)
+- [Nextjs integration](http://www.zodios.org/docs/server/next)
+
+# Ecosystem
+
+- [openapi-zod-client](https://github.com/astahmer/openapi-zod-client): generate a zodios client from an openapi specification
+- [@zodios/express](https://github.com/ecyrbe/zodios-express): full end to end type safety like tRPC, but for REST APIs
+- [@zodios/plugins](https://github.com/ecyrbe/zodios-plugins) : some plugins for zodios
+- [@zodios/react](https://github.com/ecyrbe/zodios-react) : a react-query wrapper for zodios
+- [@zodios/solid](https://github.com/ecyrbe/zodios-solid) : a solid-query wrapper for zodios
+
+# Roadmap
+
+The following will need investigation to check if it's doable :
+- implement `@zodios/nestjs` to define your API endpoints with nestjs and share it with your frontend (like tRPC)
+- generate openAPI json from your API endpoints
+
+You have other ideas ? [Let me know !](https://github.com/ecyrbe/zodios/discussions)
+# Dependencies
+
+Zodios even when working in pure Javascript is better suited to be working with Typescript Language Server to handle autocompletion.
+So you should at least use the one provided by your IDE (vscode integrates a typescript language server)
+However, we will only support fixing bugs related to typings for versions of Typescript Language v4.5
+Earlier versions should work, but do not have TS tail recusion optimisation that impact the size of the API you can declare.
+
+Also note that Zodios do not embed any dependency. It's your Job to install the peer dependencies you need.
+
+Internally Zodios uses these libraries on all platforms :
+- zod
+- axios
diff --git a/packages/core/SECURITY.md b/packages/core/SECURITY.md
new file mode 100644
index 00000000..16be6051
--- /dev/null
+++ b/packages/core/SECURITY.md
@@ -0,0 +1,20 @@
+# Security Policy
+
+## Supported Versions
+
+Use this section to tell people about which versions of your project are
+currently being supported with security updates.
+
+| Version | Supported |
+| --------- | ------------------ |
+| 10.x.y | :white_check_mark: |
+| < 10.0.0 | :x: |
+
+## Reporting a Vulnerability
+
+If you identify a vulnerability on zodios, please create an issue with a reproductible setup.
+Do not open an issue if you can't show a reproductible setup of if the vulnerability is on third party dependency.
+
+Indeed, a vulnerability on a peer dependency should be reported on the appropriate project:
+- zod
+- axios
diff --git a/packages/core/examples/airbytes-api.ts b/packages/core/examples/airbytes-api.ts
new file mode 100644
index 00000000..9030c662
--- /dev/null
+++ b/packages/core/examples/airbytes-api.ts
@@ -0,0 +1,3019 @@
+import { makeApi, ZodiosCore, type ZodiosOptions } from "../src";
+import { z } from "zod";
+
+const NotificationType = z.enum(["slack", "customerio"]);
+const SlackNotificationConfiguration = z.object({ webhook: z.string() });
+const CustomerioNotificationConfiguration = z.object({}).partial();
+const Notification = z.object({
+ notificationType: NotificationType,
+ sendOnSuccess: z.boolean(),
+ sendOnFailure: z.boolean().default(true),
+ slackConfiguration: SlackNotificationConfiguration.optional(),
+ customerioConfiguration: CustomerioNotificationConfiguration.optional(),
+});
+const Geography = z.enum(["auto", "us", "eu"]);
+const WebhookConfigWrite = z
+ .object({
+ name: z.string(),
+ authToken: z.string(),
+ validationUrl: z.string(),
+ })
+ .partial();
+const WorkspaceCreate = z.object({
+ email: z.string().email().optional(),
+ anonymousDataCollection: z.boolean().optional(),
+ name: z.string(),
+ news: z.boolean().optional(),
+ securityUpdates: z.boolean().optional(),
+ notifications: z.array(Notification).optional(),
+ displaySetupWizard: z.boolean().optional(),
+ defaultGeography: Geography.optional(),
+ webhookConfigs: z.array(WebhookConfigWrite).optional(),
+});
+const WorkspaceId = z.string();
+const CustomerId = z.string();
+const WebhookConfigRead = z.object({
+ id: z.string().uuid(),
+ name: z.string().optional(),
+});
+const WorkspaceRead = z.object({
+ workspaceId: WorkspaceId.uuid(),
+ customerId: CustomerId.uuid(),
+ email: z.string().email().optional(),
+ name: z.string(),
+ slug: z.string(),
+ initialSetupComplete: z.boolean(),
+ displaySetupWizard: z.boolean().optional(),
+ anonymousDataCollection: z.boolean().optional(),
+ news: z.boolean().optional(),
+ securityUpdates: z.boolean().optional(),
+ notifications: z.array(Notification).optional(),
+ firstCompletedSync: z.boolean().optional(),
+ feedbackDone: z.boolean().optional(),
+ defaultGeography: Geography.optional(),
+ webhookConfigs: z.array(WebhookConfigRead).optional(),
+});
+const WorkspaceIdRequestBody = z.object({ workspaceId: WorkspaceId.uuid() });
+const WorkspaceReadList = z.object({ workspaces: z.array(WorkspaceRead) });
+const SlugRequestBody = z.object({ slug: z.string() });
+const ConnectionId = z.string();
+const ConnectionIdRequestBody = z.object({ connectionId: ConnectionId.uuid() });
+const WorkspaceUpdate = z.object({
+ workspaceId: WorkspaceId.uuid(),
+ email: z.string().email().optional(),
+ initialSetupComplete: z.boolean().optional(),
+ displaySetupWizard: z.boolean().optional(),
+ anonymousDataCollection: z.boolean().optional(),
+ news: z.boolean().optional(),
+ securityUpdates: z.boolean().optional(),
+ notifications: z.array(Notification).optional(),
+ defaultGeography: Geography.optional(),
+ webhookConfigs: z.array(WebhookConfigWrite).optional(),
+});
+const WorkspaceUpdateName = z.object({
+ workspaceId: WorkspaceId.uuid(),
+ name: z.string(),
+});
+const WorkspaceGiveFeedback = z.object({ workspaceId: WorkspaceId.uuid() });
+const NotificationRead = z.object({
+ status: z.enum(["succeeded", "failed"]),
+ message: z.string().optional(),
+});
+const SourceDefinitionId = z.string();
+const ResourceRequirements = z
+ .object({
+ cpu_request: z.string(),
+ cpu_limit: z.string(),
+ memory_request: z.string(),
+ memory_limit: z.string(),
+ })
+ .partial();
+const JobType = z.enum([
+ "get_spec",
+ "check_connection",
+ "discover_schema",
+ "sync",
+ "reset_connection",
+ "connection_updater",
+ "replicate",
+]);
+const JobTypeResourceLimit = z.object({
+ jobType: JobType,
+ resourceRequirements: ResourceRequirements,
+});
+const ActorDefinitionResourceRequirements = z
+ .object({
+ default: ResourceRequirements,
+ jobSpecific: z.array(JobTypeResourceLimit),
+ })
+ .partial();
+const SourceDefinitionUpdate = z.object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ dockerImageTag: z.string(),
+ resourceRequirements: ActorDefinitionResourceRequirements.optional(),
+});
+const ReleaseStage = z.enum(["alpha", "beta", "generally_available", "custom"]);
+const SourceDefinitionRead = z.object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ name: z.string(),
+ dockerRepository: z.string(),
+ dockerImageTag: z.string(),
+ documentationUrl: z.string().url().optional(),
+ icon: z.string().optional(),
+ protocolVersion: z.string().optional(),
+ releaseStage: ReleaseStage.optional(),
+ releaseDate: z.string().optional(),
+ sourceType: z.enum(["api", "file", "database", "custom"]).optional(),
+ resourceRequirements: ActorDefinitionResourceRequirements.optional(),
+});
+const SourceDefinitionReadList = z.object({
+ sourceDefinitions: z.array(SourceDefinitionRead),
+});
+const SourceDefinitionIdRequestBody = z.object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+});
+const PrivateSourceDefinitionRead = z.object({
+ sourceDefinition: SourceDefinitionRead,
+ granted: z.boolean(),
+});
+const PrivateSourceDefinitionReadList = z.object({
+ sourceDefinitions: z.array(PrivateSourceDefinitionRead),
+});
+const SourceDefinitionCreate = z.object({
+ name: z.string(),
+ dockerRepository: z.string(),
+ dockerImageTag: z.string(),
+ documentationUrl: z.string().url(),
+ icon: z.string().optional(),
+ resourceRequirements: ActorDefinitionResourceRequirements.optional(),
+});
+const CustomSourceDefinitionCreate = z.object({
+ workspaceId: WorkspaceId.uuid(),
+ sourceDefinition: SourceDefinitionCreate,
+});
+const SourceDefinitionIdWithWorkspaceId = z.object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ workspaceId: WorkspaceId.uuid(),
+});
+const SourceDefinitionSpecification = z.object({}).partial();
+const OAuth2Specification = z.object({
+ rootObject: z.array(z.unknown()),
+ oauthFlowInitParameters: z.array(z.array(z.string())),
+ oauthFlowOutputParameters: z.array(z.array(z.string())),
+});
+const AuthSpecification = z
+ .object({
+ auth_type: z.literal("oauth2.0"),
+ oauth2Specification: OAuth2Specification,
+ })
+ .partial();
+const SourceAuthSpecification = AuthSpecification;
+const OAuthConfiguration = z.unknown();
+const OAuthConfigSpecification = z
+ .object({
+ oauthUserInputFromConnectorConfigSpecification: OAuthConfiguration,
+ completeOAuthOutputSpecification: OAuthConfiguration,
+ completeOAuthServerInputSpecification: OAuthConfiguration,
+ completeOAuthServerOutputSpecification: OAuthConfiguration,
+ })
+ .partial();
+const AdvancedAuth = z
+ .object({
+ authFlowType: z.enum(["oauth2.0", "oauth1.0"]),
+ predicateKey: z.array(z.string()),
+ predicateValue: z.string(),
+ oauthConfigSpecification: OAuthConfigSpecification,
+ })
+ .partial();
+const JobConfigType = z.enum([
+ "check_connection_source",
+ "check_connection_destination",
+ "discover_schema",
+ "get_spec",
+ "sync",
+ "reset_connection",
+]);
+const LogRead = z.object({ logLines: z.array(z.string()) });
+const SynchronousJobRead = z.object({
+ id: z.string().uuid(),
+ configType: JobConfigType,
+ configId: z.string().optional(),
+ createdAt: z.number().int(),
+ endedAt: z.number().int(),
+ succeeded: z.boolean(),
+ connectorConfigurationUpdated: z.boolean().optional(),
+ logs: LogRead.optional(),
+});
+const SourceDefinitionSpecificationRead = z.object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ documentationUrl: z.string().optional(),
+ connectionSpecification: SourceDefinitionSpecification.optional(),
+ authSpecification: SourceAuthSpecification.optional(),
+ advancedAuth: AdvancedAuth.optional(),
+ jobInfo: SynchronousJobRead,
+});
+const SourceConfiguration = z.unknown();
+const SourceCreate = z.object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ connectionConfiguration: SourceConfiguration,
+ workspaceId: WorkspaceId.uuid(),
+ name: z.string(),
+});
+const SourceId = z.string();
+const SourceRead = z.object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ sourceId: SourceId.uuid(),
+ workspaceId: WorkspaceId.uuid(),
+ connectionConfiguration: SourceConfiguration,
+ name: z.string(),
+ sourceName: z.string(),
+ icon: z.string().optional(),
+});
+const SourceUpdate = z.object({
+ sourceId: SourceId.uuid(),
+ connectionConfiguration: SourceConfiguration,
+ name: z.string(),
+});
+const SourceReadList = z.object({ sources: z.array(SourceRead) });
+const SourceIdRequestBody = z.object({ sourceId: SourceId.uuid() });
+const ActorCatalogWithUpdatedAt = z
+ .object({ updatedAt: z.number().int(), catalog: z.object({}).partial() })
+ .partial();
+const SourceSearch = z
+ .object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ sourceId: SourceId.uuid(),
+ workspaceId: WorkspaceId.uuid(),
+ connectionConfiguration: SourceConfiguration,
+ name: z.string(),
+ sourceName: z.string(),
+ })
+ .partial();
+const SourceCloneConfiguration = z
+ .object({ connectionConfiguration: SourceConfiguration, name: z.string() })
+ .partial();
+const SourceCloneRequestBody = z.object({
+ sourceCloneId: SourceId.uuid(),
+ sourceConfiguration: SourceCloneConfiguration.optional(),
+});
+const CheckConnectionRead = z.object({
+ status: z.enum(["succeeded", "failed"]),
+ message: z.string().optional(),
+ jobInfo: SynchronousJobRead,
+});
+const SourceDiscoverSchemaRequestBody = z.object({
+ sourceId: SourceId.uuid(),
+ connectionId: z.string().uuid().optional(),
+ disable_cache: z.boolean().optional(),
+ notifySchemaChange: z.boolean().optional(),
+});
+const StreamJsonSchema = z.object({}).partial();
+const SyncMode = z.enum(["full_refresh", "incremental"]);
+const AirbyteStream = z.object({
+ name: z.string(),
+ jsonSchema: StreamJsonSchema.optional(),
+ supportedSyncModes: z.array(SyncMode).optional(),
+ sourceDefinedCursor: z.boolean().optional(),
+ defaultCursorField: z.array(z.string()).optional(),
+ sourceDefinedPrimaryKey: z.array(z.array(z.string())).optional(),
+ namespace: z.string().optional(),
+});
+const DestinationSyncMode = z.enum(["append", "overwrite", "append_dedup"]);
+const SelectedFieldInfo = z
+ .object({ fieldPath: z.array(z.string()) })
+ .partial();
+const AirbyteStreamConfiguration = z.object({
+ syncMode: SyncMode,
+ cursorField: z.array(z.string()).optional(),
+ destinationSyncMode: DestinationSyncMode,
+ primaryKey: z.array(z.array(z.string())).optional(),
+ aliasName: z.string().optional(),
+ selected: z.boolean().optional(),
+ suggested: z.boolean().optional(),
+ fieldSelectionEnabled: z.boolean().optional(),
+ selectedFields: z.array(SelectedFieldInfo).optional(),
+});
+const AirbyteStreamAndConfiguration = z
+ .object({ stream: AirbyteStream, config: AirbyteStreamConfiguration })
+ .partial();
+const AirbyteCatalog = z.object({
+ streams: z.array(AirbyteStreamAndConfiguration),
+});
+const StreamDescriptor = z.object({
+ name: z.string(),
+ namespace: z.string().optional(),
+});
+const FieldName = z.array(z.string());
+const FieldSchema = z.object({}).partial();
+const FieldAdd = z.object({ schema: FieldSchema }).partial();
+const FieldRemove = z.object({ schema: FieldSchema }).partial();
+const FieldSchemaUpdate = z.object({
+ oldSchema: FieldSchema,
+ newSchema: FieldSchema,
+});
+const FieldTransform = z.object({
+ transformType: z.enum(["add_field", "remove_field", "update_field_schema"]),
+ fieldName: FieldName,
+ breaking: z.boolean(),
+ addField: FieldAdd.optional(),
+ removeField: FieldRemove.optional(),
+ updateFieldSchema: FieldSchemaUpdate.optional(),
+});
+const StreamTransform = z.object({
+ transformType: z.enum(["add_stream", "remove_stream", "update_stream"]),
+ streamDescriptor: StreamDescriptor,
+ updateStream: z.array(FieldTransform).optional(),
+});
+const CatalogDiff = z.object({ transforms: z.array(StreamTransform) });
+const ConnectionStatus = z.enum(["active", "inactive", "deprecated"]);
+const SourceDiscoverSchemaRead = z.object({
+ catalog: AirbyteCatalog.optional(),
+ jobInfo: SynchronousJobRead,
+ catalogId: z.string().uuid().optional(),
+ catalogDiff: CatalogDiff.optional(),
+ breakingChange: z.boolean().optional(),
+ connectionStatus: ConnectionStatus.optional(),
+});
+const SourceDiscoverSchemaWriteRequestBody = z.object({
+ catalog: AirbyteCatalog,
+ sourceId: SourceId.uuid().optional(),
+ connectorVersion: z.string().optional(),
+ configurationHash: z.string().optional(),
+});
+const DiscoverCatalogResult = z.object({ catalogId: z.string().uuid() });
+const DestinationDefinitionId = z.string();
+const DestinationDefinitionUpdate = z.object({
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ dockerImageTag: z.string().optional(),
+ resourceRequirements: ActorDefinitionResourceRequirements.optional(),
+});
+const NormalizationDestinationDefinitionConfig = z.object({
+ supported: z.boolean(),
+ normalizationRepository: z.string().optional(),
+ normalizationTag: z.string().optional(),
+ normalizationIntegrationType: z.string().optional(),
+});
+const DestinationDefinitionRead = z.object({
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ name: z.string(),
+ dockerRepository: z.string(),
+ dockerImageTag: z.string(),
+ documentationUrl: z.string().url(),
+ icon: z.string().optional(),
+ protocolVersion: z.string().optional(),
+ releaseStage: ReleaseStage.optional(),
+ releaseDate: z.string().optional(),
+ resourceRequirements: ActorDefinitionResourceRequirements.optional(),
+ supportsDbt: z.boolean(),
+ normalizationConfig: NormalizationDestinationDefinitionConfig,
+});
+const DestinationDefinitionReadList = z.object({
+ destinationDefinitions: z.array(DestinationDefinitionRead),
+});
+const DestinationDefinitionIdRequestBody = z.object({
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+});
+const PrivateDestinationDefinitionRead = z.object({
+ destinationDefinition: DestinationDefinitionRead,
+ granted: z.boolean(),
+});
+const PrivateDestinationDefinitionReadList = z.object({
+ destinationDefinitions: z.array(PrivateDestinationDefinitionRead),
+});
+const DestinationDefinitionCreate = z.object({
+ name: z.string(),
+ dockerRepository: z.string(),
+ dockerImageTag: z.string(),
+ documentationUrl: z.string().url(),
+ icon: z.string().optional(),
+ resourceRequirements: ActorDefinitionResourceRequirements.optional(),
+});
+const CustomDestinationDefinitionCreate = z.object({
+ workspaceId: WorkspaceId.uuid(),
+ destinationDefinition: DestinationDefinitionCreate,
+});
+const DestinationDefinitionIdWithWorkspaceId = z.object({
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ workspaceId: WorkspaceId.uuid(),
+});
+const DestinationDefinitionSpecification = z.unknown();
+const DestinationAuthSpecification = AuthSpecification;
+const DestinationDefinitionSpecificationRead = z.object({
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ documentationUrl: z.string().optional(),
+ connectionSpecification: DestinationDefinitionSpecification.optional(),
+ authSpecification: DestinationAuthSpecification.optional(),
+ advancedAuth: AdvancedAuth.optional(),
+ jobInfo: SynchronousJobRead,
+ supportedDestinationSyncModes: z.array(DestinationSyncMode).optional(),
+});
+const DestinationConfiguration = z.unknown();
+const DestinationCreate = z.object({
+ workspaceId: WorkspaceId.uuid(),
+ name: z.string(),
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ connectionConfiguration: DestinationConfiguration,
+});
+const DestinationId = z.string();
+const DestinationRead = z.object({
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ destinationId: DestinationId.uuid(),
+ workspaceId: WorkspaceId.uuid(),
+ connectionConfiguration: DestinationConfiguration,
+ name: z.string(),
+ destinationName: z.string(),
+ icon: z.string().optional(),
+});
+const DestinationUpdate = z.object({
+ destinationId: DestinationId.uuid(),
+ connectionConfiguration: DestinationConfiguration,
+ name: z.string(),
+});
+const DestinationReadList = z.object({
+ destinations: z.array(DestinationRead),
+});
+const DestinationIdRequestBody = z.object({
+ destinationId: DestinationId.uuid(),
+});
+const DestinationSearch = z
+ .object({
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ destinationId: DestinationId.uuid(),
+ workspaceId: WorkspaceId.uuid(),
+ connectionConfiguration: DestinationConfiguration,
+ name: z.string(),
+ destinationName: z.string(),
+ })
+ .partial();
+const DestinationCloneConfiguration = z
+ .object({
+ connectionConfiguration: DestinationConfiguration,
+ name: z.string(),
+ })
+ .partial();
+const DestinationCloneRequestBody = z.object({
+ destinationCloneId: DestinationId.uuid(),
+ destinationConfiguration: DestinationCloneConfiguration.optional(),
+});
+const NamespaceDefinitionType = z.enum([
+ "source",
+ "destination",
+ "customformat",
+]);
+const OperationId = z.string();
+const ConnectionSchedule = z.object({
+ units: z.number().int(),
+ timeUnit: z.enum(["minutes", "hours", "days", "weeks", "months"]),
+});
+const ConnectionScheduleType = z.enum(["manual", "basic", "cron"]);
+const ConnectionScheduleData = z
+ .object({
+ basicSchedule: z.object({
+ timeUnit: z.enum(["minutes", "hours", "days", "weeks", "months"]),
+ units: z.number().int(),
+ }),
+ cron: z.object({ cronExpression: z.string(), cronTimeZone: z.string() }),
+ })
+ .partial();
+const NonBreakingChangesPreference = z.enum(["ignore", "disable"]);
+const ConnectionCreate = z.object({
+ name: z.string().optional(),
+ namespaceDefinition: NamespaceDefinitionType.optional(),
+ namespaceFormat: z.string().optional(),
+ prefix: z.string().optional(),
+ sourceId: SourceId.uuid(),
+ destinationId: DestinationId.uuid(),
+ operationIds: z.array(OperationId).optional(),
+ syncCatalog: AirbyteCatalog.optional(),
+ schedule: ConnectionSchedule.optional(),
+ scheduleType: ConnectionScheduleType.optional(),
+ scheduleData: ConnectionScheduleData.optional(),
+ status: ConnectionStatus,
+ resourceRequirements: ResourceRequirements.optional(),
+ sourceCatalogId: z.string().uuid().optional(),
+ geography: Geography.optional(),
+ notifySchemaChanges: z.boolean().optional(),
+ nonBreakingChangesPreference: NonBreakingChangesPreference.optional(),
+});
+const ConnectionRead = z.object({
+ connectionId: ConnectionId.uuid(),
+ name: z.string(),
+ namespaceDefinition: NamespaceDefinitionType.optional(),
+ namespaceFormat: z.string().optional(),
+ prefix: z.string().optional(),
+ sourceId: SourceId.uuid(),
+ destinationId: DestinationId.uuid(),
+ operationIds: z.array(OperationId).optional(),
+ syncCatalog: AirbyteCatalog,
+ schedule: ConnectionSchedule.optional(),
+ scheduleType: ConnectionScheduleType.optional(),
+ scheduleData: ConnectionScheduleData.optional(),
+ status: ConnectionStatus,
+ resourceRequirements: ResourceRequirements.optional(),
+ sourceCatalogId: z.string().uuid().optional(),
+ geography: Geography.optional(),
+ breakingChange: z.boolean(),
+ notifySchemaChanges: z.boolean().optional(),
+ nonBreakingChangesPreference: NonBreakingChangesPreference.optional(),
+});
+const ConnectionUpdate = z.object({
+ connectionId: ConnectionId.uuid(),
+ namespaceDefinition: NamespaceDefinitionType.optional(),
+ namespaceFormat: z.string().optional(),
+ name: z.string().optional(),
+ prefix: z.string().optional(),
+ operationIds: z.array(OperationId).optional(),
+ syncCatalog: AirbyteCatalog.optional(),
+ schedule: ConnectionSchedule.optional(),
+ scheduleType: ConnectionScheduleType.optional(),
+ scheduleData: ConnectionScheduleData.optional(),
+ status: ConnectionStatus.optional(),
+ resourceRequirements: ResourceRequirements.optional(),
+ sourceCatalogId: z.string().uuid().optional(),
+ geography: Geography.optional(),
+ notifySchemaChanges: z.boolean().optional(),
+ nonBreakingChangesPreference: NonBreakingChangesPreference.optional(),
+ breakingChange: z.boolean().optional(),
+});
+const ConnectionReadList = z.object({ connections: z.array(ConnectionRead) });
+const ConnectionStateType = z.enum(["global", "stream", "legacy", "not_set"]);
+const StateBlob = z.object({}).partial();
+const StreamState = z.object({
+ streamDescriptor: StreamDescriptor,
+ streamState: StateBlob.optional(),
+});
+const GlobalState = z.object({
+ shared_state: StateBlob.optional(),
+ streamStates: z.array(StreamState),
+});
+const ConnectionState = z.object({
+ stateType: ConnectionStateType,
+ connectionId: ConnectionId.uuid(),
+ state: StateBlob.optional(),
+ streamState: z.array(StreamState).optional(),
+ globalState: GlobalState.optional(),
+});
+const ConnectionStateCreateOrUpdate = z.object({
+ connectionId: ConnectionId.uuid(),
+ connectionState: ConnectionState,
+});
+const ConnectionSearch = z
+ .object({
+ connectionId: ConnectionId.uuid(),
+ name: z.string(),
+ namespaceDefinition: NamespaceDefinitionType,
+ namespaceFormat: z.string(),
+ prefix: z.string(),
+ sourceId: SourceId.uuid(),
+ destinationId: DestinationId.uuid(),
+ schedule: ConnectionSchedule,
+ scheduleType: ConnectionScheduleType,
+ scheduleData: ConnectionScheduleData,
+ status: ConnectionStatus,
+ source: SourceSearch,
+ destination: DestinationSearch,
+ })
+ .partial();
+const JobId = z.number();
+const JobStatus = z.enum([
+ "pending",
+ "running",
+ "incomplete",
+ "failed",
+ "succeeded",
+ "cancelled",
+]);
+const ResetConfig = z
+ .object({ streamsToReset: z.array(StreamDescriptor) })
+ .partial();
+const JobRead = z.object({
+ id: JobId.int(),
+ configType: JobConfigType,
+ configId: z.string(),
+ createdAt: z.number().int(),
+ updatedAt: z.number().int(),
+ startedAt: z.number().int().optional(),
+ status: JobStatus,
+ resetConfig: ResetConfig.optional(),
+});
+const AttemptStatus = z.enum(["running", "failed", "succeeded"]);
+const AttemptStats = z
+ .object({
+ recordsEmitted: z.number().int(),
+ bytesEmitted: z.number().int(),
+ stateMessagesEmitted: z.number().int(),
+ recordsCommitted: z.number().int(),
+ estimatedRecords: z.number().int(),
+ estimatedBytes: z.number().int(),
+ })
+ .partial();
+const AttemptStreamStats = z.object({
+ streamName: z.string(),
+ streamNamespace: z.string().optional(),
+ stats: AttemptStats,
+});
+const AttemptFailureOrigin = z.enum([
+ "source",
+ "destination",
+ "replication",
+ "persistence",
+ "normalization",
+ "dbt",
+ "airbyte_platform",
+ "unknown",
+]);
+const AttemptFailureType = z.enum([
+ "config_error",
+ "system_error",
+ "manual_cancellation",
+ "refresh_schema",
+]);
+const AttemptFailureReason = z.object({
+ failureOrigin: AttemptFailureOrigin.optional(),
+ failureType: AttemptFailureType.optional(),
+ externalMessage: z.string().optional(),
+ internalMessage: z.string().optional(),
+ stacktrace: z.string().optional(),
+ retryable: z.boolean().optional(),
+ timestamp: z.number().int(),
+});
+const AttemptFailureSummary = z.object({
+ failures: z.array(AttemptFailureReason),
+ partialSuccess: z.boolean().optional(),
+});
+const AttemptRead = z.object({
+ id: z.number().int(),
+ status: AttemptStatus,
+ createdAt: z.number().int(),
+ updatedAt: z.number().int(),
+ endedAt: z.number().int().optional(),
+ bytesSynced: z.number().int().optional(),
+ recordsSynced: z.number().int().optional(),
+ totalStats: AttemptStats.optional(),
+ streamStats: z.array(AttemptStreamStats).optional(),
+ failureSummary: AttemptFailureSummary.optional(),
+});
+const AttemptInfoRead = z.object({ attempt: AttemptRead, logs: LogRead });
+const JobInfoRead = z.object({
+ job: JobRead,
+ attempts: z.array(AttemptInfoRead),
+});
+const OperatorType = z.enum(["normalization", "dbt", "webhook"]);
+const OperatorNormalization = z
+ .object({ option: z.literal("basic") })
+ .partial();
+const OperatorDbt = z.object({
+ gitRepoUrl: z.string(),
+ gitRepoBranch: z.string().optional(),
+ dockerImage: z.string().optional(),
+ dbtArguments: z.string().optional(),
+});
+const OperatorWebhook = z
+ .object({
+ webhookConfigId: z.string().uuid(),
+ webhookType: z.literal("dbtCloud"),
+ dbtCloud: z.object({
+ accountId: z.number().int(),
+ jobId: z.number().int(),
+ }),
+ executionUrl: z.string(),
+ executionBody: z.string(),
+ })
+ .partial();
+const OperatorConfiguration = z.object({
+ operatorType: OperatorType,
+ normalization: OperatorNormalization.optional(),
+ dbt: OperatorDbt.optional(),
+ webhook: OperatorWebhook.optional(),
+});
+const CheckOperationRead = z.object({
+ status: z.enum(["succeeded", "failed"]),
+ message: z.string().optional(),
+});
+const OperationCreate = z.object({
+ workspaceId: WorkspaceId.uuid(),
+ name: z.string(),
+ operatorConfiguration: OperatorConfiguration,
+});
+const OperationRead = z.object({
+ workspaceId: WorkspaceId.uuid(),
+ operationId: OperationId.uuid(),
+ name: z.string(),
+ operatorConfiguration: OperatorConfiguration,
+});
+const OperationUpdate = z.object({
+ operationId: OperationId.uuid(),
+ name: z.string(),
+ operatorConfiguration: OperatorConfiguration,
+});
+const OperationReadList = z.object({ operations: z.array(OperationRead) });
+const OperationIdRequestBody = z.object({ operationId: OperationId.uuid() });
+const SourceCoreConfig = z.object({
+ sourceId: SourceId.uuid().optional(),
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ connectionConfiguration: SourceConfiguration,
+ workspaceId: WorkspaceId.uuid(),
+});
+const DestinationCoreConfig = z.object({
+ destinationId: DestinationId.uuid().optional(),
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ connectionConfiguration: DestinationConfiguration,
+ workspaceId: WorkspaceId.uuid(),
+});
+const SetInstancewideSourceOauthParamsRequestBody = z.object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ params: z.object({}).partial().passthrough(),
+});
+const OAuthInputConfiguration = OAuthConfiguration;
+const SourceOauthConsentRequest = z.object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ workspaceId: WorkspaceId.uuid(),
+ redirectUrl: z.string(),
+ oAuthInputConfiguration: OAuthInputConfiguration.optional(),
+ sourceId: SourceId.uuid().optional(),
+});
+const OAuthConsentRead = z.object({ consentUrl: z.string() });
+const CompleteSourceOauthRequest = z.object({
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ workspaceId: WorkspaceId.uuid(),
+ redirectUrl: z.string().optional(),
+ queryParams: z.object({}).partial().passthrough().optional(),
+ oAuthInputConfiguration: OAuthInputConfiguration.optional(),
+ sourceId: SourceId.uuid().optional(),
+});
+const CompleteOAuthResponse = z.object({}).partial().passthrough();
+const DestinationOauthConsentRequest = z.object({
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ workspaceId: WorkspaceId.uuid(),
+ redirectUrl: z.string(),
+ oAuthInputConfiguration: OAuthInputConfiguration.optional(),
+ destinationId: DestinationId.uuid().optional(),
+});
+const CompleteDestinationOAuthRequest = z.object({
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ workspaceId: WorkspaceId.uuid(),
+ redirectUrl: z.string().optional(),
+ queryParams: z.object({}).partial().passthrough().optional(),
+ oAuthInputConfiguration: OAuthInputConfiguration.optional(),
+ destinationId: DestinationId.uuid().optional(),
+});
+const SetInstancewideDestinationOauthParamsRequestBody = z.object({
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ params: z.object({}).partial().passthrough(),
+});
+const WebBackendCheckUpdatesRead = z.object({
+ destinationDefinitions: z.number().int(),
+ sourceDefinitions: z.number().int(),
+});
+const WebBackendConnectionListRequestBody = z.object({
+ workspaceId: WorkspaceId.uuid(),
+ sourceId: z.array(SourceId).optional(),
+ destinationId: z.array(DestinationId).optional(),
+});
+const SourceSnippetRead = z.object({
+ sourceId: SourceId.uuid(),
+ name: z.string(),
+ sourceDefinitionId: SourceDefinitionId.uuid(),
+ sourceName: z.string(),
+ icon: z.string().optional(),
+});
+const DestinationSnippetRead = z.object({
+ destinationId: DestinationId.uuid(),
+ name: z.string(),
+ destinationDefinitionId: DestinationDefinitionId.uuid(),
+ destinationName: z.string(),
+ icon: z.string().optional(),
+});
+const JobCreatedAt = z.number();
+const SchemaChange = z.enum(["no_change", "non_breaking", "breaking"]);
+const WebBackendConnectionListItem = z.object({
+ connectionId: ConnectionId.uuid(),
+ name: z.string(),
+ scheduleType: ConnectionScheduleType.optional(),
+ scheduleData: ConnectionScheduleData.optional(),
+ status: ConnectionStatus,
+ source: SourceSnippetRead,
+ destination: DestinationSnippetRead,
+ latestSyncJobCreatedAt: JobCreatedAt.int().optional(),
+ latestSyncJobStatus: JobStatus.optional(),
+ isSyncing: z.boolean(),
+ schemaChange: SchemaChange,
+});
+const WebBackendConnectionReadList = z.object({
+ connections: z.array(WebBackendConnectionListItem),
+});
+const WebBackendConnectionRequestBody = z.object({
+ withRefreshedCatalog: z.boolean().optional(),
+ connectionId: ConnectionId.uuid(),
+});
+const WebBackendConnectionRead = z.object({
+ connectionId: ConnectionId.uuid(),
+ name: z.string(),
+ namespaceDefinition: NamespaceDefinitionType.optional(),
+ namespaceFormat: z.string().optional(),
+ prefix: z.string().optional(),
+ sourceId: SourceId.uuid(),
+ destinationId: DestinationId.uuid(),
+ syncCatalog: AirbyteCatalog,
+ schedule: ConnectionSchedule.optional(),
+ scheduleType: ConnectionScheduleType.optional(),
+ scheduleData: ConnectionScheduleData.optional(),
+ status: ConnectionStatus,
+ operationIds: z.array(OperationId).optional(),
+ source: SourceRead,
+ destination: DestinationRead,
+ operations: z.array(OperationRead).optional(),
+ latestSyncJobCreatedAt: JobCreatedAt.int().optional(),
+ latestSyncJobStatus: JobStatus.optional(),
+ isSyncing: z.boolean(),
+ resourceRequirements: ResourceRequirements.optional(),
+ catalogId: z.string().uuid().optional(),
+ catalogDiff: CatalogDiff.optional(),
+ geography: Geography.optional(),
+ schemaChange: SchemaChange,
+ notifySchemaChanges: z.boolean(),
+ nonBreakingChangesPreference: NonBreakingChangesPreference,
+});
+const WebBackendConnectionCreate = z.object({
+ name: z.string().optional(),
+ namespaceDefinition: NamespaceDefinitionType.optional(),
+ namespaceFormat: z.string().optional(),
+ prefix: z.string().optional(),
+ sourceId: SourceId.uuid(),
+ destinationId: DestinationId.uuid(),
+ operationIds: z.array(OperationId).optional(),
+ syncCatalog: AirbyteCatalog.optional(),
+ schedule: ConnectionSchedule.optional(),
+ scheduleType: ConnectionScheduleType.optional(),
+ scheduleData: ConnectionScheduleData.optional(),
+ status: ConnectionStatus,
+ resourceRequirements: ResourceRequirements.optional(),
+ operations: z.array(OperationCreate).optional(),
+ sourceCatalogId: z.string().uuid().optional(),
+ geography: Geography.optional(),
+ nonBreakingChangesPreference: NonBreakingChangesPreference.optional(),
+});
+const WebBackendOperationCreateOrUpdate = z.object({
+ operationId: OperationId.uuid().optional(),
+ workspaceId: WorkspaceId.uuid(),
+ name: z.string(),
+ operatorConfiguration: OperatorConfiguration,
+});
+const WebBackendConnectionUpdate = z.object({
+ name: z.string().optional(),
+ connectionId: ConnectionId.uuid(),
+ namespaceDefinition: NamespaceDefinitionType.optional(),
+ namespaceFormat: z.string().optional(),
+ prefix: z.string().optional(),
+ syncCatalog: AirbyteCatalog.optional(),
+ schedule: ConnectionSchedule.optional(),
+ scheduleType: ConnectionScheduleType.optional(),
+ scheduleData: ConnectionScheduleData.optional(),
+ status: ConnectionStatus.optional(),
+ resourceRequirements: ResourceRequirements.optional(),
+ skipReset: z.boolean().optional(),
+ operations: z.array(WebBackendOperationCreateOrUpdate).optional(),
+ sourceCatalogId: z.string().uuid().optional(),
+ geography: Geography.optional(),
+ notifySchemaChanges: z.boolean().optional(),
+ nonBreakingChangesPreference: NonBreakingChangesPreference.optional(),
+});
+const WebBackendWorkspaceState = z.object({ workspaceId: WorkspaceId.uuid() });
+const WebBackendWorkspaceStateResult = z.object({
+ hasConnections: z.boolean(),
+ hasSources: z.boolean(),
+ hasDestinations: z.boolean(),
+});
+const WebBackendGeographiesListResult = z.object({
+ geographies: z.array(Geography),
+});
+const Pagination = z
+ .object({ pageSize: z.number().int(), rowOffset: z.number().int() })
+ .partial();
+const JobListRequestBody = z.object({
+ configTypes: z.array(JobConfigType),
+ configId: z.string(),
+ includingJobId: JobId.int().optional(),
+ pagination: Pagination.optional(),
+});
+const JobWithAttemptsRead = z
+ .object({ job: JobRead, attempts: z.array(AttemptRead) })
+ .partial();
+const JobReadList = z.object({
+ jobs: z.array(JobWithAttemptsRead),
+ totalJobCount: z.number().int(),
+});
+const JobIdRequestBody = z.object({ id: JobId.int() });
+const JobOptionalRead = z.object({ job: JobRead }).partial();
+const JobInfoLightRead = z.object({ job: JobRead });
+const JobDebugRead = z.object({
+ id: JobId.int(),
+ configType: JobConfigType,
+ configId: z.string(),
+ status: JobStatus,
+ airbyteVersion: z.string(),
+ sourceDefinition: SourceDefinitionRead,
+ destinationDefinition: DestinationDefinitionRead,
+});
+const WorkflowStateRead = z.object({ running: z.boolean() });
+const JobDebugInfoRead = z.object({
+ job: JobDebugRead,
+ attempts: z.array(AttemptInfoRead),
+ workflowState: WorkflowStateRead.optional(),
+});
+const AttemptNumber = z.number();
+const AttemptNormalizationStatusRead = z
+ .object({
+ attemptNumber: AttemptNumber.int(),
+ hasRecordsCommitted: z.boolean(),
+ recordsCommitted: z.number().int(),
+ hasNormalizationFailed: z.boolean(),
+ })
+ .partial();
+const AttemptNormalizationStatusReadList = z
+ .object({
+ attemptNormalizationStatuses: z.array(AttemptNormalizationStatusRead),
+ })
+ .partial();
+const HealthCheckRead = z.object({ available: z.boolean() });
+const LogType = z.enum(["server", "scheduler"]);
+const LogsRequestBody = z.object({ logType: LogType });
+const WorkflowId = z.string();
+const SetWorkflowInAttemptRequestBody = z.object({
+ jobId: JobId.int(),
+ attemptNumber: AttemptNumber.int(),
+ workflowId: WorkflowId,
+ processingTaskQueue: z.string().optional(),
+});
+const InternalOperationResult = z.object({ succeeded: z.boolean() });
+const SaveStatsRequestBody = z.object({
+ jobId: JobId.int(),
+ attemptNumber: AttemptNumber.int(),
+ stats: AttemptStats,
+ streamStats: z.array(AttemptStreamStats).optional(),
+});
+const AttemptSyncConfig = z.object({
+ sourceConfiguration: SourceConfiguration,
+ destinationConfiguration: DestinationConfiguration,
+ state: ConnectionState.optional(),
+});
+const SaveAttemptSyncConfigRequestBody = z.object({
+ jobId: JobId.int(),
+ attemptNumber: AttemptNumber.int(),
+ syncConfig: AttemptSyncConfig,
+});
+
+const endpoints = makeApi([
+ {
+ method: "post",
+ path: "/v1/attempt/save_stats",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SaveStatsRequestBody,
+ },
+ ],
+ response: z.object({ succeeded: z.boolean() }),
+ },
+ {
+ method: "post",
+ path: "/v1/attempt/save_sync_config",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SaveAttemptSyncConfigRequestBody,
+ },
+ ],
+ response: z.object({ succeeded: z.boolean() }),
+ },
+ {
+ method: "post",
+ path: "/v1/attempt/set_workflow_in_attempt",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SetWorkflowInAttemptRequestBody,
+ },
+ ],
+ response: z.object({ succeeded: z.boolean() }),
+ },
+ {
+ method: "post",
+ path: "/v1/connections/create",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionCreate,
+ },
+ ],
+ response: ConnectionRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/connections/delete",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionIdRequestBody,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/connections/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionIdRequestBody,
+ },
+ ],
+ response: ConnectionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/connections/list",
+ description: `List connections for workspace. Does not return deleted connections.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceIdRequestBody,
+ },
+ ],
+ response: ConnectionReadList,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/connections/list_all",
+ description: `List connections for workspace, including deleted connections.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceIdRequestBody,
+ },
+ ],
+ response: ConnectionReadList,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/connections/reset",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionIdRequestBody,
+ },
+ ],
+ response: JobInfoRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/connections/search",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionSearch,
+ },
+ ],
+ response: ConnectionReadList,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/connections/sync",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionIdRequestBody,
+ },
+ ],
+ response: JobInfoRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/connections/update",
+ description: `Apply a patch-style update to a connection. Only fields present on the update request body will be updated.
+Note that if a catalog is present in the request body, the connection's entire catalog will be replaced
+with the catalog from the request. This means that to modify a single stream, the entire new catalog
+containing the updated stream needs to be sent.
+`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionUpdate,
+ },
+ ],
+ response: ConnectionRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definition_specifications/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationDefinitionIdWithWorkspaceId,
+ },
+ ],
+ response: DestinationDefinitionSpecificationRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/create_custom",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: CustomDestinationDefinitionCreate,
+ },
+ ],
+ response: DestinationDefinitionRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/delete",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationDefinitionIdRequestBody,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationDefinitionIdRequestBody,
+ },
+ ],
+ response: DestinationDefinitionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/get_for_workspace",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationDefinitionIdWithWorkspaceId,
+ },
+ ],
+ response: DestinationDefinitionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/grant_definition",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationDefinitionIdWithWorkspaceId,
+ },
+ ],
+ response: PrivateDestinationDefinitionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/list",
+ requestFormat: "json",
+ response: DestinationDefinitionReadList,
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/list_for_workspace",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceIdRequestBody,
+ },
+ ],
+ response: DestinationDefinitionReadList,
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/list_latest",
+ description: `Guaranteed to retrieve the latest information on supported destinations.`,
+ requestFormat: "json",
+ response: DestinationDefinitionReadList,
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/list_private",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceIdRequestBody,
+ },
+ ],
+ response: PrivateDestinationDefinitionReadList,
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/revoke_definition",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationDefinitionIdWithWorkspaceId,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_definitions/update",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationDefinitionUpdate,
+ },
+ ],
+ response: DestinationDefinitionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_oauths/complete_oauth",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: CompleteDestinationOAuthRequest,
+ },
+ ],
+ response: z.object({}).partial().passthrough(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_oauths/get_consent_url",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationOauthConsentRequest,
+ },
+ ],
+ response: z.object({ consentUrl: z.string() }),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destination_oauths/oauth_params/create",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SetInstancewideDestinationOauthParamsRequestBody,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 400,
+ schema: z.void(),
+ },
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destinations/check_connection",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationIdRequestBody,
+ },
+ ],
+ response: CheckConnectionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destinations/check_connection_for_update",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationUpdate,
+ },
+ ],
+ response: CheckConnectionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destinations/clone",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationCloneRequestBody,
+ },
+ ],
+ response: DestinationRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destinations/create",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationCreate,
+ },
+ ],
+ response: DestinationRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destinations/delete",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationIdRequestBody,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destinations/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationIdRequestBody,
+ },
+ ],
+ response: DestinationRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destinations/list",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceIdRequestBody,
+ },
+ ],
+ response: DestinationReadList,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destinations/search",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationSearch,
+ },
+ ],
+ response: DestinationReadList,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/destinations/update",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationUpdate,
+ },
+ ],
+ response: DestinationRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "get",
+ path: "/v1/health",
+ requestFormat: "json",
+ response: z.object({ available: z.boolean() }),
+ },
+ {
+ method: "post",
+ path: "/v1/jobs/cancel",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: JobIdRequestBody,
+ },
+ ],
+ response: JobInfoRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/jobs/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: JobIdRequestBody,
+ },
+ ],
+ response: JobInfoRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/jobs/get_debug_info",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: JobIdRequestBody,
+ },
+ ],
+ response: JobDebugInfoRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/jobs/get_last_replication_job",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionIdRequestBody,
+ },
+ ],
+ response: JobOptionalRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/jobs/get_light",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: JobIdRequestBody,
+ },
+ ],
+ response: JobInfoLightRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/jobs/get_normalization_status",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: JobIdRequestBody,
+ },
+ ],
+ response: AttemptNormalizationStatusReadList,
+ },
+ {
+ method: "post",
+ path: "/v1/jobs/list",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: JobListRequestBody,
+ },
+ ],
+ response: JobReadList,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/logs/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: LogsRequestBody,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/notifications/try",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: Notification,
+ },
+ ],
+ response: NotificationRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "get",
+ path: "/v1/openapi",
+ requestFormat: "json",
+ response: z.void(),
+ },
+ {
+ method: "post",
+ path: "/v1/operations/check",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: OperatorConfiguration,
+ },
+ ],
+ response: CheckOperationRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/operations/create",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: OperationCreate,
+ },
+ ],
+ response: OperationRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/operations/delete",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: OperationIdRequestBody,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/operations/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: OperationIdRequestBody,
+ },
+ ],
+ response: OperationRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/operations/list",
+ description: `List operations for connection.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionIdRequestBody,
+ },
+ ],
+ response: OperationReadList,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/operations/update",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: OperationUpdate,
+ },
+ ],
+ response: OperationRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/scheduler/destinations/check_connection",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DestinationCoreConfig,
+ },
+ ],
+ response: CheckConnectionRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/scheduler/sources/check_connection",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceCoreConfig,
+ },
+ ],
+ response: CheckConnectionRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/scheduler/sources/discover_schema",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceCoreConfig,
+ },
+ ],
+ response: SourceDiscoverSchemaRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_definition_specifications/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceDefinitionIdWithWorkspaceId,
+ },
+ ],
+ response: SourceDefinitionSpecificationRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/create_custom",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: CustomSourceDefinitionCreate,
+ },
+ ],
+ response: SourceDefinitionRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/delete",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceDefinitionIdRequestBody,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceDefinitionIdRequestBody,
+ },
+ ],
+ response: SourceDefinitionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/get_for_workspace",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceDefinitionIdWithWorkspaceId,
+ },
+ ],
+ response: SourceDefinitionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/grant_definition",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceDefinitionIdWithWorkspaceId,
+ },
+ ],
+ response: PrivateSourceDefinitionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/list",
+ requestFormat: "json",
+ response: SourceDefinitionReadList,
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/list_for_workspace",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceIdRequestBody,
+ },
+ ],
+ response: SourceDefinitionReadList,
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/list_latest",
+ description: `Guaranteed to retrieve the latest information on supported sources.`,
+ requestFormat: "json",
+ response: SourceDefinitionReadList,
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/list_private",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceIdRequestBody,
+ },
+ ],
+ response: PrivateSourceDefinitionReadList,
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/revoke_definition",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceDefinitionIdWithWorkspaceId,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_definitions/update",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceDefinitionUpdate,
+ },
+ ],
+ response: SourceDefinitionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_oauths/complete_oauth",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: CompleteSourceOauthRequest,
+ },
+ ],
+ response: z.object({}).partial().passthrough(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_oauths/get_consent_url",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceOauthConsentRequest,
+ },
+ ],
+ response: z.object({ consentUrl: z.string() }),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/source_oauths/oauth_params/create",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SetInstancewideSourceOauthParamsRequestBody,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 400,
+ schema: z.void(),
+ },
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/check_connection",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceIdRequestBody,
+ },
+ ],
+ response: CheckConnectionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/check_connection_for_update",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceUpdate,
+ },
+ ],
+ response: CheckConnectionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/clone",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceCloneRequestBody,
+ },
+ ],
+ response: SourceRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/create",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceCreate,
+ },
+ ],
+ response: SourceRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/delete",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceIdRequestBody,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/discover_schema",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceDiscoverSchemaRequestBody,
+ },
+ ],
+ response: SourceDiscoverSchemaRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceIdRequestBody,
+ },
+ ],
+ response: SourceRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/list",
+ description: `List sources for workspace. Does not return deleted sources.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceIdRequestBody,
+ },
+ ],
+ response: SourceReadList,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/most_recent_source_actor_catalog",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceIdRequestBody,
+ },
+ ],
+ response: ActorCatalogWithUpdatedAt,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/search",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceSearch,
+ },
+ ],
+ response: SourceReadList,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/update",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceUpdate,
+ },
+ ],
+ response: SourceRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/sources/write_discover_catalog_result",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: SourceDiscoverSchemaWriteRequestBody,
+ },
+ ],
+ response: z.object({ catalogId: z.string().uuid() }),
+ },
+ {
+ method: "post",
+ path: "/v1/state/create_or_update",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionStateCreateOrUpdate,
+ },
+ ],
+ response: ConnectionState,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/state/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionIdRequestBody,
+ },
+ ],
+ response: ConnectionState,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/web_backend/check_updates",
+ requestFormat: "json",
+ response: WebBackendCheckUpdatesRead,
+ },
+ {
+ method: "post",
+ path: "/v1/web_backend/connections/create",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WebBackendConnectionCreate,
+ },
+ ],
+ response: WebBackendConnectionRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/web_backend/connections/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WebBackendConnectionRequestBody,
+ },
+ ],
+ response: WebBackendConnectionRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/web_backend/connections/list",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WebBackendConnectionListRequestBody,
+ },
+ ],
+ response: WebBackendConnectionReadList,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/web_backend/connections/update",
+ description: `Apply a patch-style update to a connection. Only fields present on the update request body will be updated.
+Any operations that lack an ID will be created. Then, the newly created operationId will be applied to the
+connection along with the rest of the operationIds in the request body.
+Apply a patch-style update to a connection. Only fields present on the update request body will be updated.
+Note that if a catalog is present in the request body, the connection's entire catalog will be replaced
+with the catalog from the request. This means that to modify a single stream, the entire new catalog
+containing the updated stream needs to be sent.
+`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WebBackendConnectionUpdate,
+ },
+ ],
+ response: WebBackendConnectionRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/web_backend/geographies/list",
+ description: `Returns all available geographies in which a data sync can run.`,
+ requestFormat: "json",
+ response: WebBackendGeographiesListResult,
+ },
+ {
+ method: "post",
+ path: "/v1/web_backend/state/get_type",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionIdRequestBody,
+ },
+ ],
+ response: z.enum(["global", "stream", "legacy", "not_set"]),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/web_backend/workspace/state",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WebBackendWorkspaceState,
+ },
+ ],
+ response: WebBackendWorkspaceStateResult,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/workspaces/create",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceCreate,
+ },
+ ],
+ response: WorkspaceRead,
+ errors: [
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/workspaces/delete",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceIdRequestBody,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/workspaces/get",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceIdRequestBody,
+ },
+ ],
+ response: WorkspaceRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/workspaces/get_by_connection_id",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ConnectionIdRequestBody,
+ },
+ ],
+ response: WorkspaceRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/workspaces/get_by_slug",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({ slug: z.string() }),
+ },
+ ],
+ response: WorkspaceRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/workspaces/list",
+ requestFormat: "json",
+ response: WorkspaceReadList,
+ },
+ {
+ method: "post",
+ path: "/v1/workspaces/tag_feedback_status_as_done",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceGiveFeedback,
+ },
+ ],
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/workspaces/update",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceUpdate,
+ },
+ ],
+ response: WorkspaceRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+ {
+ method: "post",
+ path: "/v1/workspaces/update_name",
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WorkspaceUpdateName,
+ },
+ ],
+ response: WorkspaceRead,
+ errors: [
+ {
+ status: 404,
+ schema: z.void(),
+ },
+ {
+ status: 422,
+ schema: z.void(),
+ },
+ ],
+ },
+]);
+
+export const api = new ZodiosCore(endpoints);
+const result = api.post("/v1/connections/create", {
+ body: {
+ destinationId: "123",
+ sourceId: "123",
+ status: "active",
+ },
+});
diff --git a/packages/core/examples/aitbytes.ts b/packages/core/examples/aitbytes.ts
new file mode 100644
index 00000000..83db1d60
--- /dev/null
+++ b/packages/core/examples/aitbytes.ts
@@ -0,0 +1,11 @@
+import { api } from "./airbytes-api";
+
+api
+ .post("/v1/connections/list", {
+ body: {
+ workspaceId: "123",
+ },
+ })
+ .then((res) => {
+ console.log(res);
+ });
diff --git a/packages/core/examples/dev.to/api-key-plugin.ts b/packages/core/examples/dev.to/api-key-plugin.ts
new file mode 100644
index 00000000..ba768056
--- /dev/null
+++ b/packages/core/examples/dev.to/api-key-plugin.ts
@@ -0,0 +1,19 @@
+import { ZodiosPlugin } from "../../src/index";
+
+export interface ApiKeyPluginConfig {
+ getApiKey: () => Promise;
+}
+
+export function pluginApiKey(provider: ApiKeyPluginConfig): ZodiosPlugin {
+ return {
+ request: async (_, config) => {
+ return {
+ ...config,
+ headers: {
+ ...config.headers,
+ "api-key": await provider.getApiKey(),
+ },
+ };
+ },
+ };
+}
diff --git a/packages/core/examples/dev.to/articles.ts b/packages/core/examples/dev.to/articles.ts
new file mode 100644
index 00000000..96714c78
--- /dev/null
+++ b/packages/core/examples/dev.to/articles.ts
@@ -0,0 +1,167 @@
+import { apiBuilder, makeApi } from "../../src/index";
+import { z } from "zod";
+import { devUser } from "./users";
+import { paramPages } from "./params";
+
+const devArticle = z.object({
+ id: z.number(),
+ type_of: z.string(),
+ title: z.string(),
+ description: z.string(),
+ cover_image: z.string().or(z.null()),
+ readable_publish_date: z.string().optional(),
+ social_image: z.string().optional(),
+ tag_list: z.array(z.string()).or(z.string()),
+ tags: z.array(z.string()).or(z.string()).optional(),
+ slug: z.string(),
+ path: z.string(),
+ url: z.string(),
+ canonical_url: z.string(),
+ comments_count: z.number(),
+ positive_reactions_count: z.number(),
+ public_reactions_count: z.number(),
+ collection_id: z.number().or(z.null()).optional(),
+ created_at: z.string().optional(),
+ edited_at: z.string().optional(),
+ crossposted_at: z.string().or(z.null()).optional(),
+ published_at: z.string().or(z.null()).optional(),
+ last_comment_at: z.string().optional(),
+ published_timestamp: z.string(),
+ reading_time_minutes: z.number(),
+ user: devUser.partial(),
+ read_time_minutes: z.number().optional(),
+ organization: z
+ .object({
+ name: z.string(),
+ username: z.string(),
+ slug: z.string(),
+ profile_image: z.string(),
+ profile_image_90: z.string(),
+ })
+ .optional(),
+ flare_tag: z
+ .object({
+ name: z.string(),
+ bg_color_hex: z.string(),
+ text_color_hex: z.string(),
+ })
+ .optional(),
+});
+
+const devArticles = z.array(devArticle);
+
+export type Article = z.infer;
+export type Articles = z.infer;
+
+export const articlesApi = apiBuilder({
+ method: "get",
+ path: "/articles",
+ alias: "getAllArticles",
+ description: "Get all articles",
+ parameters: [
+ ...paramPages,
+ {
+ name: "tag",
+ description: "Filter by tag",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "tags",
+ description: "Filter by tags",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "tags_exclude",
+ description: "Exclude tags",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "username",
+ description: "Filter by username",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "state",
+ description: "Filter by state",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "top",
+ type: "Query",
+ schema: z.number().optional(),
+ },
+ {
+ name: "collection_id",
+ type: "Query",
+ schema: z.number().optional(),
+ },
+ ],
+ response: devArticles,
+})
+ .addEndpoint({
+ method: "get",
+ path: "/articles/latest",
+ alias: "getLatestArticle",
+ description: "Get latest articles",
+ parameters: paramPages,
+ response: devArticles,
+ })
+ .addEndpoint({
+ method: "get",
+ path: "/articles/:id",
+ alias: "getArticle",
+ description: "Get an article by id",
+ response: devArticle,
+ })
+ .addEndpoint({
+ method: "put",
+ path: "/articles/:id",
+ alias: "updateArticle",
+ description: "Update an article",
+ response: devArticle,
+ })
+ .addEndpoint({
+ method: "get",
+ path: "/articles/:username/:slug",
+ alias: "getArticleByUsernameAndSlug",
+ description: "Get an article by username and slug",
+ response: devArticle,
+ })
+ .addEndpoint({
+ method: "get",
+ path: "/articles/me",
+ alias: "getMyArticles",
+ description: "Get current user's articles",
+ parameters: paramPages,
+ response: devArticles,
+ })
+ .addEndpoint({
+ method: "get",
+ path: "/articles/me/published",
+ alias: "getMyPublishedArticles",
+ description: "Get current user's published articles",
+ parameters: paramPages,
+ response: devArticles,
+ })
+ .addEndpoint({
+ method: "get",
+ path: "/articles/me/unpublished",
+ alias: "getMyUnpublishedArticles",
+ description: "Get current user's unpublished articles",
+ parameters: paramPages,
+ response: devArticles,
+ })
+ .addEndpoint({
+ method: "get",
+ path: "/articles/me/all",
+ alias: "getAllMyArticles",
+ description: "Get current user's all articles",
+ parameters: paramPages,
+ response: devArticles,
+ })
+ .build();
diff --git a/packages/core/examples/dev.to/comments.ts b/packages/core/examples/dev.to/comments.ts
new file mode 100644
index 00000000..7f749319
--- /dev/null
+++ b/packages/core/examples/dev.to/comments.ts
@@ -0,0 +1,61 @@
+import { makeApi, makeEndpoint } from "../../src/index";
+import { z } from "zod";
+import { devUser, User } from "./users";
+
+/**
+ * zod does not handle recusive well, so we need to manually define the schema
+ */
+export type Comment = {
+ type_of: string;
+ id_code: string;
+ created_at: string;
+ body_html: string;
+ user: User;
+ children: Comment[];
+};
+
+export const devComment: z.ZodSchema = z.lazy(() =>
+ z.object({
+ type_of: z.string(),
+ id_code: z.string(),
+ created_at: z.string(),
+ body_html: z.string(),
+ user: devUser,
+ children: z.array(devComment),
+ })
+);
+export const devComments = z.array(devComment);
+
+export type Comments = z.infer;
+
+const getAllComments = makeEndpoint({
+ method: "get",
+ path: "/comments",
+ alias: "getAllComments",
+ description: "Get all comments",
+ parameters: [
+ {
+ name: "a_id",
+ description: "Article ID",
+ type: "Query",
+ schema: z.number().optional(),
+ },
+ {
+ name: "p_id",
+ description: "Podcast comment ID",
+ type: "Query",
+ schema: z.number().optional(),
+ },
+ ],
+ response: devComments,
+});
+
+const getComment = makeEndpoint({
+ method: "get",
+ path: "/comments/:id",
+ alias: "getComment",
+ description: "Get a comment",
+ response: devComment,
+});
+
+export const commentsApi = makeApi([getAllComments, getComment]);
diff --git a/packages/core/examples/dev.to/example.ts b/packages/core/examples/dev.to/example.ts
new file mode 100644
index 00000000..79c65ef9
--- /dev/null
+++ b/packages/core/examples/dev.to/example.ts
@@ -0,0 +1,27 @@
+import { ZodiosCore } from "../../src";
+import { articlesApi } from "./articles";
+import { commentsApi } from "./comments";
+import { followsApi } from "./follows";
+import { followersApi } from "./followers";
+import { userApi } from "./users";
+import { pluginApiKey } from "./api-key-plugin";
+
+export const devTo = new ZodiosCore("https://dev.to/api", [
+ ...articlesApi,
+ ...commentsApi,
+ ...followsApi,
+ ...followersApi,
+ ...userApi,
+]);
+
+devTo.use(
+ pluginApiKey({
+ getApiKey: async () => "",
+ })
+);
+
+const result = devTo.get("/comments/:id", {
+ params: {
+ id: "7",
+ },
+});
diff --git a/packages/core/examples/dev.to/followers.ts b/packages/core/examples/dev.to/followers.ts
new file mode 100644
index 00000000..db9e7d5b
--- /dev/null
+++ b/packages/core/examples/dev.to/followers.ts
@@ -0,0 +1,33 @@
+import { z } from "zod";
+import { makeApi } from "../../src/index";
+import { paramPages } from "./params";
+
+const devFollower = z.object({
+ type_of: z.string(),
+ created_at: z.string(),
+ id: z.number(),
+ name: z.string(),
+ path: z.string(),
+ username: z.string(),
+ profile_image: z.string(),
+});
+
+const devFollowers = z.array(devFollower);
+
+export const followersApi = makeApi([
+ {
+ method: "get",
+ path: "/followers/users",
+ alias: "getAllFollowers",
+ parameters: [
+ ...paramPages,
+ {
+ name: "sort",
+ description: "Sort by. defaults to created_at",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ ],
+ response: devFollowers,
+ },
+]);
diff --git a/packages/core/examples/dev.to/follows.ts b/packages/core/examples/dev.to/follows.ts
new file mode 100644
index 00000000..3aa7cae6
--- /dev/null
+++ b/packages/core/examples/dev.to/follows.ts
@@ -0,0 +1,23 @@
+import { z } from "zod";
+import { makeApi } from "../../src/index";
+
+export const devFollow = z.object({
+ id: z.number(),
+ name: z.string(),
+ points: z.number(),
+});
+
+export const devFollows = z.array(devFollow);
+
+export type Follow = z.infer;
+export type Follows = z.infer;
+
+export const followsApi = makeApi([
+ {
+ method: "get",
+ path: "/follows/tags",
+ alias: "getAllFollowedTags",
+ description: "Get all followed tags",
+ response: devFollows,
+ },
+]);
diff --git a/packages/core/examples/dev.to/params.ts b/packages/core/examples/dev.to/params.ts
new file mode 100644
index 00000000..c07e5a80
--- /dev/null
+++ b/packages/core/examples/dev.to/params.ts
@@ -0,0 +1,16 @@
+import { z } from "zod";
+import { makeParameters } from "../../src/api";
+
+export const paramPages = makeParameters([
+ {
+ name: "page",
+ type: "Query",
+ description: "Page number",
+ schema: z.number().optional(),
+ },
+ {
+ name: "per_page",
+ type: "Query",
+ schema: z.number().optional(),
+ },
+]);
diff --git a/packages/core/examples/dev.to/users.ts b/packages/core/examples/dev.to/users.ts
new file mode 100644
index 00000000..1c74bc1b
--- /dev/null
+++ b/packages/core/examples/dev.to/users.ts
@@ -0,0 +1,64 @@
+import { z } from "zod";
+import { makeApi } from "../../src/index";
+
+export const devUser = z.object({
+ id: z.number(),
+ type_of: z.string(),
+ name: z.string(),
+ username: z.string(),
+ summary: z.string().or(z.null()),
+ twitter_username: z.string().or(z.null()),
+ github_username: z.string().or(z.null()),
+ website_url: z.string().or(z.null()),
+ location: z.string().or(z.null()),
+ joined_at: z.string(),
+ profile_image: z.string(),
+ profile_image_90: z.string(),
+});
+
+export type User = z.infer;
+
+export const devProfileImage = z.object({
+ type_of: z.string(),
+ image_of: z.string(),
+ profile_image: z.string(),
+ profile_image_90: z.string(),
+});
+
+export type ProfileImage = z.infer;
+
+export const userApi = makeApi([
+ {
+ method: "get",
+ path: "/users/:id",
+ alias: "getUser",
+ description: "Get a user",
+ response: devUser,
+ errors: [
+ {
+ status: "default",
+ description: "Default error",
+ schema: z.object({
+ error: z.object({
+ code: z.string(),
+ message: z.string(),
+ }),
+ }),
+ },
+ ],
+ },
+ {
+ method: "get",
+ path: "/users/me",
+ alias: "getMe",
+ description: "Get current user",
+ response: devUser,
+ },
+ {
+ method: "get",
+ path: "/profile_image/:username",
+ alias: "getProfileImage",
+ description: "Get a user's profile image",
+ response: devProfileImage,
+ },
+]);
diff --git a/packages/core/examples/io-ts-types.ts b/packages/core/examples/io-ts-types.ts
new file mode 100644
index 00000000..41bf3ad8
--- /dev/null
+++ b/packages/core/examples/io-ts-types.ts
@@ -0,0 +1,80 @@
+import {
+ ZodiosCore,
+ makeApi,
+ ApiOf,
+ TypeProviderOf,
+ ioTsTypeProvider,
+} from "../src/index";
+import * as t from "io-ts";
+import { FetcherProviderOf } from "../src/zodios";
+import { mockFetchFactory } from "../src/fetcher-providers/mock-provider";
+
+// you can define schema before declaring the API to get back the type
+
+// you can then get back the types
+type User = t.TypeOf;
+type Users = t.TypeOf;
+
+// you can also predefine your API
+const jsonplaceholderUrl = "https://jsonplaceholder.typicode.com";
+
+const userSchema = t.type({
+ id: t.number,
+ name: t.string,
+});
+
+const usersSchema = t.array(userSchema);
+
+const jsonplaceholderApi = makeApi([
+ {
+ method: "get",
+ path: "/users",
+ alias: "getUsers",
+ description: "Get all users",
+ parameters: [
+ {
+ name: "q",
+ description: "full text search",
+ type: "Query",
+ schema: t.string,
+ },
+ {
+ name: "page",
+ description: "page number",
+ type: "Query",
+ schema: t.union([t.number, t.undefined]),
+ },
+ ],
+ response: usersSchema,
+ },
+ {
+ method: "get",
+ path: "/users/:id",
+ description: "Get a user",
+ response: userSchema,
+ },
+]);
+
+async function bootstrap() {
+ const apiClient = new ZodiosCore(jsonplaceholderUrl, jsonplaceholderApi, {
+ typeProvider: ioTsTypeProvider,
+ fetcherFactory: mockFetchFactory,
+ });
+
+ type Api = ApiOf;
+ // ^?
+ type Provider = TypeProviderOf;
+ // ^?
+ type FetcherProvider = FetcherProviderOf;
+ // ^?
+ const users = await apiClient.get("/users", { queries: { q: "Nicholas" } });
+ // ^?
+ const users2 = await apiClient.getUsers({ queries: { q: "Nicholas" } });
+ // ^?
+ console.log(users);
+ const user = await apiClient.get("/users/:id", { params: { id: 7 } });
+ // ^?
+ console.log(user);
+}
+
+bootstrap();
diff --git a/packages/core/examples/jsonplaceholder.ts b/packages/core/examples/jsonplaceholder.ts
new file mode 100644
index 00000000..401cf085
--- /dev/null
+++ b/packages/core/examples/jsonplaceholder.ts
@@ -0,0 +1,94 @@
+import {
+ ApiOf,
+ ZodiosResponseByAlias,
+ ZodiosHeaderParamsByAlias,
+ ZodiosCore,
+} from "../src/index";
+import { z } from "zod";
+
+async function bootstrap() {
+ const apiClient = new ZodiosCore("https://jsonplaceholder.typicode.com", [
+ {
+ method: "get",
+ path: "/users",
+ alias: "getUsers",
+ description: "Get all users",
+ parameters: [
+ {
+ name: "q",
+ type: "Query",
+ schema: z.string(),
+ },
+ {
+ name: "page",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ ],
+ response: z.array(z.object({ id: z.number(), name: z.string() })),
+ },
+ {
+ method: "get",
+ path: "/users/:id",
+ alias: "getUser",
+ description: "Get a user",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ {
+ method: "delete",
+ path: "/users/:id",
+ alias: "deleteUser",
+ description: "Delete a user",
+ response: z.object({}),
+ },
+ {
+ method: "post",
+ path: "/users",
+ alias: "createUser",
+ description: "Create a user",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({ name: z.string() }),
+ },
+ {
+ name: "Content-Type",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: z.object({ id: z.number(), name: z.string() }),
+ },
+ ]);
+
+ type UserResponseAlias = ZodiosResponseByAlias<
+ ApiOf,
+ "getUsers"
+ >;
+
+ type Test = ZodiosHeaderParamsByAlias, "createUser">;
+
+ const users: UserResponseAlias = await apiClient.getUsers({
+ queries: { q: "Nicholas" },
+ });
+ console.log(users);
+ const user = await apiClient.getUser({ params: { id: 7 } });
+ console.log(user);
+ const createdUser = await apiClient.createUser({
+ body: { name: "john doe" },
+ headers: {
+ "Content-Type": "application/json",
+ },
+ });
+ console.log(createdUser);
+ const deletedUser = await apiClient.deleteUser({
+ params: { id: 7 },
+ });
+ console.log(deletedUser);
+}
+
+bootstrap();
diff --git a/packages/core/examples/large-api.ts b/packages/core/examples/large-api.ts
new file mode 100644
index 00000000..3375ac6b
--- /dev/null
+++ b/packages/core/examples/large-api.ts
@@ -0,0 +1,4914 @@
+import { makeApi, ZodiosCore, type ZodiosOptions } from "../src";
+import { z } from "zod";
+
+const CategoryEnum = z.enum([
+ "hris",
+ "ats",
+ "accounting",
+ "ticketing",
+ "crm",
+ "mktg",
+ "filestorage",
+]);
+const AccountDetails = z
+ .object({
+ id: z.string().uuid(),
+ integration: z.string(),
+ integration_slug: z.string(),
+ category: CategoryEnum.nullable(),
+ end_user_origin_id: z.string(),
+ end_user_organization_name: z.string(),
+ end_user_email_address: z.string().email(),
+ status: z.string(),
+ webhook_listener_url: z.string().url(),
+ is_duplicate: z.boolean().nullable(),
+ })
+ .partial();
+const CategoriesEnum = z.enum([
+ "hris",
+ "ats",
+ "accounting",
+ "ticketing",
+ "crm",
+ "mktg",
+ "filestorage",
+]);
+const AccountIntegration = z.object({
+ name: z.string(),
+ categories: z.array(CategoriesEnum).optional(),
+ image: z.string().url().nullish(),
+ square_image: z.string().url().nullish(),
+ color: z
+ .string()
+ .max(18)
+ .regex(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)
+ .optional(),
+ slug: z.string().optional(),
+});
+const AccountToken = z.object({
+ account_token: z.string(),
+ integration: AccountIntegration,
+});
+const ClassificationEnum = z.enum([
+ "ASSET",
+ "EQUITY",
+ "EXPENSE",
+ "LIABILITY",
+ "REVENUE",
+]);
+const AccountStatusEnum = z.enum(["ACTIVE", "PENDING", "INACTIVE"]);
+const CurrencyEnum = z.enum([
+ "XUA",
+ "AFN",
+ "AFA",
+ "ALL",
+ "ALK",
+ "DZD",
+ "ADP",
+ "AOA",
+ "AOK",
+ "AON",
+ "AOR",
+ "ARA",
+ "ARS",
+ "ARM",
+ "ARP",
+ "ARL",
+ "AMD",
+ "AWG",
+ "AUD",
+ "ATS",
+ "AZN",
+ "AZM",
+ "BSD",
+ "BHD",
+ "BDT",
+ "BBD",
+ "BYN",
+ "BYB",
+ "BYR",
+ "BEF",
+ "BEC",
+ "BEL",
+ "BZD",
+ "BMD",
+ "BTN",
+ "BOB",
+ "BOL",
+ "BOV",
+ "BOP",
+ "BAM",
+ "BAD",
+ "BAN",
+ "BWP",
+ "BRC",
+ "BRZ",
+ "BRE",
+ "BRR",
+ "BRN",
+ "BRB",
+ "BRL",
+ "GBP",
+ "BND",
+ "BGL",
+ "BGN",
+ "BGO",
+ "BGM",
+ "BUK",
+ "BIF",
+ "XPF",
+ "KHR",
+ "CAD",
+ "CVE",
+ "KYD",
+ "XAF",
+ "CLE",
+ "CLP",
+ "CLF",
+ "CNX",
+ "CNY",
+ "CNH",
+ "COP",
+ "COU",
+ "KMF",
+ "CDF",
+ "CRC",
+ "HRD",
+ "HRK",
+ "CUC",
+ "CUP",
+ "CYP",
+ "CZK",
+ "CSK",
+ "DKK",
+ "DJF",
+ "DOP",
+ "NLG",
+ "XCD",
+ "DDM",
+ "ECS",
+ "ECV",
+ "EGP",
+ "GQE",
+ "ERN",
+ "EEK",
+ "ETB",
+ "EUR",
+ "XBA",
+ "XEU",
+ "XBB",
+ "XBC",
+ "XBD",
+ "FKP",
+ "FJD",
+ "FIM",
+ "FRF",
+ "XFO",
+ "XFU",
+ "GMD",
+ "GEK",
+ "GEL",
+ "DEM",
+ "GHS",
+ "GHC",
+ "GIP",
+ "XAU",
+ "GRD",
+ "GTQ",
+ "GWP",
+ "GNF",
+ "GNS",
+ "GYD",
+ "HTG",
+ "HNL",
+ "HKD",
+ "HUF",
+ "IMP",
+ "ISK",
+ "ISJ",
+ "INR",
+ "IDR",
+ "IRR",
+ "IQD",
+ "IEP",
+ "ILS",
+ "ILP",
+ "ILR",
+ "ITL",
+ "JMD",
+ "JPY",
+ "JOD",
+ "KZT",
+ "KES",
+ "KWD",
+ "KGS",
+ "LAK",
+ "LVL",
+ "LVR",
+ "LBP",
+ "LSL",
+ "LRD",
+ "LYD",
+ "LTL",
+ "LTT",
+ "LUL",
+ "LUC",
+ "LUF",
+ "MOP",
+ "MKD",
+ "MKN",
+ "MGA",
+ "MGF",
+ "MWK",
+ "MYR",
+ "MVR",
+ "MVP",
+ "MLF",
+ "MTL",
+ "MTP",
+ "MRU",
+ "MRO",
+ "MUR",
+ "MXV",
+ "MXN",
+ "MXP",
+ "MDC",
+ "MDL",
+ "MCF",
+ "MNT",
+ "MAD",
+ "MAF",
+ "MZE",
+ "MZN",
+ "MZM",
+ "MMK",
+ "NAD",
+ "NPR",
+ "ANG",
+ "TWD",
+ "NZD",
+ "NIO",
+ "NIC",
+ "NGN",
+ "KPW",
+ "NOK",
+ "OMR",
+ "PKR",
+ "XPD",
+ "PAB",
+ "PGK",
+ "PYG",
+ "PEI",
+ "PEN",
+ "PES",
+ "PHP",
+ "XPT",
+ "PLN",
+ "PLZ",
+ "PTE",
+ "GWE",
+ "QAR",
+ "XRE",
+ "RHD",
+ "RON",
+ "ROL",
+ "RUB",
+ "RUR",
+ "RWF",
+ "SVC",
+ "WST",
+ "SAR",
+ "RSD",
+ "CSD",
+ "SCR",
+ "SLL",
+ "XAG",
+ "SGD",
+ "SKK",
+ "SIT",
+ "SBD",
+ "SOS",
+ "ZAR",
+ "ZAL",
+ "KRH",
+ "KRW",
+ "KRO",
+ "SSP",
+ "SUR",
+ "ESP",
+ "ESA",
+ "ESB",
+ "XDR",
+ "LKR",
+ "SHP",
+ "XSU",
+ "SDD",
+ "SDG",
+ "SDP",
+ "SRD",
+ "SRG",
+ "SZL",
+ "SEK",
+ "CHF",
+ "SYP",
+ "STN",
+ "STD",
+ "TVD",
+ "TJR",
+ "TJS",
+ "TZS",
+ "XTS",
+ "THB",
+ "XXX",
+ "TPE",
+ "TOP",
+ "TTD",
+ "TND",
+ "TRY",
+ "TRL",
+ "TMT",
+ "TMM",
+ "USD",
+ "USN",
+ "USS",
+ "UGX",
+ "UGS",
+ "UAH",
+ "UAK",
+ "AED",
+ "UYW",
+ "UYU",
+ "UYP",
+ "UYI",
+ "UZS",
+ "VUV",
+ "VES",
+ "VEB",
+ "VEF",
+ "VND",
+ "VNN",
+ "CHE",
+ "CHW",
+ "XOF",
+ "YDD",
+ "YER",
+ "YUN",
+ "YUD",
+ "YUM",
+ "YUR",
+ "ZWN",
+ "ZRN",
+ "ZRZ",
+ "ZMW",
+ "ZMK",
+ "ZWD",
+ "ZWR",
+ "ZWL",
+]);
+const RemoteData = z.object({
+ path: z.string(),
+ data: z.object({}).partial().passthrough().optional(),
+});
+const Account = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ name: z.string().nullable(),
+ description: z.string().nullable(),
+ classification: ClassificationEnum.nullable(),
+ type: z.string().nullable(),
+ status: AccountStatusEnum.nullable(),
+ current_balance: z.number().nullable(),
+ currency: CurrencyEnum.nullable(),
+ account_number: z.string().nullable(),
+ parent_account: z.string().uuid().nullable(),
+ company: z.string().uuid().nullable(),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedAccountList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(Account),
+ })
+ .partial();
+const AccountRequest = z
+ .object({
+ name: z.string().nullable(),
+ description: z.string().nullable(),
+ classification: ClassificationEnum.nullable(),
+ type: z.string().nullable(),
+ status: AccountStatusEnum.nullable(),
+ current_balance: z.number().nullable(),
+ currency: CurrencyEnum.nullable(),
+ account_number: z.string().nullable(),
+ parent_account: z.string().uuid().nullable(),
+ company: z.string().uuid().nullable(),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const AccountEndpointRequest = z.object({ model: AccountRequest });
+const ValidationProblemSource = z.object({ pointer: z.string() });
+const WarningValidationProblem = z.object({
+ source: ValidationProblemSource.optional(),
+ title: z.string(),
+ detail: z.string(),
+ problem_type: z.string(),
+});
+const ErrorValidationProblem = z.object({
+ source: ValidationProblemSource.optional(),
+ title: z.string(),
+ detail: z.string(),
+ problem_type: z.string(),
+});
+const DebugModelLogSummary = z.object({
+ url: z.string(),
+ method: z.string(),
+ status_code: z.number().int(),
+});
+const DebugModeLog = z.object({
+ log_id: z.string(),
+ dashboard_view: z.string(),
+ log_summary: DebugModelLogSummary,
+});
+const AccountResponse = z.object({
+ model: Account,
+ warnings: z.array(WarningValidationProblem),
+ errors: z.array(ErrorValidationProblem),
+ logs: z.array(DebugModeLog).optional(),
+});
+const LinkedAccountStatus = z.object({
+ linked_account_status: z.string(),
+ can_make_request: z.boolean(),
+});
+const MetaResponse = z.object({
+ request_schema: z.object({}).partial().passthrough(),
+ remote_field_classes: z.object({}).partial().passthrough().optional(),
+ status: LinkedAccountStatus.optional(),
+ has_conditional_params: z.boolean(),
+ has_required_linked_account_params: z.boolean(),
+});
+const AddressTypeEnum = z.enum(["BILLING", "SHIPPING"]);
+const CountryEnum = z.enum([
+ "AF",
+ "AX",
+ "AL",
+ "DZ",
+ "AS",
+ "AD",
+ "AO",
+ "AI",
+ "AQ",
+ "AG",
+ "AR",
+ "AM",
+ "AW",
+ "AU",
+ "AT",
+ "AZ",
+ "BS",
+ "BH",
+ "BD",
+ "BB",
+ "BY",
+ "BE",
+ "BZ",
+ "BJ",
+ "BM",
+ "BT",
+ "BO",
+ "BQ",
+ "BA",
+ "BW",
+ "BV",
+ "BR",
+ "IO",
+ "BN",
+ "BG",
+ "BF",
+ "BI",
+ "CV",
+ "KH",
+ "CM",
+ "CA",
+ "KY",
+ "CF",
+ "TD",
+ "CL",
+ "CN",
+ "CX",
+ "CC",
+ "CO",
+ "KM",
+ "CG",
+ "CD",
+ "CK",
+ "CR",
+ "CI",
+ "HR",
+ "CU",
+ "CW",
+ "CY",
+ "CZ",
+ "DK",
+ "DJ",
+ "DM",
+ "DO",
+ "EC",
+ "EG",
+ "SV",
+ "GQ",
+ "ER",
+ "EE",
+ "SZ",
+ "ET",
+ "FK",
+ "FO",
+ "FJ",
+ "FI",
+ "FR",
+ "GF",
+ "PF",
+ "TF",
+ "GA",
+ "GM",
+ "GE",
+ "DE",
+ "GH",
+ "GI",
+ "GR",
+ "GL",
+ "GD",
+ "GP",
+ "GU",
+ "GT",
+ "GG",
+ "GN",
+ "GW",
+ "GY",
+ "HT",
+ "HM",
+ "VA",
+ "HN",
+ "HK",
+ "HU",
+ "IS",
+ "IN",
+ "ID",
+ "IR",
+ "IQ",
+ "IE",
+ "IM",
+ "IL",
+ "IT",
+ "JM",
+ "JP",
+ "JE",
+ "JO",
+ "KZ",
+ "KE",
+ "KI",
+ "KW",
+ "KG",
+ "LA",
+ "LV",
+ "LB",
+ "LS",
+ "LR",
+ "LY",
+ "LI",
+ "LT",
+ "LU",
+ "MO",
+ "MG",
+ "MW",
+ "MY",
+ "MV",
+ "ML",
+ "MT",
+ "MH",
+ "MQ",
+ "MR",
+ "MU",
+ "YT",
+ "MX",
+ "FM",
+ "MD",
+ "MC",
+ "MN",
+ "ME",
+ "MS",
+ "MA",
+ "MZ",
+ "MM",
+ "NA",
+ "NR",
+ "NP",
+ "NL",
+ "NC",
+ "NZ",
+ "NI",
+ "NE",
+ "NG",
+ "NU",
+ "NF",
+ "KP",
+ "MK",
+ "MP",
+ "NO",
+ "OM",
+ "PK",
+ "PW",
+ "PS",
+ "PA",
+ "PG",
+ "PY",
+ "PE",
+ "PH",
+ "PN",
+ "PL",
+ "PT",
+ "PR",
+ "QA",
+ "RE",
+ "RO",
+ "RU",
+ "RW",
+ "BL",
+ "SH",
+ "KN",
+ "LC",
+ "MF",
+ "PM",
+ "VC",
+ "WS",
+ "SM",
+ "ST",
+ "SA",
+ "SN",
+ "RS",
+ "SC",
+ "SL",
+ "SG",
+ "SX",
+ "SK",
+ "SI",
+ "SB",
+ "SO",
+ "ZA",
+ "GS",
+ "KR",
+ "SS",
+ "ES",
+ "LK",
+ "SD",
+ "SR",
+ "SJ",
+ "SE",
+ "CH",
+ "SY",
+ "TW",
+ "TJ",
+ "TZ",
+ "TH",
+ "TL",
+ "TG",
+ "TK",
+ "TO",
+ "TT",
+ "TN",
+ "TR",
+ "TM",
+ "TC",
+ "TV",
+ "UG",
+ "UA",
+ "AE",
+ "GB",
+ "UM",
+ "US",
+ "UY",
+ "UZ",
+ "VU",
+ "VE",
+ "VN",
+ "VG",
+ "VI",
+ "WF",
+ "EH",
+ "YE",
+ "ZM",
+ "ZW",
+]);
+const Address = z
+ .object({
+ type: AddressTypeEnum.nullable(),
+ street_1: z.string().nullable(),
+ street_2: z.string().nullable(),
+ city: z.string().nullable(),
+ state: z.unknown().nullable(),
+ country_subdivision: z.string().nullable(),
+ country: CountryEnum.nullable(),
+ zip_code: z.string().nullable(),
+ })
+ .partial();
+const AccountingAttachment = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ file_name: z.string().nullable(),
+ file_url: z.string().max(2000).url().nullable(),
+ company: z.string().uuid().nullable(),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedAccountingAttachmentList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(AccountingAttachment),
+ })
+ .partial();
+const AccountingAttachmentRequest = z
+ .object({
+ file_name: z.string().nullable(),
+ file_url: z.string().max(2000).url().nullable(),
+ company: z.string().uuid().nullable(),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const AccountingAttachmentEndpointRequest = z.object({
+ model: AccountingAttachmentRequest,
+});
+const AccountingAttachmentResponse = z.object({
+ model: AccountingAttachment,
+ warnings: z.array(WarningValidationProblem),
+ errors: z.array(ErrorValidationProblem),
+ logs: z.array(DebugModeLog).optional(),
+});
+const ModelOperation = z.object({
+ model_name: z.string(),
+ available_operations: z.array(z.string()),
+ required_post_parameters: z.array(z.string()),
+ supported_fields: z.array(z.string()),
+});
+const AvailableActions = z.object({
+ integration: AccountIntegration,
+ passthrough_available: z.boolean(),
+ available_model_operations: z.array(ModelOperation).optional(),
+});
+const ReportItem = z
+ .object({
+ remote_id: z.string().nullable(),
+ name: z.string().nullable(),
+ value: z.number().nullable(),
+ sub_items: z.object({}).partial().passthrough(),
+ company: z.string().uuid().nullable(),
+ })
+ .partial();
+const BalanceSheet = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ name: z.string().nullable(),
+ currency: CurrencyEnum.nullable(),
+ company: z.string().uuid().nullable(),
+ date: z.string().datetime().nullable(),
+ net_assets: z.number().nullable(),
+ assets: z.array(ReportItem),
+ liabilities: z.array(ReportItem),
+ equity: z.array(ReportItem),
+ remote_generated_at: z.string().datetime().nullable(),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedBalanceSheetList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(BalanceSheet),
+ })
+ .partial();
+const CashFlowStatement = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ name: z.string().nullable(),
+ currency: CurrencyEnum.nullable(),
+ company: z.string().uuid().nullable(),
+ start_period: z.string().datetime().nullable(),
+ end_period: z.string().datetime().nullable(),
+ cash_at_beginning_of_period: z.number().nullable(),
+ cash_at_end_of_period: z.number().nullable(),
+ operating_activities: z.array(ReportItem),
+ investing_activities: z.array(ReportItem),
+ financing_activities: z.array(ReportItem),
+ remote_generated_at: z.string().datetime().nullable(),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedCashFlowStatementList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(CashFlowStatement),
+ })
+ .partial();
+const CommonModelScopesDisabledModelsEnabledActionsEnum = z.enum([
+ "ENABLED_ACTION_READ",
+ "ENABLED_ACTION_WRITE",
+]);
+const CommonModelScopesDisabledModels = z.object({
+ model_name: z.string(),
+ model_id: z.string(),
+ enabled_actions: z.array(CommonModelScopesDisabledModelsEnabledActionsEnum),
+ is_disabled: z.boolean(),
+ disabled_fields: z.array(z.string()),
+});
+const CommonModelScopeData = z.object({
+ common_models: z.array(CommonModelScopesDisabledModels),
+ linked_account_id: z.string().uuid().optional(),
+});
+const CommonModelScopes = z.object({
+ organization_level_scopes: CommonModelScopeData.optional(),
+ scope_overrides: z.array(CommonModelScopeData),
+});
+const EnabledActionsEnum = z.enum(["READ", "WRITE"]);
+const CommonModelScopesPostInnerDeserializerRequest = z.object({
+ model_id: z.string().min(1),
+ enabled_actions: z.array(EnabledActionsEnum),
+ disabled_fields: z.array(z.string()),
+});
+const CommonModelScopesUpdateSerializer = z.object({
+ common_models: z.array(CommonModelScopesPostInnerDeserializerRequest),
+});
+const AccountingPhoneNumber = z
+ .object({ number: z.string().nullable(), type: z.string().nullable() })
+ .partial();
+const CompanyInfo = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ name: z.string().nullable(),
+ legal_name: z.string().nullable(),
+ tax_number: z.string().nullable(),
+ fiscal_year_end_month: z.number().int().gte(1).lte(12).nullable(),
+ fiscal_year_end_day: z.number().int().gte(1).lte(31).nullable(),
+ currency: CurrencyEnum.nullable(),
+ remote_created_at: z.string().datetime().nullable(),
+ urls: z.array(z.string()).nullable(),
+ addresses: z.array(Address),
+ phone_numbers: z.array(AccountingPhoneNumber),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedCompanyInfoList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(CompanyInfo),
+ })
+ .partial();
+const Status7d1Enum = z.enum(["ACTIVE", "ARCHIVED"]);
+const Contact = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ name: z.string().nullable(),
+ is_supplier: z.boolean().nullable(),
+ is_customer: z.boolean().nullable(),
+ email_address: z.string().nullable(),
+ tax_number: z.string().nullable(),
+ status: Status7d1Enum.nullable(),
+ currency: z.string().nullable(),
+ remote_updated_at: z.string().datetime().nullable(),
+ company: z.string().uuid().nullable(),
+ addresses: z.array(z.string()),
+ phone_numbers: z.array(AccountingPhoneNumber),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedContactList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(Contact),
+ })
+ .partial();
+const AccountingPhoneNumberRequest = z
+ .object({
+ number: z.string().nullable(),
+ type: z.string().nullable(),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const ContactRequest = z
+ .object({
+ name: z.string().nullable(),
+ is_supplier: z.boolean().nullable(),
+ is_customer: z.boolean().nullable(),
+ email_address: z.string().nullable(),
+ tax_number: z.string().nullable(),
+ status: Status7d1Enum.nullable(),
+ currency: z.string().nullable(),
+ company: z.string().uuid().nullable(),
+ addresses: z.array(z.string()),
+ phone_numbers: z.array(AccountingPhoneNumberRequest),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const ContactEndpointRequest = z.object({ model: ContactRequest });
+const ContactResponse = z.object({
+ model: Contact,
+ warnings: z.array(WarningValidationProblem),
+ errors: z.array(ErrorValidationProblem),
+ logs: z.array(DebugModeLog).optional(),
+});
+const CreditNoteStatusEnum = z.enum(["SUBMITTED", "AUTHORIZED", "PAID"]);
+const CreditNoteLineItem = z.object({
+ item: z.string().uuid().nullish(),
+ name: z.string().nullish(),
+ description: z.string().nullish(),
+ quantity: z
+ .string()
+ .regex(/^-?\d{0,24}(?:\.\d{0,8})?$/)
+ .nullish(),
+ memo: z.string().nullish(),
+ unit_price: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ tax_rate: z.string().uuid().nullish(),
+ total_line_amount: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ tracking_category: z.string().uuid().nullish(),
+ tracking_categories: z.array(z.string()),
+ account: z.string().uuid().nullish(),
+ company: z.string().uuid().nullish(),
+ remote_id: z.string().nullish(),
+});
+const CreditNote = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ transaction_date: z.string().datetime().nullable(),
+ status: CreditNoteStatusEnum.nullable(),
+ number: z.string().nullable(),
+ contact: z.string().uuid().nullable(),
+ company: z.string().uuid().nullable(),
+ total_amount: z.number().nullable(),
+ remaining_credit: z.number().nullable(),
+ line_items: z.array(CreditNoteLineItem),
+ currency: CurrencyEnum.nullable(),
+ remote_created_at: z.string().datetime().nullable(),
+ remote_updated_at: z.string().datetime().nullable(),
+ payments: z.array(z.string()),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedCreditNoteList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(CreditNote),
+ })
+ .partial();
+const ExpenseLine = z
+ .object({
+ remote_id: z.string().nullable(),
+ item: z.string().uuid().nullable(),
+ net_amount: z.number().nullable(),
+ tracking_category: z.string().uuid().nullable(),
+ tracking_categories: z.array(z.string()),
+ company: z.string().uuid().nullable(),
+ account: z.string().uuid().nullable(),
+ contact: z.string().uuid().nullable(),
+ description: z.string().nullable(),
+ })
+ .partial();
+const Expense = z
+ .object({
+ transaction_date: z.string().datetime().nullable(),
+ remote_created_at: z.string().datetime().nullable(),
+ account: z.string().uuid().nullable(),
+ contact: z.string().uuid().nullable(),
+ total_amount: z.number().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ company: z.string().uuid().nullable(),
+ memo: z.string().nullable(),
+ lines: z.array(ExpenseLine),
+ remote_was_deleted: z.boolean(),
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedExpenseList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(Expense),
+ })
+ .partial();
+const ExpenseLineRequest = z
+ .object({
+ remote_id: z.string().nullable(),
+ item: z.string().uuid().nullable(),
+ net_amount: z.number().nullable(),
+ tracking_category: z.string().uuid().nullable(),
+ tracking_categories: z.array(z.string()),
+ company: z.string().uuid().nullable(),
+ account: z.string().uuid().nullable(),
+ contact: z.string().uuid().nullable(),
+ description: z.string().nullable(),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const ExpenseRequest = z
+ .object({
+ transaction_date: z.string().datetime().nullable(),
+ account: z.string().uuid().nullable(),
+ contact: z.string().uuid().nullable(),
+ total_amount: z.number().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ company: z.string().uuid().nullable(),
+ memo: z.string().nullable(),
+ lines: z.array(ExpenseLineRequest),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const ExpenseEndpointRequest = z.object({ model: ExpenseRequest });
+const ExpenseResponse = z.object({
+ model: Expense,
+ warnings: z.array(WarningValidationProblem),
+ errors: z.array(ErrorValidationProblem),
+ logs: z.array(DebugModeLog).optional(),
+});
+const GenerateRemoteKeyRequest = z.object({ name: z.string().min(1) });
+const RemoteKey = z.object({ name: z.string(), key: z.string() });
+const IncomeStatement = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ name: z.string().nullable(),
+ currency: CurrencyEnum.nullable(),
+ company: z.string().uuid().nullable(),
+ start_period: z.string().datetime().nullable(),
+ end_period: z.string().datetime().nullable(),
+ income: z.array(ReportItem),
+ cost_of_sales: z.array(ReportItem),
+ gross_profit: z.number().nullable(),
+ operating_expenses: z.array(ReportItem),
+ net_operating_income: z.number().nullable(),
+ non_operating_expenses: z.array(ReportItem),
+ net_income: z.number().nullable(),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedIncomeStatementList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(IncomeStatement),
+ })
+ .partial();
+const InvoiceTypeEnum = z.enum(["ACCOUNTS_RECEIVABLE", "ACCOUNTS_PAYABLE"]);
+const InvoiceLineItem = z
+ .object({
+ remote_id: z.string().nullable(),
+ description: z.string().nullable(),
+ unit_price: z.number().nullable(),
+ quantity: z.number().nullable(),
+ total_amount: z.number().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ item: z.string().uuid().nullable(),
+ account: z.string().uuid().nullable(),
+ tracking_category: z.string().uuid().nullable(),
+ tracking_categories: z.array(z.string()),
+ company: z.string().uuid().nullable(),
+ id: z.string().uuid(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const Invoice = z
+ .object({
+ type: InvoiceTypeEnum.nullable(),
+ contact: z.string().uuid().nullable(),
+ number: z.string().nullable(),
+ issue_date: z.string().datetime().nullable(),
+ due_date: z.string().datetime().nullable(),
+ paid_on_date: z.string().datetime().nullable(),
+ memo: z.string().nullable(),
+ company: z.string().uuid().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ total_discount: z.number().nullable(),
+ sub_total: z.number().nullable(),
+ total_tax_amount: z.number().nullable(),
+ total_amount: z.number().nullable(),
+ balance: z.number().nullable(),
+ remote_updated_at: z.string().datetime().nullable(),
+ payments: z.array(z.string()),
+ line_items: z.array(InvoiceLineItem),
+ remote_was_deleted: z.boolean(),
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedInvoiceList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(Invoice),
+ })
+ .partial();
+const InvoiceLineItemRequest = z
+ .object({
+ remote_id: z.string().nullable(),
+ description: z.string().nullable(),
+ unit_price: z.number().nullable(),
+ quantity: z.number().nullable(),
+ total_amount: z.number().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ item: z.string().uuid().nullable(),
+ account: z.string().uuid().nullable(),
+ tracking_category: z.string().uuid().nullable(),
+ tracking_categories: z.array(z.string()),
+ company: z.string().uuid().nullable(),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const InvoiceRequest = z
+ .object({
+ type: InvoiceTypeEnum.nullable(),
+ contact: z.string().uuid().nullable(),
+ number: z.string().nullable(),
+ issue_date: z.string().datetime().nullable(),
+ due_date: z.string().datetime().nullable(),
+ paid_on_date: z.string().datetime().nullable(),
+ memo: z.string().nullable(),
+ company: z.string().uuid().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ total_discount: z.number().nullable(),
+ sub_total: z.number().nullable(),
+ total_tax_amount: z.number().nullable(),
+ total_amount: z.number().nullable(),
+ balance: z.number().nullable(),
+ payments: z.array(z.string()),
+ line_items: z.array(InvoiceLineItemRequest),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const InvoiceEndpointRequest = z.object({ model: InvoiceRequest });
+const InvoiceResponse = z.object({
+ model: Invoice,
+ warnings: z.array(WarningValidationProblem),
+ errors: z.array(ErrorValidationProblem),
+ logs: z.array(DebugModeLog).optional(),
+});
+const IssueStatusEnum = z.enum(["ONGOING", "RESOLVED"]);
+const Issue = z.object({
+ id: z.string().uuid().optional(),
+ status: IssueStatusEnum.optional(),
+ error_description: z.string(),
+ end_user: z.object({}).partial().passthrough().optional(),
+ first_incident_time: z.string().datetime().nullish(),
+ last_incident_time: z.string().datetime().nullish(),
+ is_muted: z.boolean().optional(),
+ error_details: z.array(z.string()).optional(),
+});
+const PaginatedIssueList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(Issue),
+ })
+ .partial();
+const Item = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ name: z.string().nullable(),
+ status: Status7d1Enum.nullable(),
+ unit_price: z.number().nullable(),
+ purchase_price: z.number().nullable(),
+ purchase_account: z.string().uuid().nullable(),
+ sales_account: z.string().uuid().nullable(),
+ company: z.string().uuid().nullable(),
+ remote_updated_at: z.string().datetime().nullable(),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedItemList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(Item),
+ })
+ .partial();
+const JournalLine = z
+ .object({
+ remote_id: z.string().nullable(),
+ account: z.string().uuid().nullable(),
+ net_amount: z.number().nullable(),
+ tracking_category: z.string().uuid().nullable(),
+ tracking_categories: z.array(z.string()),
+ contact: z.string().uuid().nullable(),
+ description: z.string().nullable(),
+ })
+ .partial();
+const PostingStatusEnum = z.enum(["UNPOSTED", "POSTED"]);
+const JournalEntry = z
+ .object({
+ transaction_date: z.string().datetime().nullable(),
+ remote_created_at: z.string().datetime().nullable(),
+ remote_updated_at: z.string().datetime().nullable(),
+ payments: z.array(z.string()),
+ memo: z.string().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ company: z.string().uuid().nullable(),
+ lines: z.array(JournalLine),
+ remote_was_deleted: z.boolean(),
+ posting_status: PostingStatusEnum.nullable(),
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedJournalEntryList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(JournalEntry),
+ })
+ .partial();
+const JournalLineRequest = z
+ .object({
+ remote_id: z.string().nullable(),
+ account: z.string().uuid().nullable(),
+ net_amount: z.number().nullable(),
+ tracking_category: z.string().uuid().nullable(),
+ tracking_categories: z.array(z.string()),
+ contact: z.string().uuid().nullable(),
+ description: z.string().nullable(),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const JournalEntryRequest = z
+ .object({
+ transaction_date: z.string().datetime().nullable(),
+ payments: z.array(z.string()),
+ memo: z.string().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ company: z.string().uuid().nullable(),
+ lines: z.array(JournalLineRequest),
+ posting_status: PostingStatusEnum.nullable(),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const JournalEntryEndpointRequest = z.object({ model: JournalEntryRequest });
+const JournalEntryResponse = z.object({
+ model: JournalEntry,
+ warnings: z.array(WarningValidationProblem),
+ errors: z.array(ErrorValidationProblem),
+ logs: z.array(DebugModeLog).optional(),
+});
+const CommonModelScopesBodyRequest = z.object({
+ model_id: z.string().min(1),
+ enabled_actions: z.array(EnabledActionsEnum),
+ disabled_fields: z.array(z.string()),
+});
+const EndUserDetailsRequest = z.object({
+ end_user_email_address: z.string().min(1).max(100),
+ end_user_organization_name: z.string().min(1).max(100),
+ end_user_origin_id: z.string().min(1).max(100),
+ categories: z.array(CategoriesEnum),
+ integration: z.string().min(1).nullish(),
+ link_expiry_mins: z.number().int().gte(30).lte(10080).optional().default(30),
+ should_create_magic_link_url: z.boolean().nullish(),
+ common_models: z.array(CommonModelScopesBodyRequest).nullish(),
+});
+const LinkToken = z.object({
+ link_token: z.string(),
+ integration_name: z.string().optional(),
+ magic_link_url: z.string().optional(),
+});
+const AccountDetailsAndActionsStatusEnum = z.enum([
+ "COMPLETE",
+ "INCOMPLETE",
+ "RELINK_NEEDED",
+]);
+const AccountDetailsAndActionsIntegration = z.object({
+ name: z.string(),
+ categories: z.array(CategoriesEnum),
+ image: z.string().optional(),
+ square_image: z.string().optional(),
+ color: z.string(),
+ slug: z.string(),
+ passthrough_available: z.boolean(),
+ available_model_operations: z.array(ModelOperation).optional(),
+});
+const AccountDetailsAndActions = z.object({
+ id: z.string(),
+ category: CategoryEnum.optional(),
+ status: AccountDetailsAndActionsStatusEnum,
+ status_detail: z.string().optional(),
+ end_user_origin_id: z.string().optional(),
+ end_user_organization_name: z.string(),
+ end_user_email_address: z.string(),
+ webhook_listener_url: z.string(),
+ is_duplicate: z.boolean().nullish(),
+ integration: AccountDetailsAndActionsIntegration.optional(),
+});
+const PaginatedAccountDetailsAndActionsList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(AccountDetailsAndActions),
+ })
+ .partial();
+const MethodEnum = z.enum([
+ "GET",
+ "OPTIONS",
+ "HEAD",
+ "POST",
+ "PUT",
+ "PATCH",
+ "DELETE",
+]);
+const EncodingEnum = z.enum(["RAW", "BASE64", "GZIP_BASE64"]);
+const MultipartFormFieldRequest = z.object({
+ name: z.string().min(1),
+ data: z.string().min(1),
+ encoding: EncodingEnum.nullish().default("RAW"),
+ file_name: z.string().min(1).nullish(),
+ content_type: z.string().min(1).nullish(),
+});
+const RequestFormatEnum = z.enum(["JSON", "XML", "MULTIPART"]);
+const DataPassthroughRequest = z.object({
+ method: MethodEnum,
+ path: z.string().min(1),
+ base_url_override: z.string().min(1).nullish(),
+ data: z.string().min(1).nullish(),
+ multipart_form_data: z.array(MultipartFormFieldRequest).nullish(),
+ headers: z.object({}).partial().passthrough().nullish(),
+ request_format: RequestFormatEnum.nullish(),
+ normalize_response: z.boolean().optional(),
+});
+const ResponseTypeEnum = z.enum(["JSON", "BASE64_GZIP"]);
+const RemoteResponse = z.object({
+ method: z.string(),
+ path: z.string(),
+ status: z.number().int(),
+ response: z.unknown(),
+ response_headers: z.object({}).partial().passthrough().optional(),
+ response_type: ResponseTypeEnum.optional(),
+ headers: z.object({}).partial().passthrough().optional(),
+});
+const Payment = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ transaction_date: z.string().datetime().nullable(),
+ contact: z.string().uuid().nullable(),
+ account: z.string().uuid().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ company: z.string().uuid().nullable(),
+ total_amount: z.number().nullable(),
+ remote_updated_at: z.string().datetime().nullable(),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedPaymentList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(Payment),
+ })
+ .partial();
+const PaymentRequest = z
+ .object({
+ transaction_date: z.string().datetime().nullable(),
+ contact: z.string().uuid().nullable(),
+ account: z.string().uuid().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ company: z.string().uuid().nullable(),
+ total_amount: z.number().nullable(),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const PaymentEndpointRequest = z.object({ model: PaymentRequest });
+const PaymentResponse = z.object({
+ model: Payment,
+ warnings: z.array(WarningValidationProblem),
+ errors: z.array(ErrorValidationProblem),
+ logs: z.array(DebugModeLog).optional(),
+});
+const PurchaseOrderStatusEnum = z.enum([
+ "DRAFT",
+ "SUBMITTED",
+ "AUTHORIZED",
+ "BILLED",
+ "DELETED",
+]);
+const PurchaseOrderLineItem = z.object({
+ remote_id: z.string().nullish(),
+ description: z.string().nullish(),
+ unit_price: z.number().nullish(),
+ quantity: z.number().nullish(),
+ item: z.string().uuid().nullish(),
+ account: z.string().uuid().nullish(),
+ tracking_category: z.string().uuid().nullish(),
+ tracking_categories: z.array(z.string()),
+ tax_amount: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ total_line_amount: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ currency: CurrencyEnum.nullish(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ company: z.string().uuid().nullish(),
+});
+const PurchaseOrder = z
+ .object({
+ status: PurchaseOrderStatusEnum.nullable(),
+ issue_date: z.string().datetime().nullable(),
+ delivery_date: z.string().datetime().nullable(),
+ delivery_address: z.string().uuid().nullable(),
+ customer: z.string().uuid().nullable(),
+ vendor: z.string().uuid().nullable(),
+ memo: z.string().nullable(),
+ company: z.string().uuid().nullable(),
+ total_amount: z.number().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ line_items: z.array(PurchaseOrderLineItem),
+ remote_created_at: z.string().datetime().nullable(),
+ remote_updated_at: z.string().datetime().nullable(),
+ remote_was_deleted: z.boolean(),
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedPurchaseOrderList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(PurchaseOrder),
+ })
+ .partial();
+const PurchaseOrderLineItemRequest = z.object({
+ remote_id: z.string().nullish(),
+ description: z.string().nullish(),
+ unit_price: z.number().nullish(),
+ quantity: z.number().nullish(),
+ item: z.string().uuid().nullish(),
+ account: z.string().uuid().nullish(),
+ tracking_category: z.string().uuid().nullish(),
+ tracking_categories: z.array(z.string()),
+ tax_amount: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ total_line_amount: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ currency: CurrencyEnum.nullish(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ company: z.string().uuid().nullish(),
+ integration_params: z.object({}).partial().passthrough().nullish(),
+ linked_account_params: z.object({}).partial().passthrough().nullish(),
+});
+const PurchaseOrderRequest = z
+ .object({
+ status: PurchaseOrderStatusEnum.nullable(),
+ issue_date: z.string().datetime().nullable(),
+ delivery_date: z.string().datetime().nullable(),
+ delivery_address: z.string().uuid().nullable(),
+ customer: z.string().uuid().nullable(),
+ vendor: z.string().uuid().nullable(),
+ memo: z.string().nullable(),
+ company: z.string().uuid().nullable(),
+ total_amount: z.number().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ line_items: z.array(PurchaseOrderLineItemRequest),
+ integration_params: z.object({}).partial().passthrough().nullable(),
+ linked_account_params: z.object({}).partial().passthrough().nullable(),
+ })
+ .partial();
+const PurchaseOrderEndpointRequest = z.object({ model: PurchaseOrderRequest });
+const PurchaseOrderResponse = z.object({
+ model: PurchaseOrder,
+ warnings: z.array(WarningValidationProblem),
+ errors: z.array(ErrorValidationProblem),
+ logs: z.array(DebugModeLog).optional(),
+});
+const RemoteKeyForRegenerationRequest = z.object({ name: z.string().min(1) });
+const LinkedAccountCondition = z.object({
+ condition_schema_id: z.string().uuid(),
+ common_model: z.string().optional(),
+ native_name: z.string().nullable(),
+ operator: z.string(),
+ value: z.unknown().optional(),
+ field_name: z.string().nullable(),
+});
+const LinkedAccountSelectiveSyncConfiguration = z
+ .object({ linked_account_conditions: z.array(LinkedAccountCondition) })
+ .partial();
+const LinkedAccountConditionRequest = z.object({
+ condition_schema_id: z.string().uuid(),
+ operator: z.string().min(1),
+ value: z.unknown(),
+});
+const LinkedAccountSelectiveSyncConfigurationRequest = z.object({
+ linked_account_conditions: z.array(LinkedAccountConditionRequest),
+});
+const LinkedAccountSelectiveSyncConfigurationListRequest = z.object({
+ sync_configurations: z.array(LinkedAccountSelectiveSyncConfigurationRequest),
+});
+const ConditionTypeEnum = z.enum([
+ "BOOLEAN",
+ "DATE",
+ "DATE_TIME",
+ "INTEGER",
+ "FLOAT",
+ "STRING",
+ "LIST_OF_STRINGS",
+]);
+const OperatorSchema = z
+ .object({ operator: z.string(), is_unique: z.boolean() })
+ .partial();
+const ConditionSchema = z.object({
+ id: z.string().uuid(),
+ common_model: z.string().optional(),
+ native_name: z.string().nullable(),
+ field_name: z.string().nullable(),
+ is_unique: z.boolean().optional(),
+ condition_type: ConditionTypeEnum,
+ operators: z.array(OperatorSchema),
+});
+const PaginatedConditionSchemaList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(ConditionSchema),
+ })
+ .partial();
+const SyncStatusStatusEnum = z.enum([
+ "SYNCING",
+ "DONE",
+ "FAILED",
+ "DISABLED",
+ "PAUSED",
+]);
+const SelectiveSyncConfigurationsUsageEnum = z.enum([
+ "IN_NEXT_SYNC",
+ "IN_LAST_SYNC",
+]);
+const SyncStatus = z.object({
+ model_name: z.string(),
+ model_id: z.string(),
+ last_sync_start: z.string().datetime().optional(),
+ next_sync_start: z.string().datetime().optional(),
+ status: SyncStatusStatusEnum,
+ is_initial_sync: z.boolean(),
+ selective_sync_configurations_usage:
+ SelectiveSyncConfigurationsUsageEnum.optional(),
+});
+const PaginatedSyncStatusList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(SyncStatus),
+ })
+ .partial();
+const TaxRate = z
+ .object({
+ description: z.string().nullable(),
+ total_tax_rate: z.number().nullable(),
+ effective_tax_rate: z.number().nullable(),
+ company: z.string().uuid().nullable(),
+ remote_was_deleted: z.boolean(),
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedTaxRateList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(TaxRate),
+ })
+ .partial();
+const CategoryTypeEnum = z.enum(["CLASS", "DEPARTMENT"]);
+const TrackingCategory = z
+ .object({
+ name: z.string().nullable(),
+ status: Status7d1Enum.nullable(),
+ category_type: CategoryTypeEnum.nullable(),
+ parent_category: z.string().uuid().nullable(),
+ company: z.string().uuid().nullable(),
+ remote_was_deleted: z.boolean(),
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedTrackingCategoryList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(TrackingCategory),
+ })
+ .partial();
+const TransactionLineItem = z.object({
+ remote_id: z.string().nullish(),
+ memo: z.string().nullish(),
+ unit_price: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ quantity: z
+ .string()
+ .regex(/^-?\d{0,24}(?:\.\d{0,8})?$/)
+ .nullish(),
+ item: z.string().uuid().nullish(),
+ account: z.string().uuid().nullish(),
+ tracking_category: z.string().uuid().nullish(),
+ tracking_categories: z.array(z.string()),
+ total_line_amount: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ tax_rate: z.string().uuid().nullish(),
+ currency: CurrencyEnum.nullish(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullish(),
+ company: z.string().uuid().nullish(),
+});
+const Transaction = z
+ .object({
+ transaction_type: z.string().nullable(),
+ number: z.string().nullable(),
+ transaction_date: z.string().datetime().nullable(),
+ account: z.string().uuid().nullable(),
+ contact: z.string().uuid().nullable(),
+ total_amount: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ company: z.string().uuid().nullable(),
+ line_items: z.array(TransactionLineItem),
+ remote_was_deleted: z.boolean(),
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedTransactionList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(Transaction),
+ })
+ .partial();
+const VendorCreditLine = z.object({
+ remote_id: z.string().nullish(),
+ net_amount: z.number().nullish(),
+ tracking_category: z.string().uuid().nullish(),
+ tracking_categories: z.array(z.string()),
+ description: z.string().nullish(),
+ account: z.string().uuid().nullish(),
+ company: z.string().uuid().nullish(),
+});
+const VendorCredit = z
+ .object({
+ id: z.string().uuid(),
+ remote_id: z.string().nullable(),
+ number: z.string().nullable(),
+ transaction_date: z.string().datetime().nullable(),
+ vendor: z.string().uuid().nullable(),
+ total_amount: z.number().nullable(),
+ currency: CurrencyEnum.nullable(),
+ exchange_rate: z
+ .string()
+ .regex(/^-?\d{0,32}(?:\.\d{0,16})?$/)
+ .nullable(),
+ company: z.string().uuid().nullable(),
+ lines: z.array(VendorCreditLine),
+ remote_was_deleted: z.boolean(),
+ field_mappings: z.object({}).partial().passthrough().nullable(),
+ remote_data: z.array(RemoteData).nullable(),
+ })
+ .partial();
+const PaginatedVendorCreditList = z
+ .object({
+ next: z.string().nullable(),
+ previous: z.string().nullable(),
+ results: z.array(VendorCredit),
+ })
+ .partial();
+const WebhookReceiver = z.object({
+ event: z.string(),
+ is_active: z.boolean(),
+ key: z.string().optional(),
+});
+const WebhookReceiverRequest = z.object({
+ event: z.string().min(1),
+ is_active: z.boolean(),
+ key: z.string().min(1).optional(),
+});
+
+const endpoints = makeApi([
+ {
+ method: "get",
+ path: "/account-details",
+ description: `Get details for a linked account.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: AccountDetails,
+ },
+ {
+ method: "get",
+ path: "/account-token/:public_token",
+ description: `Returns the account token for the end user with the provided public token.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "public_token",
+ type: "Path",
+ schema: z.string(),
+ },
+ ],
+ response: AccountToken,
+ },
+ {
+ method: "get",
+ path: "/accounts",
+ description: `Returns a list of `Account` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z
+ .enum(["classification", "classification,status", "status"])
+ .optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z
+ .enum(["classification", "classification,status", "status"])
+ .optional(),
+ },
+ ],
+ response: PaginatedAccountList,
+ },
+ {
+ method: "post",
+ path: "/accounts",
+ description: `Creates an `Account` object with the given values.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: AccountEndpointRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "is_debug_mode",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "run_async",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: AccountResponse,
+ },
+ {
+ method: "get",
+ path: "/accounts/:id",
+ description: `Returns an `Account` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z
+ .enum(["classification", "classification,status", "status"])
+ .optional(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z
+ .enum(["classification", "classification,status", "status"])
+ .optional(),
+ },
+ ],
+ response: Account,
+ },
+ {
+ method: "get",
+ path: "/accounts/meta/post",
+ description: `Returns metadata for `Account` POSTs.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: MetaResponse,
+ },
+ {
+ method: "get",
+ path: "/addresses/:id",
+ description: `Returns an `Address` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("type").optional(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("type").optional(),
+ },
+ ],
+ response: Address,
+ },
+ {
+ method: "get",
+ path: "/attachments",
+ description: `Returns a list of `AccountingAttachment` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ ],
+ response: PaginatedAccountingAttachmentList,
+ },
+ {
+ method: "post",
+ path: "/attachments",
+ description: `Creates an `AccountingAttachment` object with the given values.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: AccountingAttachmentEndpointRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "is_debug_mode",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "run_async",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: AccountingAttachmentResponse,
+ },
+ {
+ method: "get",
+ path: "/attachments/:id",
+ description: `Returns an `AccountingAttachment` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: AccountingAttachment,
+ },
+ {
+ method: "get",
+ path: "/attachments/meta/post",
+ description: `Returns metadata for `AccountingAttachment` POSTs.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: MetaResponse,
+ },
+ {
+ method: "get",
+ path: "/available-actions",
+ description: `Returns a list of models and actions available for an account.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: AvailableActions,
+ },
+ {
+ method: "get",
+ path: "/balance-sheets",
+ description: `Returns a list of `BalanceSheet` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ ],
+ response: PaginatedBalanceSheetList,
+ },
+ {
+ method: "get",
+ path: "/balance-sheets/:id",
+ description: `Returns a `BalanceSheet` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: BalanceSheet,
+ },
+ {
+ method: "get",
+ path: "/cash-flow-statements",
+ description: `Returns a list of `CashFlowStatement` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ ],
+ response: PaginatedCashFlowStatementList,
+ },
+ {
+ method: "get",
+ path: "/cash-flow-statements/:id",
+ description: `Returns a `CashFlowStatement` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: CashFlowStatement,
+ },
+ {
+ method: "get",
+ path: "/common-model-scopes",
+ description: `Fetch the configuration of what data is saved by Merge when syncing. Common model scopes are set as a default across all linked accounts, but can be updated to have greater granularity per account.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "linked_account_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ ],
+ response: CommonModelScopes,
+ },
+ {
+ method: "post",
+ path: "/common-model-scopes",
+ description: `Update the configuration of what data is saved by Merge when syncing. Common model scopes are set as a default across all linked accounts, but can be updated to have greater granularity per account.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: CommonModelScopesUpdateSerializer,
+ },
+ {
+ name: "linked_account_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ ],
+ response: CommonModelScopes,
+ },
+ {
+ method: "get",
+ path: "/company-info",
+ description: `Returns a list of `CompanyInfo` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum(["addresses", "addresses,phone_numbers", "phone_numbers"])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ ],
+ response: PaginatedCompanyInfoList,
+ },
+ {
+ method: "get",
+ path: "/company-info/:id",
+ description: `Returns a `CompanyInfo` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum(["addresses", "addresses,phone_numbers", "phone_numbers"])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: CompanyInfo,
+ },
+ {
+ method: "get",
+ path: "/contacts",
+ description: `Returns a list of `Contact` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "addresses",
+ "addresses,company",
+ "addresses,phone_numbers",
+ "addresses,phone_numbers,company",
+ "company",
+ "phone_numbers",
+ "phone_numbers,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ ],
+ response: PaginatedContactList,
+ },
+ {
+ method: "post",
+ path: "/contacts",
+ description: `Creates a `Contact` object with the given values.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ContactEndpointRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "is_debug_mode",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "run_async",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: ContactResponse,
+ },
+ {
+ method: "get",
+ path: "/contacts/:id",
+ description: `Returns a `Contact` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "addresses",
+ "addresses,company",
+ "addresses,phone_numbers",
+ "addresses,phone_numbers,company",
+ "company",
+ "phone_numbers",
+ "phone_numbers,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ ],
+ response: Contact,
+ },
+ {
+ method: "get",
+ path: "/contacts/meta/post",
+ description: `Returns metadata for `Contact` POSTs.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: MetaResponse,
+ },
+ {
+ method: "get",
+ path: "/credit-notes",
+ description: `Returns a list of `CreditNote` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum(["line_items", "payments", "payments,line_items"])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.enum(["status", "status,type", "type"]).optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.enum(["status", "status,type", "type"]).optional(),
+ },
+ {
+ name: "transaction_date_after",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "transaction_date_before",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ ],
+ response: PaginatedCreditNoteList,
+ },
+ {
+ method: "get",
+ path: "/credit-notes/:id",
+ description: `Returns a `CreditNote` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum(["line_items", "payments", "payments,line_items"])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.enum(["status", "status,type", "type"]).optional(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.enum(["status", "status,type", "type"]).optional(),
+ },
+ ],
+ response: CreditNote,
+ },
+ {
+ method: "post",
+ path: "/delete-account",
+ description: `Delete a linked account.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: z.void(),
+ },
+ {
+ method: "get",
+ path: "/expenses",
+ description: `Returns a list of `Expense` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "account",
+ "account,company",
+ "account,contact",
+ "account,contact,company",
+ "company",
+ "contact",
+ "contact,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "transaction_date_after",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "transaction_date_before",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ ],
+ response: PaginatedExpenseList,
+ },
+ {
+ method: "post",
+ path: "/expenses",
+ description: `Creates an `Expense` object with the given values.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: ExpenseEndpointRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "is_debug_mode",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "run_async",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: ExpenseResponse,
+ },
+ {
+ method: "get",
+ path: "/expenses/:id",
+ description: `Returns an `Expense` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "account",
+ "account,company",
+ "account,contact",
+ "account,contact,company",
+ "company",
+ "contact",
+ "contact,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: Expense,
+ },
+ {
+ method: "get",
+ path: "/expenses/meta/post",
+ description: `Returns metadata for `Expense` POSTs.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: MetaResponse,
+ },
+ {
+ method: "post",
+ path: "/generate-key",
+ description: `Create a remote key.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({ name: z.string().min(1) }),
+ },
+ ],
+ response: RemoteKey,
+ },
+ {
+ method: "get",
+ path: "/income-statements",
+ description: `Returns a list of `IncomeStatement` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ ],
+ response: PaginatedIncomeStatementList,
+ },
+ {
+ method: "get",
+ path: "/income-statements/:id",
+ description: `Returns an `IncomeStatement` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: IncomeStatement,
+ },
+ {
+ method: "get",
+ path: "/invoices",
+ description: `Returns a list of `Invoice` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "contact_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "company",
+ "contact",
+ "contact,company",
+ "line_items",
+ "line_items,company",
+ "line_items,contact",
+ "line_items,contact,company",
+ "payments",
+ "payments,company",
+ "payments,contact",
+ "payments,contact,company",
+ "payments,line_items",
+ "payments,line_items,company",
+ "payments,line_items,contact",
+ "payments,line_items,contact,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "issue_date_after",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "issue_date_before",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("type").optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("type").optional(),
+ },
+ {
+ name: "type",
+ type: "Query",
+ schema: z.enum(["ACCOUNTS_PAYABLE", "ACCOUNTS_RECEIVABLE"]).nullish(),
+ },
+ ],
+ response: PaginatedInvoiceList,
+ },
+ {
+ method: "post",
+ path: "/invoices",
+ description: `Creates an `Invoice` object with the given values.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: InvoiceEndpointRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "is_debug_mode",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "run_async",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: InvoiceResponse,
+ },
+ {
+ method: "get",
+ path: "/invoices/:id",
+ description: `Returns an `Invoice` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "company",
+ "contact",
+ "contact,company",
+ "line_items",
+ "line_items,company",
+ "line_items,contact",
+ "line_items,contact,company",
+ "payments",
+ "payments,company",
+ "payments,contact",
+ "payments,contact,company",
+ "payments,line_items",
+ "payments,line_items,company",
+ "payments,line_items,contact",
+ "payments,line_items,contact,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("type").optional(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("type").optional(),
+ },
+ ],
+ response: Invoice,
+ },
+ {
+ method: "get",
+ path: "/invoices/meta/post",
+ description: `Returns metadata for `Invoice` POSTs.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: MetaResponse,
+ },
+ {
+ method: "get",
+ path: "/issues",
+ description: `Gets issues.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "account_token",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "end_date",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "end_user_organization_name",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "first_incident_time_after",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "first_incident_time_before",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "include_muted",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "integration_name",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "last_incident_time_after",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "last_incident_time_before",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "start_date",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "status",
+ type: "Query",
+ schema: z.enum(["ONGOING", "RESOLVED"]).optional(),
+ },
+ ],
+ response: PaginatedIssueList,
+ },
+ {
+ method: "get",
+ path: "/issues/:id",
+ description: `Get a specific issue.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ ],
+ response: Issue,
+ },
+ {
+ method: "get",
+ path: "/items",
+ description: `Returns a list of `Item` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "company",
+ "purchase_account",
+ "purchase_account,company",
+ "purchase_account,sales_account",
+ "purchase_account,sales_account,company",
+ "sales_account",
+ "sales_account,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ ],
+ response: PaginatedItemList,
+ },
+ {
+ method: "get",
+ path: "/items/:id",
+ description: `Returns an `Item` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "company",
+ "purchase_account",
+ "purchase_account,company",
+ "purchase_account,sales_account",
+ "purchase_account,sales_account,company",
+ "sales_account",
+ "sales_account,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ ],
+ response: Item,
+ },
+ {
+ method: "get",
+ path: "/journal-entries",
+ description: `Returns a list of `JournalEntry` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "company",
+ "lines",
+ "lines,company",
+ "lines,payments",
+ "lines,payments,company",
+ "payments",
+ "payments,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "transaction_date_after",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "transaction_date_before",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ ],
+ response: PaginatedJournalEntryList,
+ },
+ {
+ method: "post",
+ path: "/journal-entries",
+ description: `Creates a `JournalEntry` object with the given values.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: JournalEntryEndpointRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "is_debug_mode",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "run_async",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: JournalEntryResponse,
+ },
+ {
+ method: "get",
+ path: "/journal-entries/:id",
+ description: `Returns a `JournalEntry` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "company",
+ "lines",
+ "lines,company",
+ "lines,payments",
+ "lines,payments,company",
+ "payments",
+ "payments,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: JournalEntry,
+ },
+ {
+ method: "get",
+ path: "/journal-entries/meta/post",
+ description: `Returns metadata for `JournalEntry` POSTs.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: MetaResponse,
+ },
+ {
+ method: "post",
+ path: "/link-token",
+ description: `Creates a link token to be used when linking a new end user.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: EndUserDetailsRequest,
+ },
+ ],
+ response: LinkToken,
+ },
+ {
+ method: "get",
+ path: "/linked-accounts",
+ description: `List linked accounts for your organization.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "category",
+ type: "Query",
+ schema: z
+ .enum([
+ "accounting",
+ "ats",
+ "crm",
+ "filestorage",
+ "hris",
+ "mktg",
+ "ticketing",
+ ])
+ .nullish(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "end_user_email_address",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "end_user_organization_name",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "end_user_origin_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "end_user_origin_ids",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "id",
+ type: "Query",
+ schema: z.string().uuid().optional(),
+ },
+ {
+ name: "ids",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "include_duplicates",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "integration_name",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "is_test_account",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "status",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ ],
+ response: PaginatedAccountDetailsAndActionsList,
+ },
+ {
+ method: "post",
+ path: "/passthrough",
+ description: `Pull data from an endpoint not currently supported by Merge.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: DataPassthroughRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: RemoteResponse,
+ },
+ {
+ method: "get",
+ path: "/payments",
+ description: `Returns a list of `Payment` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "account_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "contact_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "account",
+ "account,company",
+ "company",
+ "contact",
+ "contact,account",
+ "contact,account,company",
+ "contact,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "transaction_date_after",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "transaction_date_before",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ ],
+ response: PaginatedPaymentList,
+ },
+ {
+ method: "post",
+ path: "/payments",
+ description: `Creates a `Payment` object with the given values.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: PaymentEndpointRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "is_debug_mode",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "run_async",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: PaymentResponse,
+ },
+ {
+ method: "get",
+ path: "/payments/:id",
+ description: `Returns a `Payment` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "account",
+ "account,company",
+ "company",
+ "contact",
+ "contact,account",
+ "contact,account,company",
+ "contact,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: Payment,
+ },
+ {
+ method: "get",
+ path: "/payments/meta/post",
+ description: `Returns metadata for `Payment` POSTs.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: MetaResponse,
+ },
+ {
+ method: "get",
+ path: "/phone-numbers/:id",
+ description: `Returns an `AccountingPhoneNumber` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: AccountingPhoneNumber,
+ },
+ {
+ method: "get",
+ path: "/purchase-orders",
+ description: `Returns a list of `PurchaseOrder` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "company",
+ "delivery_address",
+ "delivery_address,company",
+ "delivery_address,vendor",
+ "delivery_address,vendor,company",
+ "line_items",
+ "line_items,company",
+ "line_items,delivery_address",
+ "line_items,delivery_address,company",
+ "line_items,delivery_address,vendor",
+ "line_items,delivery_address,vendor,company",
+ "line_items,vendor",
+ "line_items,vendor,company",
+ "vendor",
+ "vendor,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "issue_date_after",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "issue_date_before",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ ],
+ response: PaginatedPurchaseOrderList,
+ },
+ {
+ method: "post",
+ path: "/purchase-orders",
+ description: `Creates a `PurchaseOrder` object with the given values.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: PurchaseOrderEndpointRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "is_debug_mode",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "run_async",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: PurchaseOrderResponse,
+ },
+ {
+ method: "get",
+ path: "/purchase-orders/:id",
+ description: `Returns a `PurchaseOrder` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "company",
+ "delivery_address",
+ "delivery_address,company",
+ "delivery_address,vendor",
+ "delivery_address,vendor,company",
+ "line_items",
+ "line_items,company",
+ "line_items,delivery_address",
+ "line_items,delivery_address,company",
+ "line_items,delivery_address,vendor",
+ "line_items,delivery_address,vendor,company",
+ "line_items,vendor",
+ "line_items,vendor,company",
+ "vendor",
+ "vendor,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ ],
+ response: PurchaseOrder,
+ },
+ {
+ method: "get",
+ path: "/purchase-orders/meta/post",
+ description: `Returns metadata for `PurchaseOrder` POSTs.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: MetaResponse,
+ },
+ {
+ method: "post",
+ path: "/regenerate-key",
+ description: `Exchange remote keys.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({ name: z.string().min(1) }),
+ },
+ ],
+ response: RemoteKey,
+ },
+ {
+ method: "get",
+ path: "/selective-sync/configurations",
+ description: `Get a linked account's selective syncs.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: z.array(LinkedAccountSelectiveSyncConfiguration),
+ },
+ {
+ method: "put",
+ path: "/selective-sync/configurations",
+ description: `Replace a linked account's selective syncs.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: LinkedAccountSelectiveSyncConfigurationListRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: z.array(LinkedAccountSelectiveSyncConfiguration),
+ },
+ {
+ method: "get",
+ path: "/selective-sync/meta",
+ description: `Get metadata for the conditions available to a linked account.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "common_model",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ ],
+ response: PaginatedConditionSchemaList,
+ },
+ {
+ method: "get",
+ path: "/sync-status",
+ description: `Get syncing status. Possible values: `DISABLED`, `DONE`, `FAILED`, `PAUSED`, `SYNCING``,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ ],
+ response: PaginatedSyncStatusList,
+ },
+ {
+ method: "post",
+ path: "/sync-status/resync",
+ description: `Force re-sync of all models. This is available for all organizations via the dashboard. Force re-sync is also available for monthly and quarterly sync frequency customers on the Core, Professional, or Enterprise plans.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: z.array(SyncStatus),
+ },
+ {
+ method: "get",
+ path: "/tax-rates",
+ description: `Returns a list of `TaxRate` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ ],
+ response: PaginatedTaxRateList,
+ },
+ {
+ method: "get",
+ path: "/tax-rates/:id",
+ description: `Returns a `TaxRate` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: TaxRate,
+ },
+ {
+ method: "get",
+ path: "/tracking-categories",
+ description: `Returns a list of `TrackingCategory` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ ],
+ response: PaginatedTrackingCategoryList,
+ },
+ {
+ method: "get",
+ path: "/tracking-categories/:id",
+ description: `Returns a `TrackingCategory` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z.literal("company").optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "remote_fields",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ {
+ name: "show_enum_origins",
+ type: "Query",
+ schema: z.literal("status").optional(),
+ },
+ ],
+ response: TrackingCategory,
+ },
+ {
+ method: "get",
+ path: "/transactions",
+ description: `Returns a list of `Transaction` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "account",
+ "contact",
+ "contact,account",
+ "line_items",
+ "line_items,account",
+ "line_items,contact",
+ "line_items,contact,account",
+ ])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "transaction_date_after",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "transaction_date_before",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ ],
+ response: PaginatedTransactionList,
+ },
+ {
+ method: "get",
+ path: "/transactions/:id",
+ description: `Returns a `Transaction` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "account",
+ "contact",
+ "contact,account",
+ "line_items",
+ "line_items,account",
+ "line_items,contact",
+ "line_items,contact,account",
+ ])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: Transaction,
+ },
+ {
+ method: "get",
+ path: "/vendor-credits",
+ description: `Returns a list of `VendorCredit` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "company_id",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "created_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "created_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "cursor",
+ type: "Query",
+ schema: z.string().optional(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "company",
+ "lines",
+ "lines,company",
+ "lines,vendor",
+ "lines,vendor,company",
+ "vendor",
+ "vendor,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "include_deleted_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ {
+ name: "modified_after",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "modified_before",
+ type: "Query",
+ schema: z.string().datetime().optional(),
+ },
+ {
+ name: "page_size",
+ type: "Query",
+ schema: z.number().int().optional(),
+ },
+ {
+ name: "remote_id",
+ type: "Query",
+ schema: z.string().nullish(),
+ },
+ {
+ name: "transaction_date_after",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ {
+ name: "transaction_date_before",
+ type: "Query",
+ schema: z.string().datetime().nullish(),
+ },
+ ],
+ response: PaginatedVendorCreditList,
+ },
+ {
+ method: "get",
+ path: "/vendor-credits/:id",
+ description: `Returns a `VendorCredit` object with the given `id`.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ {
+ name: "expand",
+ type: "Query",
+ schema: z
+ .enum([
+ "company",
+ "lines",
+ "lines,company",
+ "lines,vendor",
+ "lines,vendor,company",
+ "vendor",
+ "vendor,company",
+ ])
+ .optional(),
+ },
+ {
+ name: "id",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ {
+ name: "include_remote_data",
+ type: "Query",
+ schema: z.boolean().optional(),
+ },
+ ],
+ response: VendorCredit,
+ },
+ {
+ method: "get",
+ path: "/webhook-receivers",
+ description: `Returns a list of `WebhookReceiver` objects.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: z.array(WebhookReceiver),
+ },
+ {
+ method: "post",
+ path: "/webhook-receivers",
+ description: `Creates a `WebhookReceiver` object with the given values.`,
+ requestFormat: "json",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: WebhookReceiverRequest,
+ },
+ {
+ name: "X-Account-Token",
+ type: "Header",
+ schema: z.string(),
+ },
+ ],
+ response: WebhookReceiver,
+ },
+]);
+
+export const api = new ZodiosCore(endpoints);
+
+async function main() {
+ const result = await api.get("/accounts/:id", {
+ // ^?
+ params: { id: "123" },
+ headers: { "X-Account-Token": "abc" },
+ });
+}
diff --git a/packages/core/examples/types-from-definition.ts b/packages/core/examples/types-from-definition.ts
new file mode 100644
index 00000000..bc25cf30
--- /dev/null
+++ b/packages/core/examples/types-from-definition.ts
@@ -0,0 +1,128 @@
+import {
+ ZodiosResponseByPath,
+ ZodiosBodyByPath,
+ ZodiosPathParamsByPath,
+ ZodiosQueryParamsByPath,
+ makeApi,
+ ZodiosPathParamByAlias,
+ makeErrors,
+} from "../src/index";
+import z from "zod";
+
+const user = z.object({
+ id: z.number(),
+ name: z.string(),
+ email: z.string().email(),
+ phone: z.string(),
+});
+
+const errors = makeErrors([
+ {
+ status: 404,
+ schema: z.object({
+ message: z.string(),
+ }),
+ },
+ {
+ status: 401,
+ schema: z.object({
+ message: z.string(),
+ }),
+ },
+ {
+ status: 500,
+ schema: z.object({
+ message: z.string(),
+ cause: z.record(z.string()),
+ }),
+ },
+]);
+
+const api = makeApi([
+ {
+ path: "/users",
+ method: "get",
+ response: z.array(user),
+ },
+ {
+ path: "/users/:id",
+ method: "get",
+ alias: "getUser",
+ parameters: [
+ {
+ name: "id",
+ type: "Path",
+ schema: z.number().positive(),
+ },
+ ],
+ response: user,
+ errors,
+ },
+ {
+ path: "/users",
+ method: "post",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: user,
+ },
+ ],
+ response: user,
+ },
+ {
+ path: "/users/:id",
+ method: "put",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: user,
+ },
+ ],
+ response: user,
+ },
+ {
+ path: "/users/:id",
+ method: "patch",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: user,
+ },
+ ],
+ response: user,
+ },
+ {
+ path: "/users/:id",
+ method: "delete",
+ response: z.object({}),
+ },
+]);
+
+type User = z.infer;
+type Api = typeof api;
+
+type Users = ZodiosResponseByPath;
+// ^?
+type UserById = ZodiosResponseByPath;
+// ^?
+type GetUserParams = ZodiosPathParamsByPath;
+// ^?
+type GetUserParamsByAlias = ZodiosPathParamByAlias;
+// ^?
+type GetUsersParams = ZodiosPathParamsByPath;
+// ^?
+type GetUserQueries = ZodiosQueryParamsByPath;
+// ^?
+type CreateUserBody = ZodiosBodyByPath;
+// ^?
+type CreateUserResponse = ZodiosResponseByPath;
+// ^?
+type UpdateUserBody = ZodiosBodyByPath;
+// ^?
+type PatchUserBody = ZodiosBodyByPath;
+// ^?
+type DeleteUserResponse = ZodiosResponseByPath;
+// ^?
diff --git a/packages/core/examples/typescript-types.ts b/packages/core/examples/typescript-types.ts
new file mode 100644
index 00000000..1393c1a3
--- /dev/null
+++ b/packages/core/examples/typescript-types.ts
@@ -0,0 +1,74 @@
+import {
+ ZodiosCore,
+ makeApi,
+ tsFnSchema,
+ ApiOf,
+ TypeProviderOf,
+ tsSchema,
+ tsTypeProvider,
+} from "../src/index";
+
+// you can also predefine your API
+const jsonplaceholderUrl = "https://jsonplaceholder.typicode.com";
+
+type User = {
+ id: number;
+ name: string;
+};
+
+const userSchema = tsSchema();
+
+const usersSchema = tsSchema();
+
+const jsonplaceholderApi = makeApi([
+ {
+ method: "get",
+ path: "/users",
+ description: "Get all users",
+ parameters: [
+ {
+ name: "q",
+ description: "full text search",
+ type: "Query",
+ schema: tsFnSchema((data) => {
+ if (typeof data !== "string") {
+ throw new Error("not a string");
+ }
+ return data;
+ }),
+ },
+ {
+ name: "page",
+ description: "page number",
+ type: "Query",
+ schema: tsSchema(),
+ },
+ ],
+ response: usersSchema,
+ },
+ {
+ method: "get",
+ path: "/users/:id",
+ description: "Get a user",
+ response: userSchema,
+ },
+]);
+
+async function bootstrap() {
+ const apiClient = new ZodiosCore(jsonplaceholderUrl, jsonplaceholderApi, {
+ typeProvider: tsTypeProvider,
+ });
+
+ type Api = ApiOf;
+ // ^?
+ type Provider = TypeProviderOf;
+ // ^?
+ const users = await apiClient.get("/users", { queries: { q: "Nicholas" } });
+ // ^?
+ console.log(users);
+ const user = await apiClient.get("/users/:id", { params: { id: 7 } });
+ // ^?
+ console.log(user);
+}
+
+bootstrap();
diff --git a/packages/core/examples/zod-types.ts b/packages/core/examples/zod-types.ts
new file mode 100644
index 00000000..4969efe1
--- /dev/null
+++ b/packages/core/examples/zod-types.ts
@@ -0,0 +1,75 @@
+import { ZodiosCore, ZodiosErrorByAlias, makeApi } from "../src/index";
+import { z } from "zod";
+
+// you can define schema before declaring the API to get back the type
+const userSchema = z
+ .object({
+ id: z.number(),
+ name: z.string(),
+ })
+ .required();
+
+const usersSchema = z.array(userSchema);
+
+// you can then get back the types
+type User = z.infer;
+type Users = z.infer;
+
+// you can also predefine your API
+const jsonplaceholderUrl = "https://jsonplaceholder.typicode.com";
+const jsonplaceholderApi = makeApi([
+ {
+ method: "get",
+ path: "/users",
+ description: "Get all users",
+ parameters: [
+ {
+ name: "q",
+ description: "full text search",
+ type: "Query",
+ schema: z.string(),
+ },
+ {
+ name: "page",
+ description: "page number",
+ type: "Query",
+ schema: z.number().optional(),
+ },
+ ],
+ response: usersSchema,
+ },
+ {
+ method: "get",
+ path: "/users/:id",
+ description: "Get a user",
+ alias: "getUser",
+ response: userSchema,
+ errors: [
+ {
+ status: "default",
+ schema: z.object({ error: z.string(), message: z.string() }),
+ },
+ {
+ status: 400,
+ schema: z.object({
+ error: z.string(),
+ message: z.literal("Bad Request"),
+ }),
+ },
+ ],
+ },
+]);
+
+type Error400 = ZodiosErrorByAlias;
+
+// and then use them in your API
+async function bootstrap() {
+ const apiClient = new ZodiosCore(jsonplaceholderUrl, jsonplaceholderApi);
+
+ const users = await apiClient.get("/users", { queries: { q: "Nicholas" } });
+ console.log(users);
+ const user = await apiClient.get("/users/:id", { params: { id: 7 } });
+ console.log(user);
+}
+
+bootstrap();
diff --git a/packages/core/jest.config.ts b/packages/core/jest.config.ts
new file mode 100644
index 00000000..d0da3728
--- /dev/null
+++ b/packages/core/jest.config.ts
@@ -0,0 +1,24 @@
+import type { Config } from "@jest/types";
+
+// Objet synchrone
+const config: Config.InitialOptions = {
+ verbose: true,
+ moduleFileExtensions: ["ts", "js", "json", "node"],
+ rootDir: "./",
+ testRegex: ".(spec|test).tsx?$",
+ transform: {
+ "^.+\\.tsx?$": "ts-jest",
+ },
+ coveragePathIgnorePatterns: ["/node_modules/", "index\\.ts"],
+ coverageDirectory: "./coverage",
+ coverageThreshold: {
+ global: {
+ branches: 80,
+ functions: 85,
+ lines: 85,
+ statements: 85,
+ },
+ },
+ testEnvironment: "node",
+};
+export default config;
diff --git a/packages/core/package.json b/packages/core/package.json
new file mode 100644
index 00000000..d40e2f5c
--- /dev/null
+++ b/packages/core/package.json
@@ -0,0 +1,79 @@
+{
+ "name": "@zodios/core",
+ "description": "Typescript API client with autocompletion and zod validations",
+ "version": "11.0.0-beta.19",
+ "main": "lib/index.js",
+ "module": "lib/index.mjs",
+ "typings": "lib/index.d.ts",
+ "exports": {
+ ".": {
+ "import": "./lib/index.mjs",
+ "require": "./lib/index.js",
+ "types": "./lib/index.d.ts"
+ },
+ "./lib/*.types": {
+ "import": "./lib/*.types.mjs",
+ "require": "./lib/*.types.js",
+ "types": "./lib/*.types.d.ts"
+ },
+ "./package.json": "./package.json"
+ },
+ "files": [
+ "lib"
+ ],
+ "author": {
+ "name": "ecyrbe",
+ "email": "ecyrbe@gmail.com"
+ },
+ "homepage": "https://github.com/ecyrbe/zodios",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/ecyrbe/zodios.git"
+ },
+ "license": "MIT",
+ "keywords": [
+ "openapi",
+ "zod",
+ "autocomplete",
+ "validation"
+ ],
+ "scripts": {
+ "prebuild": "rimraf lib",
+ "example": "ts-node examples/jsonplaceholder.ts",
+ "example:dev.to": "ts-node examples/dev.to/example.ts",
+ "build": "tsup",
+ "test": "jest --coverage"
+ },
+ "peerDependencies": {
+ "fp-ts": "2.x",
+ "io-ts": "2.x",
+ "zod": "^3.x"
+ },
+ "peerDependenciesMeta": {
+ "zod": {
+ "optional": true
+ },
+ "fp-ts": {
+ "optional": true
+ },
+ "io-ts": {
+ "optional": true
+ }
+ },
+ "devDependencies": {
+ "@jest/globals": "29.5.0",
+ "@jest/types": "29.5.0",
+ "@types/jest": "29.5.0",
+ "@types/node": "18.15.11",
+ "form-data": "^4.0.0",
+ "fp-ts": "2.13.1",
+ "io-ts": "2.2.20",
+ "jest": "29.5.0",
+ "rimraf": "4.4.1",
+ "ts-jest": "29.1.0",
+ "ts-node": "10.9.1",
+ "tsup": "6.7.0",
+ "typescript": "5.0.4",
+ "zod": "3.21.4"
+ }
+}
diff --git a/packages/core/src/__snapshots__/zodios.test.ts.snap b/packages/core/src/__snapshots__/zodios.test.ts.snap
new file mode 100644
index 00000000..1ec8bbce
--- /dev/null
+++ b/packages/core/src/__snapshots__/zodios.test.ts.snap
@@ -0,0 +1,23 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Zodios should not validate bad formatted responses 1`] = `
+"Zodios: Invalid response from endpoint 'get /:id'
+status: 200 OK
+cause:
+[
+ {
+ "code": "invalid_type",
+ "expected": "string",
+ "received": "undefined",
+ "path": [
+ "more"
+ ],
+ "message": "Required"
+ }
+]
+received:
+{
+ "id": 1,
+ "name": "test"
+}"
+`;
diff --git a/packages/core/src/api.test.ts b/packages/core/src/api.test.ts
new file mode 100644
index 00000000..567b00f9
--- /dev/null
+++ b/packages/core/src/api.test.ts
@@ -0,0 +1,315 @@
+import z from "zod";
+import { makeApi, mergeApis, parametersBuilder } from "./index";
+import { Assert } from "./utils.types";
+
+const userSchema = z.object({
+ id: z.number(),
+ name: z.string(),
+});
+
+describe("makeApi", () => {
+ it("should throw on duplicate path", () => {
+ expect(() =>
+ makeApi([
+ {
+ method: "get",
+ path: "/users",
+ alias: "getUsers",
+ description: "Get all users",
+ response: z.array(userSchema),
+ },
+ {
+ method: "get",
+ path: "/users",
+ alias: "getUsers2",
+ description: "Get all users",
+ response: z.array(userSchema),
+ },
+ ])
+ ).toThrowError("Zodios: Duplicate path 'get /users'");
+ });
+
+ it("should throw on duplicate alias", () => {
+ expect(() =>
+ makeApi([
+ {
+ method: "get",
+ path: "/users",
+ alias: "getUsers",
+ description: "Get all users",
+ response: z.array(userSchema),
+ },
+ {
+ method: "get",
+ path: "/users2",
+ alias: "getUsers",
+ description: "Get all users",
+ response: z.array(userSchema),
+ },
+ ])
+ ).toThrowError("Zodios: Duplicate alias 'getUsers'");
+ });
+
+ it("should throw on duplicate Body", () => {
+ expect(() =>
+ makeApi([
+ {
+ method: "post",
+ path: "/users",
+ alias: "createUser",
+ description: "Create a user",
+ parameters: [
+ {
+ name: "first",
+ type: "Body",
+ description: "The object to create",
+ schema: userSchema.partial(),
+ },
+ {
+ name: "second",
+ type: "Body",
+ description: "The object to create",
+ schema: userSchema.partial(),
+ },
+ ],
+ response: userSchema,
+ },
+ ])
+ ).toThrowError("Zodios: Multiple body parameters in endpoint '/users'");
+ });
+
+ it("should build with parameters (Path,Query,Body,Header)", () => {
+ // get users api with query filter for user name, and path parameter for user id and header parameter for user token
+ const optionalTrueSchema = z.boolean().default(true).optional();
+ const partialUserSchema = userSchema.partial();
+ const bearerSchema = z.string().transform((s) => `Bearer ${s}`);
+ const api = makeApi([
+ {
+ method: "post",
+ path: "/users/:id",
+ alias: "createtUser",
+ description: "Create a user",
+ parameters: [
+ {
+ name: "id",
+ type: "Path",
+ description: "The user id",
+ schema: z.number(),
+ },
+ {
+ name: "homonyms",
+ type: "Query",
+ description: "Allow homonyms",
+ schema: optionalTrueSchema,
+ },
+ {
+ name: "email",
+ type: "Query",
+ description: "create an email account for the user",
+ schema: optionalTrueSchema,
+ },
+ {
+ name: "body",
+ type: "Body",
+ description: "The object to create",
+ schema: partialUserSchema,
+ },
+ {
+ name: "Authorization",
+ type: "Header",
+ description: "The user token",
+ schema: bearerSchema,
+ },
+ {
+ name: "x-custom-header",
+ type: "Header",
+ description: "A custom header",
+ schema: z.string(),
+ },
+ ],
+ response: userSchema,
+ },
+ ]);
+ // check narrowing works
+ const test: Assert<
+ typeof api,
+ readonly [
+ {
+ readonly method: "post";
+ readonly path: "/users/:id";
+ readonly alias: "createtUser";
+ readonly description: "Create a user";
+ readonly parameters: readonly [
+ {
+ readonly name: "id";
+ readonly type: "Path";
+ readonly description: "The user id";
+ readonly schema: z.ZodNumber;
+ },
+ {
+ readonly name: "homonyms";
+ readonly type: "Query";
+ readonly description: "Allow homonyms";
+ readonly schema: typeof optionalTrueSchema;
+ },
+ {
+ readonly name: "email";
+ readonly type: "Query";
+ readonly description: "create an email account for the user";
+ readonly schema: typeof optionalTrueSchema;
+ },
+ {
+ readonly name: "body";
+ readonly type: "Body";
+ readonly description: "The object to create";
+ readonly schema: typeof partialUserSchema;
+ },
+ {
+ readonly name: "Authorization";
+ readonly type: "Header";
+ readonly description: "The user token";
+ readonly schema: typeof bearerSchema;
+ },
+ {
+ readonly name: "x-custom-header";
+ readonly type: "Header";
+ readonly description: "A custom header";
+ readonly schema: z.ZodString;
+ }
+ ];
+ readonly response: typeof userSchema;
+ }
+ ]
+ > = true;
+ });
+});
+
+describe("parametersBuilder", () => {
+ it("should build parameters (Path,Query,Body,Header)", () => {
+ // get users api with query filter for user name, and path parameter for user id and header parameter for user token
+ const optionalTrueSchema = z.boolean().default(true).optional();
+ const partialUserSchema = userSchema.partial();
+ const bearerSchema = z.string().transform((s) => `Bearer ${s}`);
+
+ const parameters = parametersBuilder()
+ .addParameters("Path", {
+ id: z.number(),
+ })
+ .addQueries({
+ homonyms: optionalTrueSchema,
+ email: optionalTrueSchema,
+ })
+ .addBody(partialUserSchema)
+ .addHeaders({
+ Authorization: bearerSchema,
+ "x-custom-header": z.string(),
+ })
+ .build();
+
+ const test: Assert<
+ (typeof parameters)[number],
+ | {
+ name: "id";
+ type: "Path";
+ description?: string;
+ schema: z.ZodNumber;
+ }
+ | {
+ name: "homonyms";
+ type: "Query";
+ description?: string;
+ schema: typeof optionalTrueSchema;
+ }
+ | {
+ name: "email";
+ type: "Query";
+ description?: string;
+ schema: typeof optionalTrueSchema;
+ }
+ | {
+ name: "body";
+ type: "Body";
+ description?: string;
+ schema: typeof partialUserSchema;
+ }
+ | {
+ name: "Authorization";
+ type: "Header";
+ description?: string;
+ schema: typeof bearerSchema;
+ }
+ | {
+ name: "x-custom-header";
+ type: "Header";
+ description?: string;
+ schema: z.ZodString;
+ }
+ > = true;
+ });
+});
+
+describe("mergeApis", () => {
+ it("should merge two apis", () => {
+ const usersSchema = z.array(userSchema);
+ const api1 = makeApi([
+ {
+ method: "get",
+ path: "/",
+ alias: "getUsers",
+ description: "Get all users",
+ response: usersSchema,
+ },
+ {
+ method: "get",
+ path: "/:id",
+ alias: "getUser",
+ description: "Get a user",
+ response: userSchema,
+ },
+ ]);
+
+ const api2 = makeApi([
+ {
+ method: "get",
+ path: "/",
+ alias: "getAdmins",
+ description: "Get all admins",
+ response: usersSchema,
+ },
+ ]);
+ const merged = mergeApis({
+ "/users": api1,
+ "/admins": api2,
+ });
+ expect(merged).toHaveLength(3);
+ expect(merged[0].path).toEqual("/users");
+ expect(merged[1].path).toEqual("/users/:id");
+ expect(merged[2].path).toEqual("/admins");
+ const test1: Assert<
+ typeof merged,
+ [
+ {
+ readonly method: "get";
+ readonly path: "/users";
+ readonly alias: "getUsers";
+ readonly description: "Get all users";
+ readonly response: typeof usersSchema;
+ },
+ {
+ readonly method: "get";
+ readonly path: "/users/:id";
+ readonly alias: "getUser";
+ readonly description: "Get a user";
+ readonly response: typeof userSchema;
+ },
+ {
+ readonly method: "get";
+ readonly path: "/admins";
+ readonly alias: "getAdmins";
+ readonly description: "Get all admins";
+ readonly response: typeof usersSchema;
+ }
+ ]
+ > = true;
+ });
+});
diff --git a/src/api.ts b/packages/core/src/api.ts
similarity index 53%
rename from src/api.ts
rename to packages/core/src/api.ts
index cbe21159..b92ee2a8 100644
--- a/src/api.ts
+++ b/packages/core/src/api.ts
@@ -1,15 +1,9 @@
-// disable type checking for this file as we need to defer type checking when using these utility types
-// indeed typescript seems to have a bug, where it tries to infer the type of an undecidable generic type
-// but when using the functions, types are inferred correctly
-import {
+import { TupleFlat, UnionToTuple } from "./utils.types";
+import type {
ZodiosEndpointDefinition,
ZodiosEndpointParameter,
- ZodiosEndpointDefinitions,
ZodiosEndpointError,
} from "./zodios.types";
-import z, { ZodRawShape } from "zod";
-import { capitalize } from "./utils";
-import { Narrow, TupleFlat, UnionToTuple } from "./utils.types";
/**
* check api for non unique paths
@@ -17,8 +11,9 @@ import { Narrow, TupleFlat, UnionToTuple } from "./utils.types";
* @return - nothing
* @throws - error if api has non unique paths
*/
-export function checkApi(api: T) {
- // check if no duplicate path
+export function checkApi(
+ api: T
+) {
const paths = new Set();
for (let endpoint of api) {
const fullpath = `${endpoint.method} ${endpoint.path}`;
@@ -58,13 +53,21 @@ export function checkApi(api: T) {
* @param api - api definitions
* @returns the api definitions
*/
-export function makeApi(
- api: Narrow
+export function makeApi(
+ api: Api
): Api {
checkApi(api);
- return api as Api;
+ return api;
}
+const test = makeApi([
+ {
+ method: "get",
+ path: "/test",
+ response: {},
+ },
+]);
+
/**
* Simple helper to split your parameter definitions into multiple files
* Mandatory to be used when declaring parameters appart from your endpoint definitions
@@ -73,9 +76,9 @@ export function makeApi(
* @returns the api parameter definitions
*/
export function makeParameters<
- ParameterDescriptions extends ZodiosEndpointParameter[]
->(params: Narrow): ParameterDescriptions {
- return params as ParameterDescriptions;
+ const ParameterDescriptions extends readonly ZodiosEndpointParameter[]
+>(params: ParameterDescriptions) {
+ return params;
}
export function parametersBuilder() {
@@ -84,7 +87,7 @@ export function parametersBuilder() {
type ObjectToQueryParameters<
Type extends "Query" | "Path" | "Header",
- T extends Record>,
+ T extends Record,
Keys = UnionToTuple
> = {
[Index in keyof Keys]: {
@@ -101,24 +104,20 @@ class ParametersBuilder {
addParameter<
Name extends string,
Type extends "Path" | "Query" | "Body" | "Header",
- Schema extends z.ZodType
- >(name: Name, type: Type, schema: Schema) {
+ Schema
+ >(name: Name, type: Type, schema: Schema, description?: string) {
return new ParametersBuilder<
[...T, { name: Name; type: Type; description?: string; schema: Schema }]
- >([
- ...this.params,
- { name, type, description: schema.description, schema },
- ]);
+ >([...this.params, { name, type, description, schema }]);
}
addParameters<
Type extends "Query" | "Path" | "Header",
- Schemas extends Record>
+ Schemas extends Record
>(type: Type, schemas: Schemas) {
const parameters = Object.keys(schemas).map((key) => ({
name: key,
type,
- description: schemas[key].description,
schema: schemas[key],
}));
return new ParametersBuilder<
@@ -132,46 +131,31 @@ class ParametersBuilder {
>([...this.params, ...parameters] as any);
}
- addBody>(schema: Schema) {
+ addBody(schema: Schema) {
return this.addParameter("body", "Body", schema);
}
- addQuery>(
- name: Name,
- schema: Schema
- ) {
+ addQuery(name: Name, schema: Schema) {
return this.addParameter(name, "Query", schema);
}
- addPath>(
- name: Name,
- schema: Schema
- ) {
+ addPath(name: Name, schema: Schema) {
return this.addParameter(name, "Path", schema);
}
- addHeader>(
- name: Name,
- schema: Schema
- ) {
+ addHeader(name: Name, schema: Schema) {
return this.addParameter(name, "Header", schema);
}
- addQueries>>(
- schemas: Schemas
- ) {
+ addQueries>(schemas: Schemas) {
return this.addParameters("Query", schemas);
}
- addPaths>>(
- schemas: Schemas
- ) {
+ addPaths>(schemas: Schemas) {
return this.addParameters("Path", schemas);
}
- addHeaders>>(
- schemas: Schemas
- ) {
+ addHeaders>(schemas: Schemas) {
return this.addParameters("Header", schemas);
}
@@ -187,10 +171,10 @@ class ParametersBuilder {
* @param errors - api error definitions
* @returns the error definitions
*/
-export function makeErrors(
- errors: Narrow
-): ErrorDescription {
- return errors as ErrorDescription;
+export function makeErrors<
+ const ErrorDescription extends readonly ZodiosEndpointError[]
+>(errors: ErrorDescription) {
+ return errors;
}
/**
@@ -200,14 +184,15 @@ export function makeErrors(
* @param endpoint - api endpoint definition
* @returns the endpoint definition
*/
-export function makeEndpoint>(
- endpoint: Narrow
-): T {
- return endpoint as T;
+export function makeEndpoint<
+ const EndpointDescription extends ZodiosEndpointDefinition
+>(endpoint: EndpointDescription) {
+ return endpoint;
}
-export class Builder {
+
+export class Builder {
constructor(private api: T) {}
- addEndpoint(endpoint: Narrow) {
+ addEndpoint(endpoint: E) {
return new Builder<[...T, E]>([...this.api, endpoint] as [...T, E]);
}
build(): T {
@@ -222,112 +207,12 @@ export class Builder {
* @param endpoint
* @returns - a builder to build your api definitions
*/
-export function apiBuilder>(
- endpoint: Narrow
+export function apiBuilder(
+ endpoint: T
): Builder<[T]> {
return new Builder([endpoint] as [T]);
}
-/**
- * Helper to generate a basic CRUD api for a given resource
- * @param resource - the resource to generate the api for
- * @param schema - the schema of the resource
- * @returns - the api definitions
- */
-export function makeCrudApi<
- T extends string,
- S extends z.ZodObject
->(resource: T, schema: S) {
- type Schema = z.input;
- const capitalizedResource = capitalize(resource);
- return makeApi([
- {
- method: "get",
- // @ts-expect-error
- path: `/${resource}s`,
- // @ts-expect-error
- alias: `get${capitalizedResource}s`,
- description: `Get all ${resource}s`,
- response: z.array(schema),
- },
- {
- method: "get",
- // @ts-expect-error
- path: `/${resource}s/:id`,
- // @ts-expect-error
- alias: `get${capitalizedResource}`,
- description: `Get a ${resource}`,
- // @ts-expect-error
- response: schema,
- },
- {
- method: "post",
- // @ts-expect-error
- path: `/${resource}s`,
- // @ts-expect-error
- alias: `create${capitalizedResource}`,
- description: `Create a ${resource}`,
- parameters: [
- {
- name: "body",
- type: "Body",
- description: "The object to create",
- schema: schema.partial() as z.Schema>,
- },
- ],
- // @ts-expect-error
- response: schema,
- },
- {
- method: "put",
- // @ts-expect-error
- path: `/${resource}s/:id`,
- // @ts-expect-error
- alias: `update${capitalizedResource}`,
- description: `Update a ${resource}`,
- parameters: [
- {
- name: "body",
- type: "Body",
- description: "The object to update",
- // @ts-expect-error
- schema: schema,
- },
- ],
- // @ts-expect-error
- response: schema,
- },
- {
- method: "patch",
- // @ts-expect-error
- path: `/${resource}s/:id`,
- // @ts-expect-error
- alias: `patch${capitalizedResource}`,
- description: `Patch a ${resource}`,
- parameters: [
- {
- name: "body",
- type: "Body",
- description: "The object to patch",
- schema: schema.partial() as z.Schema>,
- },
- ],
- // @ts-expect-error
- response: schema,
- },
- {
- method: "delete",
- // @ts-expect-error
- path: `/${resource}s/:id`,
- // @ts-expect-error
- alias: `delete${capitalizedResource}`,
- description: `Delete a ${resource}`,
- // @ts-expect-error
- response: schema,
- },
- ]);
-}
-
type CleanPath = Path extends `${infer PClean}/`
? PClean
: Path;
@@ -354,7 +239,7 @@ type MapApiPath<
: Acc;
type MergeApis<
- Apis extends Record,
+ Apis extends Record,
MergedPathApis = UnionToTuple<
{
[K in keyof Apis]: K extends string ? MapApiPath : never;
@@ -374,7 +259,7 @@ function cleanPath(path: string) {
*/
export function prefixApi<
Prefix extends string,
- Api extends ZodiosEndpointDefinition[]
+ const Api extends readonly ZodiosEndpointDefinition[]
>(prefix: Prefix, api: Api) {
return api.map((endpoint) => ({
...endpoint,
@@ -396,7 +281,7 @@ export function prefixApi<
* ```
*/
export function mergeApis<
- Apis extends Record
+ const Apis extends Record
>(apis: Apis): MergeApis {
return Object.keys(apis).flatMap((key) => prefixApi(key, apis[key])) as any;
}
diff --git a/packages/core/src/fetcher-providers/fetcher-provider.types.ts b/packages/core/src/fetcher-providers/fetcher-provider.types.ts
new file mode 100644
index 00000000..26e957f4
--- /dev/null
+++ b/packages/core/src/fetcher-providers/fetcher-provider.types.ts
@@ -0,0 +1,67 @@
+import { Merge, ReadonlyDeep } from "../utils.types";
+import { AnyZodiosRequestOptions } from "../zodios.types";
+
+/**
+ * A type provider for Fetcher
+ * allows to define request, response and error types for a fetcher
+ */
+export interface AnyZodiosFetcherProvider {
+ /**
+ * inputs types to call fetcher
+ */
+ arg1: unknown;
+ arg2: unknown;
+
+ /**
+ * config types to call fetcher
+ */
+ options: unknown;
+ config: unknown;
+ response: any;
+ error: any;
+}
+
+export type TypeOfFetcherConfig<
+ FetcherProvider extends AnyZodiosFetcherProvider
+> = FetcherProvider["config"];
+
+export type TypeOfFetcherError<
+ FetcherProvider extends AnyZodiosFetcherProvider,
+ Response,
+ Status
+> = (FetcherProvider & {
+ arg1: Response;
+ arg2: Status;
+})["error"];
+
+export type TypeOfFetcherResponse<
+ FetcherProvider extends AnyZodiosFetcherProvider
+> = FetcherProvider["response"];
+
+export type TypeOfFetcherOptions<
+ FetcherProvider extends AnyZodiosFetcherProvider
+> = FetcherProvider["options"];
+
+export interface ZodiosFetcher<
+ FetcherProvider extends AnyZodiosFetcherProvider
+> {
+ baseURL?: string;
+ fetch(
+ config: ReadonlyDeep>
+ ): Promise>;
+}
+
+export type ZodiosFetcherFactoryOptions<
+ FetcherProvider extends AnyZodiosFetcherProvider
+> = Merge<
+ {
+ baseURL?: string;
+ },
+ TypeOfFetcherOptions
+>;
+
+export type ZodiosFetcherFactory<
+ FetcherProvider extends AnyZodiosFetcherProvider
+> = (
+ options?: ZodiosFetcherFactoryOptions
+) => ZodiosFetcher;
diff --git a/packages/core/src/fetcher-providers/index.ts b/packages/core/src/fetcher-providers/index.ts
new file mode 100644
index 00000000..0d65dafe
--- /dev/null
+++ b/packages/core/src/fetcher-providers/index.ts
@@ -0,0 +1 @@
+export * from "./fetcher-provider.types";
diff --git a/packages/core/src/fetcher-providers/mock-provider.ts b/packages/core/src/fetcher-providers/mock-provider.ts
new file mode 100644
index 00000000..451c9698
--- /dev/null
+++ b/packages/core/src/fetcher-providers/mock-provider.ts
@@ -0,0 +1,130 @@
+import { setFetcherHook, clearFetcherHook } from "../index";
+
+import type {
+ AnyZodiosFetcherProvider,
+ AnyZodiosRequestOptions,
+ ZodiosFetcherFactory,
+} from "../index";
+
+interface MockError {
+ status: S;
+ response: {
+ status: S;
+ data: T;
+ };
+}
+
+export interface MockProvider extends AnyZodiosFetcherProvider {
+ options: {};
+ config: {
+ baseURL?: string;
+ body?: unknown;
+ auth?: { username: string; password: string };
+ validateStatus?: (status: number) => boolean;
+ timeout?: number;
+ responseType?: "arraybuffer" | "blob" | "json" | "text" | "stream";
+ };
+ response: unknown;
+ error: MockError;
+}
+
+export const mockFetchFactory: ZodiosFetcherFactory = (
+ options
+) => ({
+ async fetch(config) {
+ const requestConfig = {
+ ...config,
+ baseURL: options?.baseURL,
+ };
+ for (const [{ method, url }, callback] of registeredMocks) {
+ if (method === requestConfig.method && url === requestConfig.url) {
+ const result = {
+ status: 200,
+ statusText: "OK",
+ headers: {},
+ data: {},
+ ...(await callback(requestConfig)),
+ } as Required;
+ if (
+ (config.validateStatus && !config.validateStatus(result.status)) ||
+ result.status > 299
+ ) {
+ const err = new Error(
+ `Request failed with status code ${result.status}`
+ ) as Error & { code: string; config: any; response: any };
+ err.code = `ERR_STATUS_${result.status}`;
+ err.config = requestConfig;
+ err.response = result;
+ throw err;
+ }
+ return result;
+ }
+ }
+ throw new Error(`No mocks found for ${requestConfig.url}`);
+ },
+});
+
+type MockResponse = {
+ readonly headers?: Record;
+ readonly status?: number;
+ readonly statusText?: string;
+ readonly data?: Data;
+};
+
+interface ZodiosMockBase {
+ install(): void;
+ uninstall(): void;
+ reset(): void;
+ mockRequest(
+ method: string,
+ path: string,
+ callback: (
+ config: AnyZodiosRequestOptions
+ ) => Promise
+ ): void;
+ mockResponse(method: string, path: string, response: MockResponse): void;
+}
+
+const registeredMocks = new Map<
+ { method: string; url: string },
+ (config: AnyZodiosRequestOptions) => Promise
+>();
+
+export const zodiosMocks: ZodiosMockBase = {
+ install() {
+ const fetcher = mockFetchFactory();
+ setFetcherHook(fetcher);
+ },
+ uninstall() {
+ registeredMocks.clear();
+ clearFetcherHook();
+ },
+ reset() {
+ registeredMocks.clear();
+ },
+ mockRequest(
+ method: string,
+ path: string,
+ callback: (
+ config: AnyZodiosRequestOptions
+ ) => Promise
+ ) {
+ registeredMocks.set({ method, url: path }, callback);
+ },
+ mockResponse(method: string, path: string, response: MockResponse) {
+ registeredMocks.set(
+ {
+ method,
+ url: path,
+ },
+ () =>
+ Promise.resolve({
+ headers: {},
+ data: {},
+ status: 200,
+ statusText: "OK",
+ ...response,
+ })
+ );
+ },
+};
diff --git a/packages/core/src/hooks.ts b/packages/core/src/hooks.ts
new file mode 100644
index 00000000..f4570c31
--- /dev/null
+++ b/packages/core/src/hooks.ts
@@ -0,0 +1,18 @@
+import {
+ AnyZodiosFetcherProvider,
+ ZodiosFetcher,
+} from "./fetcher-providers/fetcher-provider.types";
+
+export const hooks: {
+ fetcher?: ZodiosFetcher;
+} = {};
+
+export function setFetcherHook(
+ fetcher: ZodiosFetcher
+) {
+ hooks.fetcher = fetcher;
+}
+
+export function clearFetcherHook() {
+ hooks.fetcher = undefined;
+}
diff --git a/src/index.ts b/packages/core/src/index.ts
similarity index 50%
rename from src/index.ts
rename to packages/core/src/index.ts
index e1b36f0a..127e094b 100644
--- a/src/index.ts
+++ b/packages/core/src/index.ts
@@ -1,8 +1,12 @@
-export { Zodios } from "./zodios";
-export type { ApiOf } from "./zodios";
-export type { ZodiosInstance, ZodiosClass, ZodiosConstructor } from "./zodios";
+export { ZodiosCore } from "./zodios";
+export type {
+ ApiOf,
+ TypeProviderOf,
+ FetcherProviderOf,
+ ZodiosInstance,
+ ZodiosBase,
+} from "./zodios";
export { ZodiosError } from "./zodios-error";
-export { isErrorFromPath, isErrorFromAlias } from "./zodios-error.utils";
export type {
AnyZodiosMethodOptions,
AnyZodiosRequestOptions,
@@ -24,27 +28,58 @@ export type {
ZodiosQueryParamsForEndpoint,
ZodiosQueryParamsByPath,
ZodiosQueryParamsByAlias,
- ZodiosEndpointDefinitionByPath,
- ZodiosEndpointDefinitionByAlias,
+ FindZodiosEndpointDefinitionByPath,
+ FindZodiosEndpointDefinitionByAlias,
ZodiosErrorForEndpoint,
ZodiosErrorByPath,
ZodiosErrorByAlias,
+ ZodiosErrorsByPath,
+ ZodiosErrorsByAlias,
ZodiosEndpointDefinition,
- ZodiosEndpointDefinitions,
ZodiosEndpointParameter,
- ZodiosEndpointParameters,
ZodiosEndpointError,
- ZodiosEndpointErrors,
ZodiosOptions,
ZodiosRequestOptions,
- ZodiosMethodOptions,
ZodiosRequestOptionsByPath,
ZodiosRequestOptionsByAlias,
ZodiosPlugin,
} from "./zodios.types";
export {
- PluginId,
- zodValidationPlugin,
+ HTTP_METHODS,
+ HTTP_MUTATION_METHODS,
+ HTTP_QUERY_METHODS,
+} from "./zodios.types";
+export type {
+ AnyZodiosTypeProvider,
+ InferInputTypeFromSchema,
+ InferOutputTypeFromSchema,
+ IoTsTypeProvider,
+ TsTypeProvider,
+ ZodiosRuntimeTypeProvider,
+ ZodiosValidateResult,
+ ZodTypeProvider,
+} from "./type-providers";
+export {
+ ioTsTypeProvider,
+ tsTypeProvider,
+ zodTypeProvider,
+ tsSchema,
+ tsFnSchema,
+} from "./type-providers";
+export type {
+ AnyZodiosFetcherProvider,
+ TypeOfFetcherConfig,
+ TypeOfFetcherError,
+ TypeOfFetcherOptions,
+ TypeOfFetcherResponse,
+ ZodiosFetcherFactoryOptions,
+ ZodiosFetcherFactory,
+ ZodiosFetcher,
+} from "./fetcher-providers";
+export { setFetcherHook, clearFetcherHook } from "./hooks";
+export type { PluginId } from "./plugins";
+export {
+ schemaValidationPlugin,
formDataPlugin,
formURLPlugin,
headerPlugin,
@@ -52,7 +87,6 @@ export {
export {
makeApi,
- makeCrudApi,
apiBuilder,
parametersBuilder,
makeParameters,
diff --git a/src/plugins/form-data.plugin.ts b/packages/core/src/plugins/form-data.plugin.ts
similarity index 54%
rename from src/plugins/form-data.plugin.ts
rename to packages/core/src/plugins/form-data.plugin.ts
index 65d84e07..987eb39d 100644
--- a/src/plugins/form-data.plugin.ts
+++ b/packages/core/src/plugins/form-data.plugin.ts
@@ -1,27 +1,7 @@
import { getFormDataStream } from "./form-data.utils";
import { ZodiosError } from "../zodios-error";
import type { ZodiosPlugin } from "../zodios.types";
-
-const plugin: ZodiosPlugin = {
- name: "form-data",
- request: async (_, config) => {
- if (typeof config.data !== "object" || Array.isArray(config.data)) {
- throw new ZodiosError(
- "Zodios: multipart/form-data body must be an object",
- config
- );
- }
- const result = getFormDataStream(config.data as any);
- return {
- ...config,
- data: result.data,
- headers: {
- ...config.headers,
- ...result.headers,
- },
- };
- },
-};
+import { AnyZodiosFetcherProvider } from "../fetcher-providers";
/**
* form-data plugin used internally by Zodios.
@@ -53,6 +33,31 @@ const plugin: ZodiosPlugin = {
* ```
* @returns form-data plugin
*/
-export function formDataPlugin(): ZodiosPlugin {
- return plugin;
+export function formDataPlugin<
+ FetcherProvider extends AnyZodiosFetcherProvider
+>(): ZodiosPlugin {
+ return {
+ name: "form-data",
+ request: async (_, config) => {
+ if (
+ !config.body ||
+ typeof config.body !== "object" ||
+ Array.isArray(config.body)
+ ) {
+ throw new ZodiosError(
+ "Zodios: multipart/form-data body must be an object",
+ config
+ );
+ }
+ const result = getFormDataStream(config.body as any);
+ return {
+ ...config,
+ body: result.data,
+ headers: {
+ ...config.headers,
+ ...result.headers,
+ },
+ };
+ },
+ };
}
diff --git a/src/plugins/form-data.utils.ts b/packages/core/src/plugins/form-data.utils.ts
similarity index 100%
rename from src/plugins/form-data.utils.ts
rename to packages/core/src/plugins/form-data.utils.ts
diff --git a/src/plugins/form-url.plugin.ts b/packages/core/src/plugins/form-url.plugin.ts
similarity index 52%
rename from src/plugins/form-url.plugin.ts
rename to packages/core/src/plugins/form-url.plugin.ts
index 7cee181c..c553474c 100644
--- a/src/plugins/form-url.plugin.ts
+++ b/packages/core/src/plugins/form-url.plugin.ts
@@ -1,27 +1,7 @@
+import { AnyZodiosFetcherProvider } from "../fetcher-providers";
import { ZodiosError } from "../zodios-error";
import type { ZodiosPlugin } from "../zodios.types";
-const plugin: ZodiosPlugin = {
- name: "form-url",
- request: async (_, config) => {
- if (typeof config.data !== "object" || Array.isArray(config.data)) {
- throw new ZodiosError(
- "Zodios: application/x-www-form-urlencoded body must be an object",
- config
- );
- }
-
- return {
- ...config,
- data: new URLSearchParams(config.data as any).toString(),
- headers: {
- ...config.headers,
- "Content-Type": "application/x-www-form-urlencoded",
- },
- };
- },
-};
-
/**
* form-url plugin used internally by Zodios.
* @example
@@ -53,6 +33,31 @@ const plugin: ZodiosPlugin = {
* ```
* @returns form-url plugin
*/
-export function formURLPlugin(): ZodiosPlugin {
- return plugin;
+export function formURLPlugin<
+ FetcherProvider extends AnyZodiosFetcherProvider
+>(): ZodiosPlugin {
+ return {
+ name: "form-url",
+ request: async (_, config) => {
+ if (
+ !config.body ||
+ typeof config.body !== "object" ||
+ Array.isArray(config.body)
+ ) {
+ throw new ZodiosError(
+ "Zodios: application/x-www-form-urlencoded body must be an object",
+ config
+ );
+ }
+
+ return {
+ ...config,
+ body: new URLSearchParams(config.body as any).toString(),
+ headers: {
+ ...config.headers,
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ };
+ },
+ };
}
diff --git a/src/plugins/header.plugin.ts b/packages/core/src/plugins/header.plugin.ts
similarity index 50%
rename from src/plugins/header.plugin.ts
rename to packages/core/src/plugins/header.plugin.ts
index ea9d7234..580b51f7 100644
--- a/src/plugins/header.plugin.ts
+++ b/packages/core/src/plugins/header.plugin.ts
@@ -1,6 +1,9 @@
+import { AnyZodiosFetcherProvider } from "../fetcher-providers";
import type { ZodiosPlugin } from "../zodios.types";
-export function headerPlugin(key: string, value: string): ZodiosPlugin {
+export function headerPlugin<
+ FetcherProvider extends AnyZodiosFetcherProvider = AnyZodiosFetcherProvider
+>(key: string, value: string): ZodiosPlugin {
return {
request: async (_, config) => {
return {
diff --git a/src/plugins/index.ts b/packages/core/src/plugins/index.ts
similarity index 59%
rename from src/plugins/index.ts
rename to packages/core/src/plugins/index.ts
index be1f6cdf..09b66505 100644
--- a/src/plugins/index.ts
+++ b/packages/core/src/plugins/index.ts
@@ -1,5 +1,6 @@
export * from "./form-data.plugin";
export * from "./form-url.plugin";
export * from "./header.plugin";
-export * from "./zod-validation.plugin";
+export * from "./validation.plugin";
export * from "./zodios-plugins";
+export type { PluginId } from "./zodios-plugins.types";
diff --git a/src/plugins/zod-validation.plugin.test.ts b/packages/core/src/plugins/validation.plugin.test.ts
similarity index 81%
rename from src/plugins/zod-validation.plugin.test.ts
rename to packages/core/src/plugins/validation.plugin.test.ts
index ec12250f..4a59b3d1 100644
--- a/src/plugins/zod-validation.plugin.test.ts
+++ b/packages/core/src/plugins/validation.plugin.test.ts
@@ -1,25 +1,29 @@
-import type { AxiosResponse } from "axios";
import { z } from "zod";
import { apiBuilder } from "../api";
import { ReadonlyDeep } from "../utils.types";
import { AnyZodiosRequestOptions } from "../zodios.types";
-import { zodValidationPlugin } from "./zod-validation.plugin";
+import { schemaValidationPlugin } from "./validation.plugin";
+import { zodTypeProvider } from "../type-providers";
+import { AnyZodiosFetcherProvider } from "../fetcher-providers";
-describe("zodValidationPlugin", () => {
- const plugin = zodValidationPlugin({
+describe("schemaValidationPlugin", () => {
+ const plugin = schemaValidationPlugin({
validate: true,
transform: true,
sendDefaults: false,
+ typeProvider: zodTypeProvider,
});
- const pluginWithDefaults = zodValidationPlugin({
+ const pluginWithDefaults = schemaValidationPlugin({
validate: true,
transform: true,
sendDefaults: true,
+ typeProvider: zodTypeProvider,
});
- const pluginWithoutTransform = zodValidationPlugin({
+ const pluginWithoutTransform = schemaValidationPlugin({
validate: true,
transform: false,
sendDefaults: false,
+ typeProvider: zodTypeProvider,
});
describe("request", () => {
@@ -27,19 +31,13 @@ describe("zodValidationPlugin", () => {
expect(plugin.request).toBeDefined();
});
- it("should throw if endpoint is not found", async () => {
- await expect(
- plugin.request!(api, notExistingConfig)
- ).rejects.toThrowError("No endpoint found for get /notExisting");
- });
-
it("should verify parameters", async () => {
const transformed = await plugin.request!(
- api,
+ api[0],
createSampleConfig("/parse")
);
- expect(transformed.data).toBe("123");
+ expect(transformed.body).toBe("123");
expect(transformed.queries).toStrictEqual({
sampleQueryParam: "456",
});
@@ -50,11 +48,11 @@ describe("zodValidationPlugin", () => {
it("should transform parameters", async () => {
const transformed = await plugin.request!(
- api,
+ api[2],
createSampleConfig("/transform")
);
- expect(transformed.data).toBe("123_transformed");
+ expect(transformed.body).toBe("123_transformed");
expect(transformed.queries).toStrictEqual({
sampleQueryParam: "456_transformed",
});
@@ -65,11 +63,11 @@ describe("zodValidationPlugin", () => {
it("should transform empty string parameters", async () => {
const transformed = await plugin.request!(
- api,
+ api[2],
createEmptySampleConfig("/transform")
);
- expect(transformed.data).toBe("_transformed");
+ expect(transformed.body).toBe("_transformed");
expect(transformed.queries).toStrictEqual({
sampleQueryParam: "_transformed",
});
@@ -80,7 +78,7 @@ describe("zodValidationPlugin", () => {
it("should generate default parameter when generateDefaults is activated", async () => {
const defaulted = await pluginWithDefaults.request!(
- api,
+ api[1],
createUndefinedSampleConfig("/defaults")
);
@@ -94,11 +92,11 @@ describe("zodValidationPlugin", () => {
it("should not transform parameters when transform is disabled", async () => {
const notTransformed = await pluginWithoutTransform.request!(
- api,
+ api[2],
createSampleConfig("/transform")
);
- expect(notTransformed.data).toBe("123");
+ expect(notTransformed.body).toBe("123");
expect(notTransformed.queries).toStrictEqual({
sampleQueryParam: "456",
});
@@ -109,11 +107,11 @@ describe("zodValidationPlugin", () => {
it("should transform parameters (async)", async () => {
const transformed = await plugin.request!(
- api,
+ api[3],
createSampleConfig("/transformAsync")
);
- expect(transformed.data).toBe("123_transformed");
+ expect(transformed.body).toBe("123_transformed");
expect(transformed.queries).toStrictEqual({
sampleQueryParam: "456_transformed",
});
@@ -124,11 +122,11 @@ describe("zodValidationPlugin", () => {
it("should not transform parameters (async) when transform is disabled", async () => {
const notTransformed = await pluginWithoutTransform.request!(
- api,
+ api[3],
createSampleConfig("/transformAsync")
);
- expect(notTransformed.data).toBe("123");
+ expect(notTransformed.body).toBe("123");
expect(notTransformed.queries).toStrictEqual({
sampleQueryParam: "456",
});
@@ -143,7 +141,7 @@ describe("zodValidationPlugin", () => {
sampleQueryParam: 123,
};
- await expect(plugin.request!(api, badConfig)).rejects.toThrowError(
+ await expect(plugin.request!(api[0], badConfig)).rejects.toThrowError(
"Zodios: Invalid Query parameter 'sampleQueryParam'"
);
});
@@ -154,15 +152,9 @@ describe("zodValidationPlugin", () => {
expect(plugin.response).toBeDefined();
});
- it("should throw if endpoint is not found", async () => {
- await expect(
- plugin.response!(api, notExistingConfig, createSampleResponse())
- ).rejects.toThrowError("No endpoint found for get /notExisting");
- });
-
it("should verify body", async () => {
const transformed = await plugin.response!(
- api,
+ api[0],
createSampleConfig("/parse"),
createSampleResponse()
);
@@ -175,7 +167,7 @@ describe("zodValidationPlugin", () => {
it("should transform body", async () => {
const transformed = await plugin.response!(
- api,
+ api[2],
createSampleConfig("/transform"),
createSampleResponse()
);
@@ -188,7 +180,7 @@ describe("zodValidationPlugin", () => {
it("should not transform body when transform is disabled", async () => {
const notTransformed = await pluginWithoutTransform.response!(
- api,
+ api[2],
createSampleConfig("/transform"),
createSampleResponse()
);
@@ -201,7 +193,7 @@ describe("zodValidationPlugin", () => {
it("should transform body (async)", async () => {
const transformed = await plugin.response!(
- api,
+ api[3],
createSampleConfig("/transformAsync"),
createSampleResponse()
);
@@ -214,7 +206,7 @@ describe("zodValidationPlugin", () => {
it("should not transform body (async) when transform is disabled", async () => {
const notTransformed = await pluginWithoutTransform.response!(
- api,
+ api[3],
createSampleConfig("/transformAsync"),
createSampleResponse()
);
@@ -227,10 +219,11 @@ describe("zodValidationPlugin", () => {
it("should throw on unsuccessful parse", async () => {
const badResponse = createSampleResponse();
+ // @ts-expect-error
badResponse.data.first = 123;
await expect(
- plugin.response!(api, createSampleConfig("/parse"), badResponse)
+ plugin.response!(api[0], createSampleConfig("/parse"), badResponse)
).rejects
.toThrowError(`Zodios: Invalid response from endpoint 'post /parse'
status: 200 OK
@@ -254,15 +247,19 @@ received:
});
});
- const notExistingConfig: ReadonlyDeep = {
+ const notExistingConfig: ReadonlyDeep<
+ AnyZodiosRequestOptions
+ > = {
method: "get",
url: "/notExisting",
};
- const createSampleConfig = (url: string): AnyZodiosRequestOptions => ({
+ const createSampleConfig = (
+ url: string
+ ): AnyZodiosRequestOptions => ({
method: "post",
url,
- data: "123",
+ body: "123",
queries: {
sampleQueryParam: "456",
},
@@ -271,10 +268,12 @@ received:
},
});
- const createEmptySampleConfig = (url: string): AnyZodiosRequestOptions => ({
+ const createEmptySampleConfig = (
+ url: string
+ ): AnyZodiosRequestOptions => ({
method: "post",
url,
- data: "",
+ body: "",
queries: {
sampleQueryParam: "",
},
@@ -285,24 +284,23 @@ received:
const createUndefinedSampleConfig = (
url: string
- ): AnyZodiosRequestOptions => ({
+ ): AnyZodiosRequestOptions => ({
method: "get",
url,
});
- const createSampleResponse = () =>
- ({
- data: {
- first: "123",
- second: 111,
- },
- status: 200,
- headers: {
- "content-type": "application/json",
- },
- config: {},
- statusText: "OK",
- } as unknown as AxiosResponse);
+ const createSampleResponse = () => ({
+ data: {
+ first: "123",
+ second: 111,
+ },
+ status: 200,
+ headers: {
+ "content-type": "application/json",
+ },
+ config: {},
+ statusText: "OK",
+ });
const api = apiBuilder({
path: "/parse",
diff --git a/src/plugins/zod-validation.plugin.ts b/packages/core/src/plugins/validation.plugin.ts
similarity index 63%
rename from src/plugins/zod-validation.plugin.ts
rename to packages/core/src/plugins/validation.plugin.ts
index af8c035a..a85974bb 100644
--- a/src/plugins/zod-validation.plugin.ts
+++ b/packages/core/src/plugins/validation.plugin.ts
@@ -1,9 +1,16 @@
import { ZodiosError } from "../zodios-error";
+import type { AnyZodiosTypeProvider } from "../type-providers";
import type { ZodiosOptions, ZodiosPlugin } from "../zodios.types";
-import { findEndpoint } from "../utils";
+import { AnyZodiosFetcherProvider } from "../fetcher-providers";
-type Options = Required<
- Pick
+type Options<
+ FetcherProvider extends AnyZodiosFetcherProvider,
+ TypeProvider extends AnyZodiosTypeProvider
+> = Required<
+ Pick<
+ ZodiosOptions,
+ "validate" | "transform" | "sendDefaults" | "typeProvider"
+ >
>;
function shouldResponse(option: string | boolean) {
@@ -15,25 +22,23 @@ function shouldRequest(option: string | boolean) {
}
/**
- * Zod validation plugin used internally by Zodios.
+ * alidation plugin used internally by Zodios.
* By default zodios always validates the response.
- * @returns zod-validation plugin
+ * @returns schema-validation plugin
*/
-export function zodValidationPlugin({
+export function schemaValidationPlugin<
+ FetcherProvider extends AnyZodiosFetcherProvider,
+ TypeProvider extends AnyZodiosTypeProvider
+>({
validate,
transform,
sendDefaults,
-}: Options): ZodiosPlugin {
+ typeProvider,
+}: Options): ZodiosPlugin {
return {
- name: "zod-validation",
+ name: "schema-validation",
request: shouldRequest(validate)
- ? async (api, config) => {
- const endpoint = findEndpoint(api, config.method, config.url);
- if (!endpoint) {
- throw new Error(
- `No endpoint found for ${config.method} ${config.url}`
- );
- }
+ ? async (endpoint, config) => {
const { parameters } = endpoint;
if (!parameters) {
return config;
@@ -49,16 +54,17 @@ export function zodValidationPlugin({
params: {
...config.params,
},
+ body: config.body,
};
const paramsOf = {
Query: (name: string) => conf.queries?.[name],
- Body: (_: string) => conf.data,
+ Body: (_: string) => conf.body,
Header: (name: string) => conf.headers?.[name],
Path: (name: string) => conf.params?.[name],
};
const setParamsOf = {
Query: (name: string, value: any) => (conf.queries![name] = value),
- Body: (_: string, value: any) => (conf.data = value),
+ Body: (_: string, value: any) => (conf.body = value),
Header: (name: string, value: any) => (conf.headers![name] = value),
Path: (name: string, value: any) => (conf.params![name] = value),
};
@@ -67,7 +73,7 @@ export function zodValidationPlugin({
const { name, schema, type } = parameter;
const value = paramsOf[type](name);
if (sendDefaults || value !== undefined) {
- const parsed = await schema.safeParseAsync(value);
+ const parsed = await typeProvider.validateAsync(schema, value);
if (!parsed.success) {
throw new ZodiosError(
`Zodios: Invalid ${type} parameter '${name}'`,
@@ -85,18 +91,18 @@ export function zodValidationPlugin({
}
: undefined,
response: shouldResponse(validate)
- ? async (api, config, response) => {
- const endpoint = findEndpoint(api, config.method, config.url);
- /* istanbul ignore next */
- if (!endpoint) {
- throw new Error(
- `No endpoint found for ${config.method} ${config.url}`
- );
- }
+ ? async (endpoint, config, response) => {
if (
- response.headers?.["content-type"]?.includes("application/json")
+ typeof response.headers?.get === "function"
+ ? (response.headers.get("content-type") as string)?.includes?.(
+ "application/json"
+ )
+ : response.headers?.["content-type"]?.includes?.(
+ "application/json"
+ )
) {
- const parsed = await endpoint.response.safeParseAsync(
+ const parsed = await typeProvider.validateAsync(
+ endpoint.response,
response.data
);
if (!parsed.success) {
@@ -105,11 +111,9 @@ export function zodValidationPlugin({
endpoint.path
}'\nstatus: ${response.status} ${
response.statusText
- }\ncause:\n${parsed.error.message}\nreceived:\n${JSON.stringify(
- response.data,
- null,
- 2
- )}`,
+ }\ncause:\n${
+ parsed.error.message ?? JSON.stringify(parsed.error)
+ }\nreceived:\n${JSON.stringify(response.data, null, 2)}`,
config,
response.data,
parsed.error
diff --git a/packages/core/src/plugins/zodios-plugins.test.ts b/packages/core/src/plugins/zodios-plugins.test.ts
new file mode 100644
index 00000000..6a3f6b5d
--- /dev/null
+++ b/packages/core/src/plugins/zodios-plugins.test.ts
@@ -0,0 +1,89 @@
+import { AnyZodiosFetcherProvider } from "../fetcher-providers";
+import { tsSchema } from "../type-providers";
+import { ZodiosEndpointDefinition, ZodiosPlugin } from "../zodios.types";
+import { ZodiosPlugins } from "./zodios-plugins";
+
+const testEndpoint: ZodiosEndpointDefinition = {
+ method: "get",
+ path: "/test",
+ alias: "getTest",
+ response: tsSchema<{ test: string }>(),
+};
+
+describe("ZodiosPlugins", () => {
+ it("should be defined", () => {
+ expect(ZodiosPlugins).toBeDefined();
+ });
+
+ it("should register one plugin", () => {
+ const plugins = new ZodiosPlugins();
+ const plugin: ZodiosPlugin = {
+ request: async (endpoint, config) => config,
+ response: async (endpoint, config, response) => response,
+ };
+ const id = plugins.use({}, plugin);
+ expect(id).toBe(0);
+ });
+
+ it("should unregister one plugin", () => {
+ const plugins = new ZodiosPlugins();
+ const plugin: ZodiosPlugin = {
+ request: async (api, config) => config,
+ response: async (api, config, response) => response,
+ };
+ const id = plugins.use({}, plugin);
+ plugins.eject(id);
+ // @ts-ignore
+ expect(plugins.plugins.filter((filter) => filter.plugin).length).toBe(0);
+ });
+
+ it("should execute response plugins consistently", async () => {
+ const plugins = new ZodiosPlugins();
+ const plugin1: ZodiosPlugin = {
+ request: async (api, config) => config,
+ response: async (api, config, response) => {
+ response.data += "1";
+ return response;
+ },
+ };
+ plugins.use({}, plugin1);
+ const plugin2: ZodiosPlugin = {
+ request: async (api, config) => config,
+ response: async (api, config, response) => {
+ response.data += "2";
+ return response;
+ },
+ };
+ plugins.use({}, plugin2);
+ const response1 = await plugins.interceptResponse(
+ testEndpoint,
+ // @ts-ignore
+ {},
+ Promise.resolve({ data: "test1:" })
+ );
+ expect(response1.data).toBe("test1:21");
+ const response2 = await plugins.interceptResponse(
+ testEndpoint,
+ // @ts-ignore
+ {},
+ Promise.resolve({ data: "test2:" })
+ );
+ expect(response2.data).toBe("test2:21");
+ });
+
+ it('should catch error if plugin "error" is defined', async () => {
+ const plugins = new ZodiosPlugins();
+ const plugin: ZodiosPlugin = {
+ request: async (api, config) => config,
+ error: async (api, config, error) => ({ test: true }),
+ };
+ plugins.use({}, plugin);
+ const response = await plugins.interceptResponse(
+ testEndpoint,
+ // @ts-ignore
+ { method: "any", url: "any" },
+ Promise.reject(new Error("test"))
+ );
+ expect(response).toEqual({ test: true });
+ });
+});
diff --git a/packages/core/src/plugins/zodios-plugins.ts b/packages/core/src/plugins/zodios-plugins.ts
new file mode 100644
index 00000000..77877d82
--- /dev/null
+++ b/packages/core/src/plugins/zodios-plugins.ts
@@ -0,0 +1,149 @@
+import type {
+ AnyZodiosFetcherProvider,
+ TypeOfFetcherResponse,
+} from "../fetcher-providers";
+import type { ReadonlyDeep } from "../utils.types";
+import type {
+ AnyZodiosRequestOptions,
+ ZodiosEndpointDefinition,
+ ZodiosPlugin,
+} from "../zodios.types";
+import {
+ PluginId,
+ ZodiosPluginRegistration,
+ RequiredZodiosPluginRegistration,
+ ZodiosPluginFilters,
+ PluginPriority,
+ PLUGIN_PRIORITIES_REQUEST,
+ PLUGIN_PRIORITIES_RESPONSE,
+ PluginPriorities,
+} from "./zodios-plugins.types";
+
+const matchPluginFilter = (
+ endpoint: ZodiosEndpointDefinition,
+ filters: ZodiosPluginFilters
+) => {
+ return (Object.keys(filters) as (keyof ZodiosPluginFilters)[]).every(
+ (key) => {
+ const filter = filters[key];
+ const endpointValue = endpoint[key];
+ if (typeof filter === "string" && endpointValue) {
+ return filter === endpointValue;
+ }
+ if (filter instanceof RegExp && endpointValue) {
+ return filter.test(endpointValue);
+ }
+ if (typeof filter === "function") {
+ return filter(endpointValue ?? "");
+ }
+ return filter === undefined;
+ }
+ );
+};
+
+const isPluginFor =
+ (
+ endpoint: ZodiosEndpointDefinition,
+ priority: PluginPriority,
+ type: "request" | "response"
+ ) =>
+ (
+ plugin: ZodiosPluginRegistration
+ ): plugin is RequiredZodiosPluginRegistration => {
+ return (
+ plugin.priority === priority &&
+ Boolean(plugin.plugin) &&
+ Boolean(
+ type === "request"
+ ? plugin.plugin!.request
+ : plugin.plugin!.response || plugin.plugin!.error
+ ) &&
+ matchPluginFilter(endpoint, plugin.filter)
+ );
+ };
+export class ZodiosPlugins {
+ private plugins: Array> = [];
+
+ constructor() {}
+
+ /**
+ * register a plugin
+ * @param filter - how to match the plugin
+ * @param plugin - plugin to be registered
+ * @param priority - low, normal, high, default: normal
+ * @returns - plugin id to be used for ejecting
+ */
+ use(
+ filter: ZodiosPluginFilters,
+ plugin: ZodiosPlugin,
+ priority: PluginPriority = PluginPriorities.normal
+ ): PluginId {
+ this.plugins.push({
+ filter,
+ plugin,
+ priority,
+ });
+ return this.plugins.length - 1;
+ }
+ eject(id: PluginId) {
+ this.plugins[id].plugin = undefined;
+ }
+
+ /**
+ * intercept the request before it is sent to the server
+ * apply plugins in order of registration (internal plugins first)
+ * @param endpoint - endpoint definition
+ * @param config - request config
+ * @returns - modified request config
+ */
+ async interceptRequest(
+ endpoint: ZodiosEndpointDefinition,
+ config: ReadonlyDeep>
+ ) {
+ let pluginConfig = config;
+ for (const priority of PLUGIN_PRIORITIES_REQUEST) {
+ for (const plugin of this.plugins.filter(
+ isPluginFor(endpoint, priority, "request")
+ )) {
+ pluginConfig = await plugin.plugin.request(endpoint, pluginConfig);
+ }
+ }
+ return pluginConfig;
+ }
+
+ /**
+ * intercept the response before it is returned to the user
+ * apply plugins in reverse order of registration (user plugins first)
+ * @param endpoint - endpoint definition
+ * @param config - request config
+ * @param response - response promise from the server
+ * @returns - modified response promise
+ */
+ async interceptResponse(
+ endpoint: ZodiosEndpointDefinition,
+ config: ReadonlyDeep>,
+ response: Promise>
+ ) {
+ let pluginResponse = response;
+ const plugins = [...this.plugins].reverse();
+
+ for (const priority of PLUGIN_PRIORITIES_RESPONSE) {
+ for (const plugin of plugins.filter(
+ isPluginFor(endpoint, priority, "response")
+ )) {
+ pluginResponse = pluginResponse.then(
+ Boolean(plugin.plugin.response)
+ ? (res) => plugin.plugin.response(endpoint, config, res)
+ : undefined,
+ Boolean(plugin.plugin.error)
+ ? (err) => {
+ console.log("plugin error", err);
+ return plugin.plugin.error(endpoint, config, err);
+ }
+ : undefined
+ );
+ }
+ }
+ return pluginResponse;
+ }
+}
diff --git a/packages/core/src/plugins/zodios-plugins.types.ts b/packages/core/src/plugins/zodios-plugins.types.ts
new file mode 100644
index 00000000..2b897e7c
--- /dev/null
+++ b/packages/core/src/plugins/zodios-plugins.types.ts
@@ -0,0 +1,46 @@
+import { AnyZodiosFetcherProvider } from "../fetcher-providers";
+import { ZodiosPlugin } from "../zodios.types";
+
+export type PluginId = number;
+
+export const PluginPriorities = {
+ low: "low",
+ normal: "normal",
+ high: "high",
+} as const;
+
+export const PLUGIN_PRIORITIES_REQUEST = [
+ PluginPriorities.high,
+ PluginPriorities.normal,
+ PluginPriorities.low,
+] as const;
+
+export const PLUGIN_PRIORITIES_RESPONSE = [
+ PluginPriorities.low,
+ PluginPriorities.normal,
+ PluginPriorities.high,
+] as const;
+
+export type PluginPriority = keyof typeof PluginPriorities;
+
+export type ZodiosPluginFilters = {
+ method?: string | RegExp | ((method: string) => boolean);
+ path?: string | RegExp | ((path: string) => boolean);
+ alias?: string | RegExp | ((alias: string) => boolean);
+};
+
+export type ZodiosPluginRegistration<
+ FetcherProvider extends AnyZodiosFetcherProvider
+> = {
+ priority: PluginPriority;
+ filter: ZodiosPluginFilters;
+ plugin?: ZodiosPlugin;
+};
+
+export type RequiredZodiosPluginRegistration<
+ FetcherProvider extends AnyZodiosFetcherProvider
+> = {
+ priority: PluginPriority;
+ filter: ZodiosPluginFilters;
+ plugin: Required>;
+};
diff --git a/packages/core/src/type-providers/index.ts b/packages/core/src/type-providers/index.ts
new file mode 100644
index 00000000..d10fe1c0
--- /dev/null
+++ b/packages/core/src/type-providers/index.ts
@@ -0,0 +1,4 @@
+export * from "./type-provider.types";
+export * from "./type-provider.zod";
+export * from "./type-provider.io-ts";
+export * from "./type-provider.typescript";
diff --git a/packages/core/src/type-providers/type-provider.io-ts.ts b/packages/core/src/type-providers/type-provider.io-ts.ts
new file mode 100644
index 00000000..fd75c90d
--- /dev/null
+++ b/packages/core/src/type-providers/type-provider.io-ts.ts
@@ -0,0 +1,25 @@
+import {
+ AnyZodiosTypeProvider,
+ ZodiosRuntimeTypeProvider,
+} from "./type-provider.types";
+
+export interface IoTsTypeProvider
+ extends AnyZodiosTypeProvider<{ _A: unknown; _O: unknown }> {
+ input: this["schema"]["_O"];
+ output: this["schema"]["_A"];
+}
+
+export const ioTsTypeProvider: ZodiosRuntimeTypeProvider = {
+ validate: (schema, input) => {
+ const result = schema.decode(input);
+ return result._tag === "Right"
+ ? { success: true, data: result.right }
+ : { success: false, error: result.left };
+ },
+ validateAsync: async (schema, input) => {
+ const result = schema.decode(input);
+ return result._tag === "Right"
+ ? { success: true, data: result.right }
+ : { success: false, error: result.left };
+ },
+};
diff --git a/packages/core/src/type-providers/type-provider.test.ts b/packages/core/src/type-providers/type-provider.test.ts
new file mode 100644
index 00000000..23e9819e
--- /dev/null
+++ b/packages/core/src/type-providers/type-provider.test.ts
@@ -0,0 +1,84 @@
+import {
+ ioTsTypeProvider,
+ zodTypeProvider,
+ tsTypeProvider,
+ tsSchema,
+ tsFnSchema,
+} from "./index";
+import * as t from "io-ts";
+import z from "zod";
+import assert from "assert";
+
+describe("type-provider", () => {
+ describe("io-ts", () => {
+ it("should validate", async () => {
+ const schema = t.type({
+ name: t.string,
+ });
+ const result = ioTsTypeProvider.validate(schema, { name: "test" });
+ assert(result.success);
+ expect(result.data).toEqual({ name: "test" });
+ const result2 = await ioTsTypeProvider.validateAsync(schema, {
+ name: "test",
+ });
+ assert(result2.success);
+ expect(result2.data).toEqual({ name: "test" });
+ });
+ });
+ it("should not validate", async () => {
+ const schema = t.type({
+ name: t.string,
+ });
+ const result = ioTsTypeProvider.validate(schema, { names: "test" });
+ assert(!result.success);
+ expect(result.error).toBeDefined();
+ const result2 = await ioTsTypeProvider.validateAsync(schema, {
+ name: 2,
+ });
+ assert(!result2.success);
+ expect(result2.error).toBeDefined();
+ });
+ describe("zod", () => {
+ it("should validate", () => {
+ const schema = z.object({
+ name: z.string(),
+ });
+ const result = zodTypeProvider.validate(schema, { name: "test" });
+ assert(result.success);
+ expect(result.data).toEqual({ name: "test" });
+ });
+ });
+ it("should not validate", () => {
+ const schema = z.object({
+ name: z.string(),
+ });
+ const result = zodTypeProvider.validate(schema, { names: "test" });
+ assert(!result.success);
+ expect(result.error).toBeDefined();
+ });
+ describe("ts", () => {
+ it("should validate", async () => {
+ const schema = tsSchema<{ name: string }>();
+ const result = tsTypeProvider.validate(schema, { name: "test" });
+ assert(result.success);
+ expect(result.data).toEqual({ name: "test" });
+ const result2 = await tsTypeProvider.validateAsync(schema, {
+ name: "test",
+ });
+ assert(result2.success);
+ expect(result2.data).toEqual({ name: "test" });
+ });
+ });
+ it("should not validate", () => {
+ const schema = tsFnSchema((data) => {
+ if (!data || typeof data !== "object") throw new Error("not an object");
+ if (!("name" in data)) throw new Error("missing name");
+ // @ts-ignore
+ const { name } = data;
+ if (typeof name !== "string") throw new Error("name is not a string");
+ return data;
+ });
+ const result = tsTypeProvider.validate(schema, { names: "test" });
+ assert(!result.success);
+ });
+});
diff --git a/packages/core/src/type-providers/type-provider.types.ts b/packages/core/src/type-providers/type-provider.types.ts
new file mode 100644
index 00000000..8a7b9e14
--- /dev/null
+++ b/packages/core/src/type-providers/type-provider.types.ts
@@ -0,0 +1,27 @@
+export interface AnyZodiosTypeProvider {
+ schema: Schema;
+ input: unknown;
+ output: unknown;
+}
+
+export type InferInputTypeFromSchema<
+ TypeProvider extends AnyZodiosTypeProvider,
+ Schema
+> = (TypeProvider & { schema: Schema })["input"];
+
+export type InferOutputTypeFromSchema<
+ TypeProvider extends AnyZodiosTypeProvider,
+ Schema
+> = (TypeProvider & { schema: Schema })["output"];
+
+export type ZodiosValidateResult =
+ | { success: true; data: any }
+ | { success: false; error: any };
+
+export interface ZodiosRuntimeTypeProvider<
+ TypeProvider extends AnyZodiosTypeProvider
+> {
+ readonly _provider?: TypeProvider;
+ validate: (schema: any, input: unknown) => ZodiosValidateResult;
+ validateAsync: (schema: any, input: unknown) => Promise;
+}
diff --git a/packages/core/src/type-providers/type-provider.typescript.ts b/packages/core/src/type-providers/type-provider.typescript.ts
new file mode 100644
index 00000000..5116ee36
--- /dev/null
+++ b/packages/core/src/type-providers/type-provider.typescript.ts
@@ -0,0 +1,62 @@
+import {
+ AnyZodiosTypeProvider,
+ ZodiosRuntimeTypeProvider,
+ ZodiosValidateResult,
+} from "./type-provider.types";
+
+const genericTsSchema = {
+ parse: (data: unknown): ZodiosValidateResult => ({
+ success: true,
+ data,
+ }),
+};
+
+type TsSchema = {
+ readonly _schema: Schema;
+ parse: (input: unknown) => ZodiosValidateResult;
+};
+
+/**
+ * A basic typescript schema provider that does not do any validation but provides type inference
+ * @returns - a schema that can be used with the `tsTypeProvider`
+ */
+export const tsSchema = (): TsSchema => genericTsSchema as any;
+/**
+ * An advanced typescript schema provider where the schema is inferred from the
+ * output type of the throwing validation function
+ * @param throwingValidator - a function that throws if the input is invalid and returns the output type if the input is valid
+ * @returns - a schema that can be used with the `tsTypeProvider`
+ */
+export const tsFnSchema = (
+ throwingValidator: (data: unknown) => Schema
+): TsSchema => ({
+ _schema: undefined as Schema,
+ parse: (data: unknown): ZodiosValidateResult => {
+ try {
+ return {
+ success: true,
+ data: throwingValidator(data),
+ };
+ } catch (error) {
+ return {
+ success: false,
+ error,
+ };
+ }
+ },
+});
+
+export interface TsTypeProvider
+ extends AnyZodiosTypeProvider<{ _schema: unknown }> {
+ input: this["schema"]["_schema"];
+ output: this["schema"]["_schema"];
+}
+
+/**
+ * A native typescript type provider
+ * to use with the `tsSchema` and `tsFnSchema` functions
+ */
+export const tsTypeProvider: ZodiosRuntimeTypeProvider = {
+ validate: (schema, input) => schema.parse(input),
+ validateAsync: (schema, input) => schema.parse(input),
+};
diff --git a/packages/core/src/type-providers/type-provider.zod.ts b/packages/core/src/type-providers/type-provider.zod.ts
new file mode 100644
index 00000000..447a3d81
--- /dev/null
+++ b/packages/core/src/type-providers/type-provider.zod.ts
@@ -0,0 +1,15 @@
+import {
+ AnyZodiosTypeProvider,
+ ZodiosRuntimeTypeProvider,
+} from "./type-provider.types";
+
+export interface ZodTypeProvider
+ extends AnyZodiosTypeProvider<{ _input: unknown; _output: unknown }> {
+ input: this["schema"]["_input"];
+ output: this["schema"]["_output"];
+}
+
+export const zodTypeProvider: ZodiosRuntimeTypeProvider = {
+ validate: (schema, input) => schema.safeParse(input),
+ validateAsync: (schema, input) => schema.safeParseAsync(input),
+};
diff --git a/src/utils.test.ts b/packages/core/src/utils.test.ts
similarity index 100%
rename from src/utils.test.ts
rename to packages/core/src/utils.test.ts
diff --git a/src/utils.ts b/packages/core/src/utils.ts
similarity index 69%
rename from src/utils.ts
rename to packages/core/src/utils.ts
index 310fb1e3..2ab75e59 100644
--- a/src/utils.ts
+++ b/packages/core/src/utils.ts
@@ -1,10 +1,4 @@
-import { AxiosError } from "axios";
-import { ReadonlyDeep } from "./utils.types";
-import {
- AnyZodiosRequestOptions,
- ZodiosEndpointDefinition,
- ZodiosEndpointDefinitions,
-} from "./zodios.types";
+import type { ZodiosEndpointDefinition } from "./zodios.types";
/**
* omit properties from an object
@@ -42,32 +36,8 @@ export function pick(
return ret;
}
-/**
- * set first letter of a string to uppercase
- * @param str - the string to capitalize
- * @returns - the string with the first letter uppercased
- */
-export function capitalize(str: T): Capitalize {
- return (str.charAt(0).toUpperCase() + str.slice(1)) as Capitalize;
-}
-
-const paramsRegExp = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
-
-export function replacePathParams(
- config: ReadonlyDeep
-) {
- let result: string = config.url;
- const params = config.params;
- if (params) {
- result = result.replace(paramsRegExp, (match, key) =>
- key in params ? `${params[key]}` : match
- );
- }
- return result;
-}
-
export function findEndpoint(
- api: ZodiosEndpointDefinitions,
+ api: ZodiosEndpointDefinition[] | readonly ZodiosEndpointDefinition[],
method: string,
path: string
) {
@@ -75,15 +45,23 @@ export function findEndpoint(
}
export function findEndpointByAlias(
- api: ZodiosEndpointDefinitions,
+ api: ZodiosEndpointDefinition[] | readonly ZodiosEndpointDefinition[],
alias: string
) {
return api.find((e) => e.alias === alias);
}
+const paramsRegExp = /:([a-zA-Z_][a-zA-Z0-9_]*)/g;
+
+export function pathMatchesUrl(path: string, url: string) {
+ return new RegExp(`^${path.replace(paramsRegExp, () => "([^/]*)")}$`).test(
+ url
+ );
+}
+
export function findEndpointErrors(
endpoint: ZodiosEndpointDefinition,
- err: AxiosError
+ err: any
) {
const matchingErrors = endpoint.errors?.filter(
(error) => error.status === err.response!.status
@@ -93,10 +71,10 @@ export function findEndpointErrors(
}
export function findEndpointErrorsByPath(
- api: ZodiosEndpointDefinitions,
+ api: ZodiosEndpointDefinition[] | readonly ZodiosEndpointDefinition[],
method: string,
path: string,
- err: AxiosError
+ err: any
) {
const endpoint = findEndpoint(api, method, path);
return endpoint &&
@@ -109,11 +87,13 @@ export function findEndpointErrorsByPath(
}
export function findEndpointErrorsByAlias(
- api: ZodiosEndpointDefinitions,
+ api: ZodiosEndpointDefinition[] | readonly ZodiosEndpointDefinition[],
alias: string,
- err: AxiosError
+ err: any
) {
const endpoint = findEndpointByAlias(api, alias);
+ console.log("For Alias: ", alias);
+ console.log("Found Endpoint: ", endpoint);
return endpoint &&
err.config &&
@@ -123,9 +103,3 @@ export function findEndpointErrorsByAlias(
? findEndpointErrors(endpoint, err)
: undefined;
}
-
-export function pathMatchesUrl(path: string, url: string) {
- return new RegExp(`^${path.replace(paramsRegExp, () => "([^/]*)")}$`).test(
- url
- );
-}
diff --git a/src/utils.types.test.ts b/packages/core/src/utils.types.test.ts
similarity index 100%
rename from src/utils.types.test.ts
rename to packages/core/src/utils.types.test.ts
diff --git a/src/utils.types.ts b/packages/core/src/utils.types.ts
similarity index 75%
rename from src/utils.types.ts
rename to packages/core/src/utils.types.ts
index cab8e5ab..313bba4a 100644
--- a/src/utils.types.ts
+++ b/packages/core/src/utils.types.ts
@@ -1,5 +1,3 @@
-import { z, ZodType } from "zod";
-
/**
* filter an array type by a predicate value
* @param T - array type
@@ -7,15 +5,38 @@ import { z, ZodType } from "zod";
* @details - this is using tail recursion type optimization from typescript 4.5
*/
export type FilterArrayByValue<
- T extends unknown[] | undefined,
+ T extends readonly unknown[] | unknown[] | undefined,
C,
Acc extends unknown[] = []
-> = T extends [infer Head, ...infer Tail]
+> = T extends readonly [infer Head, ...infer Tail]
+ ? Head extends C
+ ? FilterArrayByValue
+ : FilterArrayByValue
+ : T extends [infer Head, ...infer Tail]
? Head extends C
? FilterArrayByValue
: FilterArrayByValue
: Acc;
+/**
+ * find the first value in an array type that matches a predicate
+ * @param T - array type
+ * @param C - predicate object to match
+ * @details - this is using tail recursion type optimization from typescript 4.5
+ */
+export type ArrayFindByValue<
+ T extends readonly unknown[] | unknown[] | undefined,
+ C
+> = T extends readonly [infer Head, ...infer Tail]
+ ? Head extends C
+ ? Head
+ : ArrayFindByValue
+ : T extends [infer Head, ...infer Tail]
+ ? Head extends C
+ ? Head
+ : ArrayFindByValue
+ : never;
+
/**
* filter an array type by key
* @param T - array type
@@ -23,10 +44,14 @@ export type FilterArrayByValue<
* @details - this is using tail recursion type optimization from typescript 4.5
*/
export type FilterArrayByKey<
- T extends unknown[],
+ T extends readonly unknown[] | unknown[],
K extends string,
Acc extends unknown[] = []
-> = T extends [infer Head, ...infer Tail]
+> = T extends readonly [infer Head, ...infer Tail]
+ ? Head extends { [Key in K]: unknown }
+ ? FilterArrayByKey
+ : FilterArrayByKey
+ : T extends [infer Head, ...infer Tail]
? Head extends { [Key in K]: unknown }
? FilterArrayByKey
: FilterArrayByKey
@@ -38,34 +63,18 @@ export type FilterArrayByKey<
* @details - this is using tail recursion type optimization from typescript 4.5
*/
export type DefinedArray<
- T extends unknown[],
+ T extends readonly unknown[] | unknown[],
Acc extends unknown[] = []
-> = T extends [infer Head, ...infer Tail]
+> = T extends readonly [infer Head, ...infer Tail]
+ ? Head extends undefined
+ ? DefinedArray
+ : DefinedArray
+ : T extends [infer Head, ...infer Tail]
? Head extends undefined
? DefinedArray
: DefinedArray
: Acc;
-type Try = A extends B ? A : C;
-
-type NarrowRaw =
- | (T extends Function ? T : never)
- | (T extends string | number | bigint | boolean ? T : never)
- | (T extends [] ? [] : never)
- | {
- [K in keyof T]: K extends "description" ? T[K] : NarrowNotZod;
- };
-
-type NarrowNotZod = Try>;
-
-/**
- * Utility to infer the embedded primitive type of any type
- * Same as `as const` but without setting the object as readonly and without needing the user to use it
- * @param T - type to infer the embedded type of
- * @see - thank you tannerlinsley for this idea
- */
-export type Narrow = Try>;
-
/**
* merge all union types into a single type
* @param T - union type
@@ -169,22 +178,13 @@ export type UndefinedIfEmpty = IfEquals;
export type UndefinedIfNever = IfEquals;
-type RequiredChildProps = {
- [K in keyof T]: IfEquals, never, K>;
-}[keyof T];
-
-export type OptionalChildProps = {
- [K in keyof T]: IfEquals, K, never>;
-}[keyof T];
-
/**
* set properties to optional if their child properties are optional
* @param T - object type
*/
-export type SetPropsOptionalIfChildrenAreOptional = Merge<
- Pick, OptionalChildProps>,
- Pick>
->;
+export type TransitiveOptional = UndefinedToOptional<{
+ [k in keyof T]: RequiredKeys extends never ? T[k] | undefined : T[k];
+}>;
/**
* transform an array type into a readonly array type
@@ -214,39 +214,6 @@ export type ReadonlyDeep = T extends (infer R)[]
export type MaybeReadonly = T | ReadonlyDeep;
-/**
- * Map a type an api description parameter to a zod infer type
- * @param T - array of api description parameters
- * @details - this is using tail recursion type optimization from typescript 4.5
- */
-export type MapSchemaParameters<
- T,
- Frontend extends boolean = true,
- Acc = {}
-> = T extends [infer Head, ...infer Tail]
- ? Head extends {
- name: infer Name;
- schema: infer Schema;
- }
- ? Name extends string
- ? MapSchemaParameters<
- Tail,
- Frontend,
- Merge<
- {
- [Key in Name]: Schema extends z.ZodType
- ? Frontend extends true
- ? z.input
- : z.output
- : never;
- },
- Acc
- >
- >
- : Acc
- : Acc
- : Acc;
-
/**
* get all parameters from an API path
* @param Path - API path
diff --git a/src/zodios-error.ts b/packages/core/src/zodios-error.ts
similarity index 58%
rename from src/zodios-error.ts
rename to packages/core/src/zodios-error.ts
index 3741b535..1e86deed 100644
--- a/src/zodios-error.ts
+++ b/packages/core/src/zodios-error.ts
@@ -1,5 +1,6 @@
-import { ReadonlyDeep } from "./utils.types";
-import { AnyZodiosRequestOptions } from "./zodios.types";
+import { AnyZodiosFetcherProvider } from "./fetcher-providers";
+import type { ReadonlyDeep, DeepReadonlyObject } from "./utils.types";
+import type { AnyZodiosRequestOptions } from "./zodios.types";
/**
* Custom Zodios Error with additional information
@@ -11,7 +12,9 @@ import { AnyZodiosRequestOptions } from "./zodios.types";
export class ZodiosError extends Error {
constructor(
message: string,
- public readonly config?: ReadonlyDeep,
+ public readonly config?: ReadonlyDeep<
+ AnyZodiosRequestOptions
+ >,
public readonly data?: unknown,
public readonly cause?: Error
) {
diff --git a/packages/core/src/zodios-request.test.ts b/packages/core/src/zodios-request.test.ts
new file mode 100644
index 00000000..50894823
--- /dev/null
+++ b/packages/core/src/zodios-request.test.ts
@@ -0,0 +1,206 @@
+import { z } from "zod";
+import { makeApi, ZodiosCore } from "./index";
+import { Assert } from "./utils.types";
+
+const api = makeApi([
+ {
+ method: "get",
+ path: "/users",
+ alias: "getUsers",
+ description: "Get all users",
+ parameters: [
+ {
+ name: "page",
+ type: "Query",
+ schema: z.number().positive().optional(),
+ },
+ {
+ name: "limit",
+ type: "Query",
+ schema: z.number().positive().optional(),
+ },
+ ],
+ response: z.object({
+ page: z.number(),
+ count: z.number(),
+ nextPage: z.number().optional(),
+ users: z.array(
+ z.object({
+ id: z.number(),
+ name: z.string(),
+ })
+ ),
+ }),
+ },
+ {
+ method: "post",
+ path: "/users/search",
+ alias: "searchUsers",
+ description: "Search users",
+ immutable: true,
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ name: z.string(),
+ page: z.number().positive().optional(),
+ limit: z.number().positive().optional(),
+ }),
+ },
+ ],
+ response: z.object({
+ page: z.number(),
+ count: z.number(),
+ nextPage: z.number().optional(),
+ users: z.array(
+ z.object({
+ id: z.number(),
+ name: z.string(),
+ })
+ ),
+ }),
+ },
+ {
+ method: "get",
+ path: "/users/:id",
+ alias: "getUser",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ {
+ method: "get",
+ path: "/users/:id/address/:address",
+ alias: "getUserAddress",
+ response: z.object({
+ id: z.number(),
+ address: z.string(),
+ }),
+ },
+ {
+ method: "post",
+ path: "/users",
+ alias: "createUser",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ {
+ method: "put",
+ path: "/users",
+ alias: "updateUser",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ {
+ method: "patch",
+ path: "/users",
+ alias: "patchUser",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ {
+ method: "delete",
+ path: "/users/:id",
+ alias: "deleteUser",
+ response: z.object({
+ id: z.number(),
+ }),
+ },
+ {
+ method: "get",
+ path: "/users/:id/error",
+ alias: "getUserError",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ {
+ method: "get",
+ path: "/users/:id/cancel",
+ alias: "getUserCancel",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+]);
+const core = new ZodiosCore(api);
+
+describe("ZodiosCore request", () => {
+ it("should return only one response type for get request", async () => {
+ const req = () =>
+ core.request({
+ method: "get",
+ url: "/users",
+ });
+ type Req = typeof req;
+ const testResult: Assert<
+ ReturnType,
+ Promise<{
+ nextPage?: number | undefined;
+ page: number;
+ count: number;
+ users: {
+ name: string;
+ id: number;
+ }[];
+ }>
+ > = true;
+ });
+
+ it("should return only one response type for post request", async () => {
+ const core = new ZodiosCore(api);
+
+ const req = () =>
+ core.request({
+ method: "post",
+ url: "/users",
+ body: {
+ name: "John",
+ },
+ });
+ type Req = typeof req;
+ const testResult: Assert<
+ ReturnType,
+ Promise<{ name: string; id: number }>
+ > = true;
+ });
+});
diff --git a/packages/core/src/zodios.test.ts b/packages/core/src/zodios.test.ts
new file mode 100644
index 00000000..46d72fa8
--- /dev/null
+++ b/packages/core/src/zodios.test.ts
@@ -0,0 +1,1486 @@
+import { z, ZodError } from "zod";
+
+//Mock form data
+globalThis.FormData = class FormData {
+ data = new Map();
+ append(name: string, value: string | Blob, fileName?: string): void {
+ this.data.set(name, `${value}`);
+ }
+ delete(name: string): void {
+ this.data.delete(name);
+ }
+ get(name: string): string | File | null {
+ return this.data.get(name) || null;
+ }
+ getAll(name: string): (string | File)[] {
+ return this.data.has(name) ? [this.data.get(name)!] : [];
+ }
+ has(name: string): boolean {
+ return this.data.has(name);
+ }
+ set(name: string, value: string | Blob, fileName?: string): void {
+ if (typeof value === "string") {
+ this.data.set(name, value);
+ }
+ }
+ forEach(
+ callbackfn: (value: string | File, key: string, parent: FormData) => void,
+ thisArg?: any
+ ): void {
+ this.data.forEach((value, key) => callbackfn(value, key, this));
+ }
+};
+
+import {
+ ZodiosCore,
+ ZodiosError,
+ apiBuilder,
+ makeApi,
+ makeParameters,
+ ApiOf,
+ ZodTypeProvider,
+} from "./index";
+
+import type { Assert } from "./utils.types";
+import {
+ FindZodiosEndpointDefinitionByPath,
+ ZodiosMatchingErrorsByPath,
+} from "./zodios.types";
+import {
+ zodiosMocks,
+ MockProvider,
+ mockFetchFactory,
+} from "./fetcher-providers/mock-provider";
+
+describe("Zodios", () => {
+ beforeAll(async () => {
+ zodiosMocks.install();
+ zodiosMocks.mockRequest("get", "/token", async (conf) => ({
+ data: {
+ token: conf.headers!.authorization,
+ },
+ }));
+ zodiosMocks.mockRequest("post", "/token", async (conf) => ({
+ data: {
+ token: conf.headers!.authorization,
+ },
+ }));
+ zodiosMocks.mockRequest("get", "/error401", async (conf) => ({
+ status: 401,
+ statusText: "Unauthorized",
+ data: {},
+ }));
+ zodiosMocks.mockRequest("get", "/error/:id/error401", async (conf) => ({
+ status: 401,
+ statusText: "Unauthorized",
+ data: {},
+ }));
+ zodiosMocks.mockRequest(
+ "get",
+ "/error/:id/error401/:message",
+ async (conf) => ({
+ status: 401,
+ statusText: "Unauthorized",
+ data: {},
+ })
+ );
+ zodiosMocks.mockRequest("get", "/error502", async (conf) => ({
+ status: 502,
+ statusText: "Bad Gateway",
+ data: {
+ error: {
+ message: "bad gateway",
+ },
+ },
+ }));
+ zodiosMocks.mockRequest("get", "/queries", async (conf) => ({
+ data: {
+ queries: conf.queries!.id,
+ },
+ }));
+ zodiosMocks.mockRequest("get", "/:id", async (conf) => ({
+ data: {
+ id: conf.params!.id,
+ name: "test",
+ },
+ headers: {
+ "content-type": "application/json",
+ },
+ }));
+ zodiosMocks.mockRequest("get", "/path/:uuid", async (config) => ({
+ data: {
+ uuid: config.params!.uuid,
+ },
+ }));
+ zodiosMocks.mockRequest("get", "/:id/address/:address", async (config) => ({
+ data: {
+ id: config.params!.id,
+ address: config.params!.address,
+ },
+ }));
+ zodiosMocks.mockRequest("post", "/", async (config) => ({
+ data: {
+ id: 3,
+ // @ts-ignore
+ name: config.body.name, // @ts-ignore
+ },
+ }));
+ zodiosMocks.mockRequest("put", "/", async (config) => ({
+ data: {
+ // @ts-ignore
+ id: config.body.id,
+ // @ts-ignore
+ name: config.body.name,
+ },
+ }));
+ zodiosMocks.mockRequest("patch", "/", async (config) => ({
+ data: {
+ // @ts-ignore
+ id: config.body.id,
+ // @ts-ignore
+ name: config.body.name,
+ },
+ }));
+ zodiosMocks.mockRequest("delete", "/:id", async (config) => ({
+ data: {
+ id: config.params!.id,
+ },
+ }));
+ zodiosMocks.mockRequest("post", "/form-data", async (config) => {
+ const data = {};
+ (config.body as FormData).forEach((value, key) => {
+ // @ts-ignore
+ data[key] = value;
+ });
+ return {
+ data,
+ };
+ });
+ zodiosMocks.mockRequest("post", "/form-url", async (config) => {
+ const data = {};
+ const url = new URLSearchParams(config.body as string);
+ for (const [key, value] of url) {
+ // @ts-ignore
+ data[key] = value;
+ }
+ return {
+ data,
+ };
+ });
+ zodiosMocks.mockRequest("post", "/text", async (config) => ({
+ headers: {
+ "content-type": "text/plain",
+ },
+ data: config.body,
+ }));
+ });
+
+ afterAll(() => {
+ zodiosMocks.uninstall();
+ });
+
+ it("should be defined", () => {
+ expect(ZodiosCore).toBeDefined();
+ });
+
+ it("should throw if baseUrl is not provided", () => {
+ // @ts-ignore
+ expect(() => new ZodiosCore(undefined, [])).toThrowError(
+ "Zodios: missing base url"
+ );
+ });
+
+ it("should throw if api is not provided", () => {
+ // @ts-ignore
+ expect(() => new ZodiosCore()).toThrowError(
+ "Zodios: missing api description"
+ );
+ });
+
+ it("should throw if api is not an array", () => {
+ // @ts-ignore
+ expect(() => new ZodiosCore({})).toThrowError(
+ "Zodios: api must be an array"
+ );
+ });
+
+ it("should create a new instance of Zodios", () => {
+ const zodios = new ZodiosCore(`http://localhost`, []);
+ expect(zodios).toBeDefined();
+ });
+ it("should create a new instance when providing an api", () => {
+ const zodios = new ZodiosCore(`http://localhost`, [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ expect(zodios).toBeDefined();
+ });
+
+ it("should should throw with duplicate api endpoints", () => {
+ expect(
+ () =>
+ new ZodiosCore(`http://localhost`, [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ])
+ ).toThrowError("Zodios: Duplicate path 'get /:id'");
+ });
+
+ it("should create a new instance whithout base URL", () => {
+ const zodios = new ZodiosCore([
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ expect(zodios).toBeDefined();
+ });
+
+ it("should register have validation plugin automatically installed", () => {
+ const zodios = new ZodiosCore(`http://localhost`, []);
+ expect(
+ // @ts-expect-error
+ zodios.plugins.plugins.filter((plugin) => plugin.plugin).length
+ ).toBe(1);
+ });
+
+ it("should register a plugin", () => {
+ const zodios = new ZodiosCore(`http://localhost`, []);
+ zodios.use({
+ request: async (_, config) => config,
+ });
+ expect(
+ // @ts-expect-error
+ zodios.plugins.plugins.filter((plugin) => plugin.plugin).length
+ ).toBe(2);
+ });
+
+ it("should unregister a plugin", () => {
+ const zodios = new ZodiosCore(`http://localhost`, []);
+ const id = zodios.use({
+ request: async (_, config) => config,
+ });
+ expect(
+ // @ts-expect-error
+ zodios.plugins.plugins.filter((plugin) => plugin.plugin).length
+ ).toBe(2);
+ zodios.eject(id);
+ expect(
+ // @ts-expect-error
+ zodios.plugins.plugins.filter((plugin) => plugin.plugin).length
+ ).toBe(1);
+ });
+
+ it("should throw if invalide parameters when registering a plugin", () => {
+ const zodios = new ZodiosCore(`http://localhost`, []);
+ // @ts-expect-error
+ expect(() => zodios.use(0)).toThrowError("Zodios: invalid plugin");
+ });
+
+ it("should register a plugin by endpoint", () => {
+ const api = makeApi([
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+
+ const zodios = new ZodiosCore(`http://localhost`, [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ zodios.use("get", "/:id", {
+ request: async (_, config) => config,
+ });
+ expect(
+ // @ts-expect-error
+ zodios.plugins.plugins.filter((plugin) => plugin.plugin).length
+ ).toBe(2);
+ });
+
+ it("should register a plugin by alias", () => {
+ const zodios = new ZodiosCore(`http://localhost`, [
+ {
+ method: "get",
+ path: "/:id",
+ alias: "test",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ]);
+ zodios.use("test", {
+ request: async (_, config) => config,
+ });
+ expect(
+ // @ts-expect-error
+ zodios.plugins.plugins.filter((plugin) => plugin.plugin).length
+ ).toBe(2);
+ });
+
+ it("should make an http request", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ {
+ method: "get",
+ path: "/users",
+ response: z.array(
+ z.object({
+ id: z.number(),
+ name: z.string(),
+ })
+ ),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.request({
+ // ^?
+ method: "get",
+ url: "/:id",
+ params: { id: 7 },
+ });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+ expect(response).toEqual({ id: 7, name: "test" });
+ });
+
+ it("should make an http get with standard query arrays", async () => {
+ const api = makeApi([
+ {
+ method: "get",
+ path: "/queries",
+ parameters: makeParameters([
+ {
+ name: "id",
+ type: "Query",
+ schema: z.array(z.number()),
+ },
+ ]),
+ response: z.object({
+ queries: z.array(z.string()),
+ }),
+ },
+ {
+ method: "get",
+ path: "/users",
+ response: z.array(
+ z.object({
+ id: z.number(),
+ name: z.string(),
+ })
+ ),
+ },
+ ]);
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/queries",
+ parameters: [
+ {
+ name: "id",
+ type: "Query",
+ schema: z.array(z.number()),
+ },
+ ],
+ response: z.object({
+ queries: z.array(z.string()),
+ }),
+ },
+ {
+ method: "get",
+ path: "/users",
+ response: z.array(
+ z.object({
+ id: z.number(),
+ name: z.string(),
+ })
+ ),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.get("/queries", { queries: { id: [1, 2] } });
+ expect(response).toEqual({ queries: [1, 2] });
+ });
+
+ it("should make an http get with one path params", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.get("/:id", { params: { id: 7 } });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+
+ expect(response).toEqual({ id: 7, name: "test" });
+ });
+
+ it("should make an http alias request with one path params", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/:id",
+ alias: "getById",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.getById({ params: { id: 7 } });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+
+ expect(response).toEqual({ id: 7, name: "test" });
+ });
+
+ it("should work with api builder", async () => {
+ const api = apiBuilder({
+ method: "get",
+ path: "/:id",
+ alias: "getById",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ }).build();
+ const zodios = new ZodiosCore(`http://localhost`, api, {
+ fetcherFactory: mockFetchFactory,
+ });
+ const response = await zodios.getById({ params: { id: 7 } });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+
+ expect(response).toEqual({ id: 7, name: "test" });
+ });
+
+ it("should make a get request with bad params and get back a zod error", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/:id",
+ parameters: [
+ {
+ name: "id",
+ type: "Path",
+ schema: z.number(),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ try {
+ await zodios.get("/:id", { params: { id: "7" as unknown as number } });
+ } catch (e) {
+ expect(e).toBeInstanceOf(ZodiosError);
+ }
+ });
+
+ it("should make an http get with multiples path params", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/:id/address/:address",
+ response: z.object({
+ id: z.number(),
+ address: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.get("/:id/address/:address", {
+ params: { id: 7, address: "address" },
+ });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; address: string }
+ > = true;
+
+ expect(response).toEqual({ id: 7, address: "address" });
+ });
+
+ it("should make an http post with body param", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "post",
+ path: "/",
+ parameters: [
+ {
+ name: "name",
+ type: "Body",
+ schema: z.object({
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.post("/", { body: { name: "post" } });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+ expect(response).toEqual({ id: 3, name: "post" });
+ });
+
+ it("should make an http post with transformed body param", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "post",
+ path: "/",
+ parameters: [
+ {
+ name: "name",
+ type: "Body",
+ schema: z
+ .object({
+ firstname: z.string(),
+ lastname: z.string(),
+ })
+ .transform((data) => ({
+ name: `${data.firstname} ${data.lastname}`,
+ })),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const config = {
+ body: { firstname: "post", lastname: "test" },
+ } as const;
+ const response = await zodios.post("/", config);
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+
+ expect(config).toEqual({
+ body: { firstname: "post", lastname: "test" },
+ });
+ expect(response).toEqual({ id: 3, name: "post test" });
+ });
+
+ it("should throw a zodios error if params are not correct", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "post",
+ path: "/",
+ parameters: [
+ {
+ name: "name",
+ type: "Body",
+ schema: z
+ .object({
+ email: z.string().email(),
+ })
+ .transform((data) => ({
+ name: `${data.email.split("@")[0]}`,
+ })),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ let response;
+ let error: ZodiosError | undefined;
+ try {
+ response = await zodios.post("/", {
+ body: {
+ email: "post",
+ },
+ });
+ } catch (err) {
+ error = err as ZodiosError;
+ }
+ expect(response).toBeUndefined();
+ expect(error).toBeInstanceOf(ZodiosError);
+ expect(error!.cause).toBeInstanceOf(ZodError);
+ expect(error!.message).toBe("Zodios: Invalid Body parameter 'name'");
+ });
+
+ it("should make an http mutation alias request with body param", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "post",
+ path: "/",
+ alias: "create",
+ parameters: [
+ {
+ name: "name",
+ type: "Body",
+ schema: z.object({
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.create({ body: { name: "post" } });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+ expect(response).toEqual({ id: 3, name: "post" });
+ });
+
+ it("should make an http put", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "put",
+ path: "/",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.put("/", { body: { id: 5, name: "put" } });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+ expect(response).toEqual({ id: 5, name: "put" });
+ });
+
+ it("should make an http put alias", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "put",
+ path: "/",
+ alias: "update",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.update({ body: { id: 5, name: "put" } });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+ expect(response).toEqual({ id: 5, name: "put" });
+ });
+
+ it("should make an http patch", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "patch",
+ path: "/",
+ parameters: [
+ {
+ name: "id",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.patch("/", {
+ body: { id: 4, name: "patch" },
+ });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+ expect(response).toEqual({ id: 4, name: "patch" });
+ });
+
+ it("should make an http patch alias", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "patch",
+ path: "/",
+ alias: "update",
+ parameters: [
+ {
+ name: "id",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.update({ body: { id: 4, name: "patch" } });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string }
+ > = true;
+ expect(response).toEqual({ id: 4, name: "patch" });
+ });
+
+ it("should make an http delete", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "delete",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.delete("/:id", {
+ params: { id: 6 },
+ });
+ const testResonseType: Assert = true;
+ expect(response).toEqual({ id: 6 });
+ });
+
+ it("should make an http delete alias", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "delete",
+ path: "/:id",
+ alias: "remove",
+ response: z.object({
+ id: z.number(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.remove({
+ params: { id: 6 },
+ });
+ const testResonseType: Assert = true;
+ expect(response).toEqual({ id: 6 });
+ });
+
+ it("should validate uuid in path params", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/path/:uuid",
+ parameters: [
+ {
+ name: "uuid",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ ],
+ response: z.object({
+ uuid: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.get("/path/:uuid", {
+ params: { uuid: "e9e09a1d-3967-4518-bc89-75a901aee128" },
+ });
+ const testResonseType: Assert = true;
+ expect(response).toEqual({
+ uuid: "e9e09a1d-3967-4518-bc89-75a901aee128",
+ });
+ });
+
+ it("should not validate bad path params", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/path/:uuid",
+ parameters: [
+ {
+ name: "uuid",
+ type: "Path",
+ schema: z.string().uuid(),
+ },
+ ],
+ response: z.object({
+ uuid: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ let error;
+ try {
+ await zodios.get("/path/:uuid", {
+ params: { uuid: "e9e09a1-3967-4518-bc89-75a901aee128" },
+ });
+ } catch (e) {
+ error = e;
+ }
+ expect(error).toBeInstanceOf(ZodiosError);
+ expect((error as ZodiosError).cause).toBeInstanceOf(ZodError);
+ expect((error as ZodiosError).message).toBe(
+ "Zodios: Invalid Path parameter 'uuid'"
+ );
+ });
+
+ it("should not validate bad formatted responses", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ more: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ let error: Error | undefined = undefined;
+ try {
+ await zodios.get("/:id", { params: { id: 1 } });
+ } catch (e) {
+ error = e as Error;
+ }
+ expect(error).toBeInstanceOf(ZodiosError);
+ expect((error as ZodiosError).cause).toBeInstanceOf(ZodError);
+ expect((error as ZodiosError).message).toMatchSnapshot();
+ expect((error as ZodiosError).data).toEqual({
+ id: 1,
+ name: "test",
+ });
+ expect((error as ZodiosError).config).toEqual({
+ method: "get",
+ url: "/:id",
+ params: { id: 1 },
+ });
+ });
+
+ it("should match Expected error", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ alias: "getError502",
+ path: "/error502",
+ response: z.void(),
+ errors: [
+ {
+ status: 502,
+ schema: z.object({
+ error: z.object({
+ message: z.string(),
+ }),
+ }),
+ },
+ {
+ status: 401,
+ schema: z.object({
+ error: z.object({
+ message: z.string(),
+ _401: z.literal(true),
+ }),
+ }),
+ },
+ {
+ status: "default",
+ schema: z.object({
+ error: z.object({
+ message: z.string(),
+ _default: z.literal(true),
+ }),
+ }),
+ },
+ ],
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ let error;
+ try {
+ await zodios.get("/error502");
+ } catch (e) {
+ error = e;
+ }
+ type Test = ZodiosMatchingErrorsByPath<
+ ApiOf,
+ "get",
+ "/error502",
+ MockProvider,
+ ZodTypeProvider
+ >;
+ type Test2 = FindZodiosEndpointDefinitionByPath<
+ ApiOf,
+ "get",
+ "/error502"
+ >["errors"];
+
+ expect(error).toBeInstanceOf(Error);
+ // @ts-ignore
+ expect(error.response?.status).toBe(502);
+ if (zodios.isErrorFromPath("get", "/error502", error)) {
+ expect(error.response.status).toBe(502);
+ expect(error.response?.data).toEqual({
+ error: { message: "bad gateway" },
+ });
+ }
+ if (zodios.isErrorFromAlias("getError502", error)) {
+ expect(error.response.status).toBe(502);
+ expect(error.response?.data).toEqual({
+ error: { message: "bad gateway" },
+ });
+ }
+ });
+
+ it("should match error with params", async () => {
+ const zodios = new ZodiosCore(`http://localhost`, [
+ {
+ method: "get",
+ alias: "getError401",
+ path: "/error/:id/error401",
+ response: z.void(),
+ errors: [
+ {
+ status: 401,
+ schema: z.object({}),
+ },
+ ],
+ },
+ {
+ method: "get",
+ alias: "getError404",
+ path: "/error/:id/error404",
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.object({}),
+ },
+ ],
+ },
+ ]);
+
+ const params = {
+ id: "test",
+ };
+
+ let error;
+ try {
+ await zodios.getError401({ params });
+ } catch (e) {
+ error = e;
+ console.log("Match Error params", e);
+ }
+
+ expect(zodios.isErrorFromAlias("getError401", error)).toBe(true);
+ expect(zodios.isErrorFromAlias("getError404", error)).toBe(false);
+
+ expect(zodios.isErrorFromPath("get", "/error/:id/error401", error)).toBe(
+ true
+ );
+ expect(zodios.isErrorFromPath("get", "/error/:id/error404", error)).toBe(
+ false
+ );
+ });
+
+ it("should match error with empty params", async () => {
+ const zodios = new ZodiosCore(`http://localhost`, [
+ {
+ method: "get",
+ alias: "getError401",
+ path: "/error/:id/error401",
+ response: z.void(),
+ errors: [
+ {
+ status: 401,
+ schema: z.object({}),
+ },
+ ],
+ },
+ {
+ method: "get",
+ alias: "getError404",
+ path: "/error/:id/error404",
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.object({}),
+ },
+ ],
+ },
+ ]);
+
+ const params = {
+ id: "",
+ };
+
+ let error;
+ try {
+ await zodios.getError401({ params });
+ } catch (e) {
+ error = e;
+ }
+
+ expect(zodios.isErrorFromAlias("getError401", error)).toBe(true);
+ expect(zodios.isErrorFromAlias("getError404", error)).toBe(false);
+
+ expect(zodios.isErrorFromPath("get", "/error/:id/error401", error)).toBe(
+ true
+ );
+ expect(zodios.isErrorFromPath("get", "/error/:id/error404", error)).toBe(
+ false
+ );
+ });
+
+ it("should match error with optional params at the end", async () => {
+ const zodios = new ZodiosCore(`http://localhost`, [
+ {
+ method: "get",
+ alias: "getError401",
+ path: "/error/:id/error401/:message",
+ response: z.void(),
+ errors: [
+ {
+ status: 401,
+ schema: z.object({}),
+ },
+ ],
+ },
+ {
+ method: "get",
+ alias: "getError404",
+ path: "/error/:id/error404/:message",
+ response: z.void(),
+ errors: [
+ {
+ status: 404,
+ schema: z.object({}),
+ },
+ ],
+ },
+ ]);
+
+ const params = {
+ id: "test",
+ message: "",
+ };
+
+ let error;
+ try {
+ await zodios.getError401({ params });
+ } catch (e) {
+ error = e;
+ }
+
+ expect(zodios.isErrorFromAlias("getError401", error)).toBe(true);
+ expect(zodios.isErrorFromAlias("getError404", error)).toBe(false);
+
+ expect(
+ zodios.isErrorFromPath("get", "/error/:id/error401/:message", error)
+ ).toBe(true);
+ expect(
+ zodios.isErrorFromPath("get", "/error/:id/error404/:message", error)
+ ).toBe(false);
+ });
+
+ it("should match Unexpected error", async () => {
+ const zodios = new ZodiosCore(`http://localhost`, [
+ {
+ method: "get",
+ alias: "getError502",
+ path: "/error502",
+ response: z.void(),
+ },
+ ]);
+ let error;
+ try {
+ await zodios.get("/error502");
+ } catch (e) {
+ error = e;
+ }
+
+ expect(error).toBeInstanceOf(Error);
+ // @ts-ignore
+ expect(error.response?.status).toBe(502);
+ expect(zodios.isErrorFromPath("get", "/error502", error)).toBe(false);
+ expect(zodios.isErrorFromAlias("getError502", error)).toBe(false);
+ });
+
+ it("should return response when disabling validation", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/:id",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ more: z.string(),
+ }),
+ },
+ ],
+ { validate: false, fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.get("/:id", { params: { id: 1 } });
+ const testResonseType: Assert<
+ typeof response,
+ { id: number; name: string; more: string }
+ > = true;
+ expect(response).toEqual({
+ id: 1,
+ name: "test",
+ });
+ });
+
+ it("should trigger an error with error response", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "get",
+ path: "/error502",
+ response: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ try {
+ await zodios.get("/error502");
+ } catch (e) {
+ // @ts-ignore
+ expect(e.response?.data).toEqual({
+ error: {
+ message: "bad gateway",
+ },
+ });
+ }
+ });
+
+ it("should send a form data request", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "post",
+ path: "/form-data",
+ requestFormat: "form-data",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.string(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.post("/form-data", {
+ body: { id: 4, name: "post" },
+ });
+ const testResonseType: Assert<
+ typeof response,
+ { id: string; name: string }
+ > = true;
+ expect(response).toEqual({ id: "4", name: "post" });
+ });
+
+ it("should not send an array as form data request", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "post",
+ path: "/form-data",
+ requestFormat: "form-data",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.array(z.string()),
+ },
+ ],
+ response: z.string(),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ let error: Error | undefined;
+ let response: string | undefined;
+ try {
+ response = await zodios.post("/form-data", { body: ["test", "test2"] });
+ } catch (err) {
+ error = err as Error;
+ }
+ expect(response).toBeUndefined();
+ expect(error).toBeInstanceOf(ZodiosError);
+ expect((error as ZodiosError).message).toBe(
+ "Zodios: multipart/form-data body must be an object"
+ );
+ });
+
+ it("should send a form url request", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "post",
+ path: "/form-url",
+ requestFormat: "form-url",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.object({
+ id: z.number(),
+ name: z.string(),
+ }),
+ },
+ ],
+ response: z.object({
+ id: z.string(),
+ name: z.string(),
+ }),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.post("/form-url", {
+ body: { id: 4, name: "post" },
+ });
+ const testResonseType: Assert<
+ typeof response,
+ { id: string; name: string }
+ > = true;
+ expect(response).toEqual({ id: "4", name: "post" });
+ });
+
+ it("should not send an array as form url request", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "post",
+ path: "/form-url",
+ requestFormat: "form-url",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.array(z.string()),
+ },
+ ],
+ response: z.string(),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ let error: Error | undefined;
+ let response: string | undefined;
+ try {
+ response = await zodios.post("/form-url", { body: ["test", "test2"] });
+ } catch (err) {
+ error = err as Error;
+ }
+ expect(response).toBeUndefined();
+ expect(error).toBeInstanceOf(ZodiosError);
+ expect((error as ZodiosError).message).toBe(
+ "Zodios: application/x-www-form-urlencoded body must be an object"
+ );
+ });
+
+ it("should send a text request", async () => {
+ const zodios = new ZodiosCore(
+ `http://localhost`,
+ [
+ {
+ method: "post",
+ path: "/text",
+ requestFormat: "text",
+ parameters: [
+ {
+ name: "body",
+ type: "Body",
+ schema: z.string(),
+ },
+ ],
+ response: z.string(),
+ },
+ ],
+ { fetcherFactory: mockFetchFactory }
+ );
+ const response = await zodios.post("/text", { body: "test" });
+ const testResonseType: Assert = true;
+ expect(response).toEqual("test");
+ });
+});
diff --git a/packages/core/src/zodios.ts b/packages/core/src/zodios.ts
new file mode 100644
index 00000000..eca0ff60
--- /dev/null
+++ b/packages/core/src/zodios.ts
@@ -0,0 +1,498 @@
+import type {
+ AnyZodiosRequestOptions,
+ ZodiosRequestOptions,
+ Method,
+ ZodiosPathsByMethod,
+ ZodiosResponseByPath,
+ ZodiosOptions,
+ ZodiosEndpointDefinition,
+ ZodiosAliases,
+ ZodiosPlugin,
+ Aliases,
+ ZodiosEndpointError,
+ ZodiosMatchingErrorsByPath,
+ ZodiosMatchingErrorsByAlias,
+ ZodiosVerbs,
+} from "./zodios.types";
+import { HTTP_METHODS } from "./zodios.types";
+import {
+ ZodiosPlugins,
+ schemaValidationPlugin,
+ formDataPlugin,
+ formURLPlugin,
+ headerPlugin,
+} from "./plugins";
+import type { PickRequired, ReadonlyDeep } from "./utils.types";
+import { checkApi } from "./api";
+import type { AnyZodiosTypeProvider, ZodTypeProvider } from "./type-providers";
+import { zodTypeProvider } from "./type-providers";
+import {
+ AnyZodiosFetcherProvider,
+ TypeOfFetcherOptions,
+ ZodiosFetcher,
+} from "./fetcher-providers";
+import {
+ findEndpoint,
+ findEndpointErrorsByAlias,
+ findEndpointErrorsByPath,
+} from "./utils";
+import { hooks } from "./hooks";
+import {
+ PluginPriority,
+ ZodiosPluginFilters,
+ PluginId,
+ PluginPriorities,
+} from "./plugins/zodios-plugins.types";
+
+export interface ZodiosBase<
+ Api extends readonly ZodiosEndpointDefinition[] | ZodiosEndpointDefinition[],
+ FetcherProvider extends AnyZodiosFetcherProvider,
+ TypeProvider extends AnyZodiosTypeProvider
+> {
+ readonly api: Api;
+ readonly _typeProvider: TypeProvider;
+ readonly _fetcherProvider: FetcherProvider;
+}
+
+/**
+ * zodios api client
+ */
+export class ZodiosCoreImpl<
+ const Api extends
+ | readonly ZodiosEndpointDefinition[]
+ | ZodiosEndpointDefinition[],
+ FetcherProvider extends AnyZodiosFetcherProvider,
+ TypeProvider extends AnyZodiosTypeProvider = ZodTypeProvider
+> implements ZodiosBase
+{
+ public readonly options: PickRequired<
+ ZodiosOptions,
+ "validate" | "transform" | "sendDefaults" | "typeProvider"
+ >;
+ public readonly api: Api;
+ public readonly fetcher: ZodiosFetcher | undefined;
+ public readonly _typeProvider: TypeProvider;
+ public readonly _fetcherProvider: FetcherProvider;
+ private plugins = new ZodiosPlugins();
+
+ /**
+ * constructor
+ * @param baseURL - the base url to use - if omited will use the browser domain
+ * @param api - the description of all the api endpoints
+ * @param options - the options to setup the client API
+ * @example
+ * const apiClient = new Zodios("https://jsonplaceholder.typicode.com", [
+ * {
+ * method: "get",
+ * path: "/users",
+ * description: "Get all users",
+ * parameters: [
+ * {
+ * name: "q",
+ * type: "Query",
+ * schema: z.string(),
+ * },
+ * {
+ * name: "page",
+ * type: "Query",
+ * schema: z.string().optional(),
+ * },
+ * ],
+ * response: z.array(z.object({ id: z.number(), name: z.string() })),
+ * }
+ * ]);
+ */
+ constructor(
+ api: Api,
+ options?: ZodiosOptions &
+ TypeOfFetcherOptions
+ );
+ constructor(
+ baseUrl: string,
+ api: Api,
+ options?: ZodiosOptions &
+ TypeOfFetcherOptions
+ );
+ constructor(
+ arg1?: Api | string,
+ arg2?:
+ | Api
+ | (ZodiosOptions &
+ TypeOfFetcherOptions