diff --git a/.gitignore b/.gitignore index 04015870b..9ddc45ba5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ dist .vercel .DS_Store .vscode/settings.json +.env.local diff --git a/CHANGELOG.md b/CHANGELOG.md index 60b496877..14a85cdea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +# 0.5.0 (2022-12-15) + +### Features + +- Serialization between client (hooks) and server now uses [superjson](https://github.com/blitz-js/superjson), [[#139](https://github.com/zenstackhq/zenstack/issues/139)] + +### Fixes and improvements + +- Fixed goto definition issue in VSCode extension, [[#69](https://github.com/zenstackhq/zenstack/issues/69)] + +### Breaking changes + +- Next-auth adapter and helper are moved to a separate package `@zenstackhq/next-auth`. + # 0.4.0 (2022-12-01) ### Features diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..4998472ff --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| >=0.4.0 | :white_check_mark: | + +## Reporting a Vulnerability + +Please [create an issue](https://github.com/zenstackhq/zenstack/issues) and add a "security" label. We'll actively watch, verify and fix them with high priority. +Alternatively, you can also reach out to us at contact@zenstack.dev. + +Thank you for helping us make a better project! diff --git a/doc-serve/.eslintrc.json b/doc-serve/.eslintrc.json new file mode 100644 index 000000000..bffb357a7 --- /dev/null +++ b/doc-serve/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/doc-serve/.gitignore b/doc-serve/.gitignore new file mode 100644 index 000000000..c87c9b392 --- /dev/null +++ b/doc-serve/.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/doc-serve/README.md b/doc-serve/README.md new file mode 100644 index 000000000..c87e0421d --- /dev/null +++ b/doc-serve/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/doc-serve/middleware.ts b/doc-serve/middleware.ts new file mode 100644 index 000000000..c20bf1632 --- /dev/null +++ b/doc-serve/middleware.ts @@ -0,0 +1,31 @@ +import { NextRequest, NextResponse } from 'next/server'; + +export const config = { + matcher: '/:path*', +}; + +const botUAPattern = /.*(Googlebot|bingbot).*/i; + +export default async function middleware(req: NextRequest) { + const url = req.nextUrl; + + if (url.pathname.includes('.')) { + return NextResponse.next(); + } + + const ua = req.headers.get('user-agent'); + + if (ua && botUAPattern.test(ua)) { + const trimmed = url.pathname.replace(/^\//, ''); + if (trimmed === '' || trimmed === '/') { + url.pathname = '/static/index.html'; + } else { + url.pathname = `/static/${trimmed}.html`; + } + console.log(`REWRITE: ua - ${ua}, url - ${url.pathname}`); + return NextResponse.rewrite(url); + } else { + url.pathname = '/index.html'; + return NextResponse.rewrite(url); + } +} diff --git a/doc-serve/next.config.js b/doc-serve/next.config.js new file mode 100644 index 000000000..ae887958d --- /dev/null +++ b/doc-serve/next.config.js @@ -0,0 +1,7 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, + swcMinify: true, +} + +module.exports = nextConfig diff --git a/doc-serve/package-lock.json b/doc-serve/package-lock.json new file mode 100644 index 000000000..40af89b5d --- /dev/null +++ b/doc-serve/package-lock.json @@ -0,0 +1,5107 @@ +{ + "name": "doc-serve", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "doc-serve", + "version": "0.1.0", + "dependencies": { + "@types/node": "18.11.13", + "@types/react": "18.0.26", + "@types/react-dom": "18.0.9", + "eslint": "8.29.0", + "eslint-config-next": "13.0.6", + "next": "13.0.6", + "react": "18.2.0", + "react-dom": "18.2.0", + "typescript": "4.9.4" + } + }, + "node_modules/@babel/runtime": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", + "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz", + "integrity": "sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==", + "dependencies": { + "core-js-pure": "^3.25.1", + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.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" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + }, + "node_modules/@next/env": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.0.6.tgz", + "integrity": "sha512-yceT6DCHKqPRS1cAm8DHvDvK74DLIkDQdm5iV+GnIts8h0QbdHvkUIkdOvQoOODgpr6018skbmSQp12z5OWIQQ==" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.0.6.tgz", + "integrity": "sha512-JUANdYNCddhmQBjQQPxEJYL7GMCqYtbfrdmtX7c013srig7waNCG69Aoql7CgAgjdy8jn1ovHVdcF/NB46XN3Q==", + "dependencies": { + "glob": "7.1.7" + } + }, + "node_modules/@next/swc-android-arm-eabi": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.0.6.tgz", + "integrity": "sha512-FGFSj3v2Bluw8fD/X+1eXIEB0PhoJE0zfutsAauRhmNpjjZshLDgoXMWm1jTRL/04K/o9gwwO2+A8+sPVCH1uw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-android-arm64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.0.6.tgz", + "integrity": "sha512-7MgbtU7kimxuovVsd7jSJWMkIHBDBUsNLmmlkrBRHTvgzx5nDBXogP0hzZm7EImdOPwVMPpUHRQMBP9mbsiJYQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.0.6.tgz", + "integrity": "sha512-AUVEpVTxbP/fxdFsjVI9d5a0CFn6NVV7A/RXOb0Y+pXKIIZ1V5rFjPwpYfIfyOo2lrqgehMNQcyMRoTrhq04xg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.0.6.tgz", + "integrity": "sha512-SasCDJlshglsPnbzhWaIF6VEGkQy2NECcAOxPwaPr0cwbbt4aUlZ7QmskNzgolr5eAjFS/xTr7CEeKJtZpAAtQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-freebsd-x64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.0.6.tgz", + "integrity": "sha512-6Lbxd9gAdXneTkwHyYW/qtX1Tdw7ND9UbiGsGz/SP43ZInNWnW6q0au4hEVPZ9bOWWRKzcVoeTBdoMpQk9Hx9w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm-gnueabihf": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.0.6.tgz", + "integrity": "sha512-wNdi5A519e1P+ozEuYOhWPzzE6m1y7mkO6NFwn6watUwO0X9nZs7fT9THmnekvmFQpaZ6U+xf2MQ9poQoCh6jQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.0.6.tgz", + "integrity": "sha512-e8KTRnleQY1KLk5PwGV5hrmvKksCc74QRpHl5ffWnEEAtL2FE0ave5aIkXqErsPdXkiKuA/owp3LjQrP+/AH7Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.0.6.tgz", + "integrity": "sha512-/7RF03C3mhjYpHN+pqOolgME3guiHU5T3TsejuyteqyEyzdEyLHod+jcYH6ft7UZ71a6TdOewvmbLOtzHW2O8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.0.6.tgz", + "integrity": "sha512-kxyEXnYHpOEkFnmrlwB1QlzJtjC6sAJytKcceIyFUHbCaD3W/Qb5tnclcnHKTaFccizZRePXvV25Ok/eUSpKTw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.0.6.tgz", + "integrity": "sha512-N0c6gubS3WW1oYYgo02xzZnNatfVQP/CiJq2ax+DJ55ePV62IACbRCU99TZNXXg+Kos6vNW4k+/qgvkvpGDeyA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.0.6.tgz", + "integrity": "sha512-QjeMB2EBqBFPb/ac0CYr7GytbhUkrG4EwFWbcE0vsRp4H8grt25kYpFQckL4Jak3SUrp7vKfDwZ/SwO7QdO8vw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.0.6.tgz", + "integrity": "sha512-EQzXtdqRTcmhT/tCq81rIwE36Y3fNHPInaCuJzM/kftdXfa0F+64y7FAoMO13npX8EG1+SamXgp/emSusKrCXg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.6.tgz", + "integrity": "sha512-pSkqZ//UP/f2sS9T7IvHLfEWDPTX0vRyXJnAUNisKvO3eF3e1xdhDX7dix/X3Z3lnN4UjSwOzclAI87JFbOwmQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgr/utils": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.3.1.tgz", + "integrity": "sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==", + "dependencies": { + "cross-spawn": "^7.0.3", + "is-glob": "^4.0.3", + "open": "^8.4.0", + "picocolors": "^1.0.0", + "tiny-glob": "^0.2.9", + "tslib": "^2.4.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", + "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" + }, + "node_modules/@swc/helpers": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", + "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, + "node_modules/@types/node": { + "version": "18.11.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.13.tgz", + "integrity": "sha512-IASpMGVcWpUsx5xBOrxMj7Bl8lqfuTY7FKAnPmu5cHkfQVWF8GulWS1jbRqA934qZL35xh5xN/+Xe/i26Bod4w==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "node_modules/@types/react": { + "version": "18.0.26", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", + "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", + "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.0.tgz", + "integrity": "sha512-joNO6zMGUZg+C73vwrKXCd8usnsmOYmgW/w5ZW0pG0RGvqeznjtGDk61EqqTpNrFLUYBW2RSBFrxdAZMqA4OZA==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.46.0", + "@typescript-eslint/types": "5.46.0", + "@typescript-eslint/typescript-estree": "5.46.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.0.tgz", + "integrity": "sha512-7wWBq9d/GbPiIM6SqPK9tfynNxVbfpihoY5cSFMer19OYUA3l4powA2uv0AV2eAZV6KoAh6lkzxv4PoxOLh1oA==", + "dependencies": { + "@typescript-eslint/types": "5.46.0", + "@typescript-eslint/visitor-keys": "5.46.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.0.tgz", + "integrity": "sha512-wHWgQHFB+qh6bu0IAPAJCdeCdI0wwzZnnWThlmHNY01XJ9Z97oKqKOzWYpR2I83QmshhQJl6LDM9TqMiMwJBTw==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.0.tgz", + "integrity": "sha512-kDLNn/tQP+Yp8Ro2dUpyyVV0Ksn2rmpPpB0/3MO874RNmXtypMwSeazjEN/Q6CTp8D7ExXAAekPEcCEB/vtJkw==", + "dependencies": { + "@typescript-eslint/types": "5.46.0", + "@typescript-eslint/visitor-keys": "5.46.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.0.tgz", + "integrity": "sha512-E13gBoIXmaNhwjipuvQg1ByqSAu/GbEpP/qzFihugJ+MomtoJtFAJG/+2DRPByf57B863m0/q7Zt16V9ohhANw==", + "dependencies": { + "@typescript-eslint/types": "5.46.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dependencies": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" + }, + "node_modules/axe-core": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", + "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001439", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/core-js-pure": { + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", + "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/enhanced-resolve": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-abstract": { + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", + "integrity": "sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==", + "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", + "gopd": "^1.0.1", + "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.6", + "string.prototype.trimstart": "^1.0.6", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz", + "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==", + "dependencies": { + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@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.15.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" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.0.6.tgz", + "integrity": "sha512-Tfn/0lirhkEuoGxKMtDQNtQuC7P3eHcyUyhIJY/OHtjU9ExHFtcge/Fe8Ou/Jd7DIC71vN3CT72oszVwia71cg==", + "dependencies": { + "@next/eslint-plugin-next": "13.0.6", + "@rushstack/eslint-patch": "^1.1.3", + "@typescript-eslint/parser": "^5.42.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.31.7", + "eslint-plugin-react-hooks": "^4.5.0" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.2.tgz", + "integrity": "sha512-zX4ebnnyXiykjhcBvKIf5TNvt8K7yX6bllTRZ14MiurKPjDpCAZujlszTdB8pcNXhZcOf+god4s9SjQa5GnytQ==", + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.10.0", + "get-tsconfig": "^4.2.0", + "globby": "^13.1.2", + "is-core-module": "^2.10.0", + "is-glob": "^4.0.3", + "synckit": "^0.8.4" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "node_modules/eslint-import-resolver-typescript/node_modules/globby": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", + "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-import-resolver-typescript/node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "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" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", + "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" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.31.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", + "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "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.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "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" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "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" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "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" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "node_modules/fastq": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.2.0.tgz", + "integrity": "sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==", + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", + "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ignore": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "dependencies": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" + }, + "node_modules/language-tags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.6.tgz", + "integrity": "sha512-HNkaCgM8wZgE/BZACeotAAgpL9FUjEnhgF0FVQMIgH//zqTPreLYMb3rWYkYAqPoF75Jwuycp1da7uz66cfFQg==", + "dependencies": { + "language-subtag-registry": "^0.3.20" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "node_modules/next": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/next/-/next-13.0.6.tgz", + "integrity": "sha512-COvigvms2LRt1rrzfBQcMQ2GZd86Mvk1z+LOLY5pniFtL4VrTmhZ9salrbKfSiXbhsD01TrDdD68ec3ABDyscA==", + "dependencies": { + "@next/env": "13.0.6", + "@swc/helpers": "0.4.14", + "caniuse-lite": "^1.0.30001406", + "postcss": "8.4.14", + "styled-jsx": "5.1.0" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=14.6.0" + }, + "optionalDependencies": { + "@next/swc-android-arm-eabi": "13.0.6", + "@next/swc-android-arm64": "13.0.6", + "@next/swc-darwin-arm64": "13.0.6", + "@next/swc-darwin-x64": "13.0.6", + "@next/swc-freebsd-x64": "13.0.6", + "@next/swc-linux-arm-gnueabihf": "13.0.6", + "@next/swc-linux-arm64-gnu": "13.0.6", + "@next/swc-linux-arm64-musl": "13.0.6", + "@next/swc-linux-x64-gnu": "13.0.6", + "@next/swc-linux-x64-musl": "13.0.6", + "@next/swc-win32-arm64-msvc": "13.0.6", + "@next/swc-win32-ia32-msvc": "13.0.6", + "@next/swc-win32-x64-msvc": "13.0.6" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^6.0.0 || ^7.0.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "dependencies": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "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" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.0.tgz", + "integrity": "sha512-/iHaRJt9U7T+5tp6TRelLnqBqiaIT0HsO0+vgyj8hK2KUk7aejFqRrumqPUlAqDwAj8IbS/1hk3IhBAAK/FCUQ==", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.4.tgz", + "integrity": "sha512-Dn2ZkzMdSX827QbowGbU/4yjWuvNaCoScLLoMo/yKbu+P4GBR6cRGKZH27k6a9bRzdqcyd1DE96pQtQ6uNkmyw==", + "dependencies": { + "@pkgr/utils": "^2.3.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dependencies": { + "tslib": "^1.8.1" + }, + "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" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "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" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@babel/runtime": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", + "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", + "requires": { + "regenerator-runtime": "^0.13.11" + } + }, + "@babel/runtime-corejs3": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz", + "integrity": "sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==", + "requires": { + "core-js-pure": "^3.25.1", + "regenerator-runtime": "^0.13.11" + } + }, + "@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.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": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + }, + "@next/env": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-13.0.6.tgz", + "integrity": "sha512-yceT6DCHKqPRS1cAm8DHvDvK74DLIkDQdm5iV+GnIts8h0QbdHvkUIkdOvQoOODgpr6018skbmSQp12z5OWIQQ==" + }, + "@next/eslint-plugin-next": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.0.6.tgz", + "integrity": "sha512-JUANdYNCddhmQBjQQPxEJYL7GMCqYtbfrdmtX7c013srig7waNCG69Aoql7CgAgjdy8jn1ovHVdcF/NB46XN3Q==", + "requires": { + "glob": "7.1.7" + } + }, + "@next/swc-android-arm-eabi": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.0.6.tgz", + "integrity": "sha512-FGFSj3v2Bluw8fD/X+1eXIEB0PhoJE0zfutsAauRhmNpjjZshLDgoXMWm1jTRL/04K/o9gwwO2+A8+sPVCH1uw==", + "optional": true + }, + "@next/swc-android-arm64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-13.0.6.tgz", + "integrity": "sha512-7MgbtU7kimxuovVsd7jSJWMkIHBDBUsNLmmlkrBRHTvgzx5nDBXogP0hzZm7EImdOPwVMPpUHRQMBP9mbsiJYQ==", + "optional": true + }, + "@next/swc-darwin-arm64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.0.6.tgz", + "integrity": "sha512-AUVEpVTxbP/fxdFsjVI9d5a0CFn6NVV7A/RXOb0Y+pXKIIZ1V5rFjPwpYfIfyOo2lrqgehMNQcyMRoTrhq04xg==", + "optional": true + }, + "@next/swc-darwin-x64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.0.6.tgz", + "integrity": "sha512-SasCDJlshglsPnbzhWaIF6VEGkQy2NECcAOxPwaPr0cwbbt4aUlZ7QmskNzgolr5eAjFS/xTr7CEeKJtZpAAtQ==", + "optional": true + }, + "@next/swc-freebsd-x64": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.0.6.tgz", + "integrity": "sha512-6Lbxd9gAdXneTkwHyYW/qtX1Tdw7ND9UbiGsGz/SP43ZInNWnW6q0au4hEVPZ9bOWWRKzcVoeTBdoMpQk9Hx9w==", + "optional": true + }, + "@next/swc-linux-arm-gnueabihf": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.0.6.tgz", + "integrity": "sha512-wNdi5A519e1P+ozEuYOhWPzzE6m1y7mkO6NFwn6watUwO0X9nZs7fT9THmnekvmFQpaZ6U+xf2MQ9poQoCh6jQ==", + "optional": true + }, + "@next/swc-linux-arm64-gnu": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.0.6.tgz", + "integrity": "sha512-e8KTRnleQY1KLk5PwGV5hrmvKksCc74QRpHl5ffWnEEAtL2FE0ave5aIkXqErsPdXkiKuA/owp3LjQrP+/AH7Q==", + "optional": true + }, + "@next/swc-linux-arm64-musl": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.0.6.tgz", + "integrity": "sha512-/7RF03C3mhjYpHN+pqOolgME3guiHU5T3TsejuyteqyEyzdEyLHod+jcYH6ft7UZ71a6TdOewvmbLOtzHW2O8A==", + "optional": true + }, + "@next/swc-linux-x64-gnu": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.0.6.tgz", + "integrity": "sha512-kxyEXnYHpOEkFnmrlwB1QlzJtjC6sAJytKcceIyFUHbCaD3W/Qb5tnclcnHKTaFccizZRePXvV25Ok/eUSpKTw==", + "optional": true + }, + "@next/swc-linux-x64-musl": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.0.6.tgz", + "integrity": "sha512-N0c6gubS3WW1oYYgo02xzZnNatfVQP/CiJq2ax+DJ55ePV62IACbRCU99TZNXXg+Kos6vNW4k+/qgvkvpGDeyA==", + "optional": true + }, + "@next/swc-win32-arm64-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.0.6.tgz", + "integrity": "sha512-QjeMB2EBqBFPb/ac0CYr7GytbhUkrG4EwFWbcE0vsRp4H8grt25kYpFQckL4Jak3SUrp7vKfDwZ/SwO7QdO8vw==", + "optional": true + }, + "@next/swc-win32-ia32-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.0.6.tgz", + "integrity": "sha512-EQzXtdqRTcmhT/tCq81rIwE36Y3fNHPInaCuJzM/kftdXfa0F+64y7FAoMO13npX8EG1+SamXgp/emSusKrCXg==", + "optional": true + }, + "@next/swc-win32-x64-msvc": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.6.tgz", + "integrity": "sha512-pSkqZ//UP/f2sS9T7IvHLfEWDPTX0vRyXJnAUNisKvO3eF3e1xdhDX7dix/X3Z3lnN4UjSwOzclAI87JFbOwmQ==", + "optional": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@pkgr/utils": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.3.1.tgz", + "integrity": "sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==", + "requires": { + "cross-spawn": "^7.0.3", + "is-glob": "^4.0.3", + "open": "^8.4.0", + "picocolors": "^1.0.0", + "tiny-glob": "^0.2.9", + "tslib": "^2.4.0" + } + }, + "@rushstack/eslint-patch": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", + "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" + }, + "@swc/helpers": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", + "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", + "requires": { + "tslib": "^2.4.0" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" + }, + "@types/node": { + "version": "18.11.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.13.tgz", + "integrity": "sha512-IASpMGVcWpUsx5xBOrxMj7Bl8lqfuTY7FKAnPmu5cHkfQVWF8GulWS1jbRqA934qZL35xh5xN/+Xe/i26Bod4w==" + }, + "@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "@types/react": { + "version": "18.0.26", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", + "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "18.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", + "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", + "requires": { + "@types/react": "*" + } + }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + }, + "@typescript-eslint/parser": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.46.0.tgz", + "integrity": "sha512-joNO6zMGUZg+C73vwrKXCd8usnsmOYmgW/w5ZW0pG0RGvqeznjtGDk61EqqTpNrFLUYBW2RSBFrxdAZMqA4OZA==", + "requires": { + "@typescript-eslint/scope-manager": "5.46.0", + "@typescript-eslint/types": "5.46.0", + "@typescript-eslint/typescript-estree": "5.46.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.46.0.tgz", + "integrity": "sha512-7wWBq9d/GbPiIM6SqPK9tfynNxVbfpihoY5cSFMer19OYUA3l4powA2uv0AV2eAZV6KoAh6lkzxv4PoxOLh1oA==", + "requires": { + "@typescript-eslint/types": "5.46.0", + "@typescript-eslint/visitor-keys": "5.46.0" + } + }, + "@typescript-eslint/types": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.46.0.tgz", + "integrity": "sha512-wHWgQHFB+qh6bu0IAPAJCdeCdI0wwzZnnWThlmHNY01XJ9Z97oKqKOzWYpR2I83QmshhQJl6LDM9TqMiMwJBTw==" + }, + "@typescript-eslint/typescript-estree": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.46.0.tgz", + "integrity": "sha512-kDLNn/tQP+Yp8Ro2dUpyyVV0Ksn2rmpPpB0/3MO874RNmXtypMwSeazjEN/Q6CTp8D7ExXAAekPEcCEB/vtJkw==", + "requires": { + "@typescript-eslint/types": "5.46.0", + "@typescript-eslint/visitor-keys": "5.46.0", + "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": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.46.0.tgz", + "integrity": "sha512-E13gBoIXmaNhwjipuvQg1ByqSAu/GbEpP/qzFihugJ+MomtoJtFAJG/+2DRPByf57B863m0/q7Zt16V9ohhANw==", + "requires": { + "@typescript-eslint/types": "5.46.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "acorn": { + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "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": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + } + }, + "array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "requires": { + "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" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" + }, + "axe-core": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", + "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==" + }, + "axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "caniuse-lite": { + "version": "1.0.30001439", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==" + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "core-js-pure": { + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", + "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==" + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "csstype": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + }, + "damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==" + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "enhanced-resolve": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "es-abstract": { + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", + "integrity": "sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==", + "requires": { + "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", + "gopd": "^1.0.1", + "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.6", + "string.prototype.trimstart": "^1.0.6", + "unbox-primitive": "^1.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "eslint": { + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz", + "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==", + "requires": { + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@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.15.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" + } + }, + "eslint-config-next": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.0.6.tgz", + "integrity": "sha512-Tfn/0lirhkEuoGxKMtDQNtQuC7P3eHcyUyhIJY/OHtjU9ExHFtcge/Fe8Ou/Jd7DIC71vN3CT72oszVwia71cg==", + "requires": { + "@next/eslint-plugin-next": "13.0.6", + "@rushstack/eslint-patch": "^1.1.3", + "@typescript-eslint/parser": "^5.42.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.31.7", + "eslint-plugin-react-hooks": "^4.5.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-import-resolver-typescript": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.2.tgz", + "integrity": "sha512-zX4ebnnyXiykjhcBvKIf5TNvt8K7yX6bllTRZ14MiurKPjDpCAZujlszTdB8pcNXhZcOf+god4s9SjQa5GnytQ==", + "requires": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.10.0", + "get-tsconfig": "^4.2.0", + "globby": "^13.1.2", + "is-core-module": "^2.10.0", + "is-glob": "^4.0.3", + "synckit": "^0.8.4" + }, + "dependencies": { + "globby": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", + "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==" + } + } + }, + "eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "requires": { + "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" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", + "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", + "requires": { + "@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" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "eslint-plugin-react": { + "version": "7.31.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", + "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "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.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.8" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "requires": {} + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==" + }, + "espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "requires": { + "estraverse": "^5.1.0" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "requires": { + "@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" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "fastq": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "requires": { + "reusify": "^1.0.4" + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==" + }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "get-tsconfig": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.2.0.tgz", + "integrity": "sha512-X8u8fREiYOE6S8hLbq99PeykTDoLVnxvF4DjWKJmz9xy2nNRdUcV8ZN9tniJFeKyTU3qnC9lL8n4Chd6LmVKHg==" + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "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-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", + "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "requires": { + "type-fest": "^0.20.2" + } + }, + "globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "requires": { + "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" + } + }, + "globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "ignore": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "requires": { + "is-docker": "^2.0.0" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "requires": { + "minimist": "^1.2.0" + } + }, + "jsx-ast-utils": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "requires": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + } + }, + "language-subtag-registry": { + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", + "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" + }, + "language-tags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.6.tgz", + "integrity": "sha512-HNkaCgM8wZgE/BZACeotAAgpL9FUjEnhgF0FVQMIgH//zqTPreLYMb3rWYkYAqPoF75Jwuycp1da7uz66cfFQg==", + "requires": { + "language-subtag-registry": "^0.3.20" + } + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "requires": { + "p-locate": "^5.0.0" + } + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "next": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/next/-/next-13.0.6.tgz", + "integrity": "sha512-COvigvms2LRt1rrzfBQcMQ2GZd86Mvk1z+LOLY5pniFtL4VrTmhZ9salrbKfSiXbhsD01TrDdD68ec3ABDyscA==", + "requires": { + "@next/env": "13.0.6", + "@next/swc-android-arm-eabi": "13.0.6", + "@next/swc-android-arm64": "13.0.6", + "@next/swc-darwin-arm64": "13.0.6", + "@next/swc-darwin-x64": "13.0.6", + "@next/swc-freebsd-x64": "13.0.6", + "@next/swc-linux-arm-gnueabihf": "13.0.6", + "@next/swc-linux-arm64-gnu": "13.0.6", + "@next/swc-linux-arm64-musl": "13.0.6", + "@next/swc-linux-x64-gnu": "13.0.6", + "@next/swc-linux-x64-musl": "13.0.6", + "@next/swc-win32-arm64-msvc": "13.0.6", + "@next/swc-win32-ia32-msvc": "13.0.6", + "@next/swc-win32-x64-msvc": "13.0.6", + "@swc/helpers": "0.4.14", + "caniuse-lite": "^1.0.30001406", + "postcss": "8.4.14", + "styled-jsx": "5.1.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "requires": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "requires": { + "wrappy": "1" + } + }, + "open": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "requires": { + "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": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "requires": { + "p-limit": "^3.0.2" + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "postcss": { + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, + "scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" + }, + "string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "requires": { + "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" + } + }, + "string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "styled-jsx": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.0.tgz", + "integrity": "sha512-/iHaRJt9U7T+5tp6TRelLnqBqiaIT0HsO0+vgyj8hK2KUk7aejFqRrumqPUlAqDwAj8IbS/1hk3IhBAAK/FCUQ==", + "requires": { + "client-only": "0.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "synckit": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.4.tgz", + "integrity": "sha512-Dn2ZkzMdSX827QbowGbU/4yjWuvNaCoScLLoMo/yKbu+P4GBR6cRGKZH27k6a9bRzdqcyd1DE96pQtQ6uNkmyw==", + "requires": { + "@pkgr/utils": "^2.3.1", + "tslib": "^2.4.0" + } + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + }, + "tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "requires": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + }, + "typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==" + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "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" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + } + } +} diff --git a/doc-serve/package.json b/doc-serve/package.json new file mode 100644 index 000000000..cd602b5c1 --- /dev/null +++ b/doc-serve/package.json @@ -0,0 +1,22 @@ +{ + "name": "doc-serve", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@types/node": "18.11.13", + "@types/react": "18.0.26", + "@types/react-dom": "18.0.9", + "eslint": "8.29.0", + "eslint-config-next": "13.0.6", + "next": "13.0.6", + "react": "18.2.0", + "react-dom": "18.2.0", + "typescript": "4.9.4" + } +} diff --git a/doc-serve/pages/.gitkeep b/doc-serve/pages/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/doc-serve/public/8cd31ff7afe74424abbec00b65f04ae8.txt b/doc-serve/public/8cd31ff7afe74424abbec00b65f04ae8.txt new file mode 100644 index 000000000..4c8237722 --- /dev/null +++ b/doc-serve/public/8cd31ff7afe74424abbec00b65f04ae8.txt @@ -0,0 +1 @@ +8cd31ff7afe74424abbec00b65f04ae8 diff --git a/doc-serve/public/README.md b/doc-serve/public/README.md new file mode 100644 index 000000000..50e6e9cc5 --- /dev/null +++ b/doc-serve/public/README.md @@ -0,0 +1,28 @@ +# ZenStack + +> A toolkit for building secure CRUD apps with Next.js. + +## What it is + +ZenStack is a schema-first toolkit for defining data models, relations and access policies. It generates database schema, backend CRUD services and frontend React hooks for you automatically from the model. Our goal is to let you save time writing boilerplate code and focus on building real features! + +_NOTE_: ZenStack is built above [Prisma ORM](https://www.prisma.io/) - the greatest ORM solution for Typescript. It extends Prisma's power from database handling to full-stack development. + +See the [Quick start](quick-start.md) guide for more details. + +## Features + +- Intuitive data & authorization modeling language +- Generating RESTful CRUD services and React hooks +- End-to-end type safety +- Support for [all major relational databases](zmodel-data-source.md#supported-databases) +- Integration with authentication libraries (like [NextAuth](https://next-auth.js.org/ ':target=_blank')) +- [VSCode extension](https://marketplace.visualstudio.com/items?itemName=zenstack.zenstack ':target=_blank') for model authoring + +## Examples + +Check out the [Collaborative Todo App](https://zenstack-todo.vercel.app/ ':target=_blank') for a running example. You can find the source code [here](https://github.com/zenstackhq/todo-demo-sqlite ':target=_blank'). + +## Community + +Join our [discord server](https://go.zenstack.dev/chat ':target=_blank') for chat and updates! diff --git a/doc-serve/public/_coverpage.md b/doc-serve/public/_coverpage.md new file mode 100644 index 000000000..539dc966a --- /dev/null +++ b/doc-serve/public/_coverpage.md @@ -0,0 +1,12 @@ +![cover-logo](_media/logo.png) + +# ZenStack 0.4.0 + +> A toolkit for building secure CRUD apps with Next.js + Typescript. + +- Full-stack toolkit made for front-end developers +- Intuitive and flexible data modeling +- No more boilerplate CRUD code + +[GitHub](https://github.com/zenstackhq/zenstack/) +[Get Started](#zenstack) diff --git a/doc-serve/public/_media/banner.png b/doc-serve/public/_media/banner.png new file mode 100644 index 000000000..b2074d34e Binary files /dev/null and b/doc-serve/public/_media/banner.png differ diff --git a/doc-serve/public/_media/cli-shot.png b/doc-serve/public/_media/cli-shot.png new file mode 100644 index 000000000..6f7fdbc6e Binary files /dev/null and b/doc-serve/public/_media/cli-shot.png differ diff --git a/doc-serve/public/_media/logo.png b/doc-serve/public/_media/logo.png new file mode 100644 index 000000000..7358d53b6 Binary files /dev/null and b/doc-serve/public/_media/logo.png differ diff --git a/doc-serve/public/_media/starter-shot.png b/doc-serve/public/_media/starter-shot.png new file mode 100644 index 000000000..d6531d8b1 Binary files /dev/null and b/doc-serve/public/_media/starter-shot.png differ diff --git a/doc-serve/public/_navbar.md b/doc-serve/public/_navbar.md new file mode 100644 index 000000000..1c416471c --- /dev/null +++ b/doc-serve/public/_navbar.md @@ -0,0 +1 @@ +- [Live Chat](https://go.zenstack.dev/chat ':target=_blank') diff --git a/doc-serve/public/_sidebar.md b/doc-serve/public/_sidebar.md new file mode 100644 index 000000000..7e1be8536 --- /dev/null +++ b/doc-serve/public/_sidebar.md @@ -0,0 +1,38 @@ +- Getting started + + - [Quick start](quick-start.md) + - [Modeling your app](modeling-your-app.md) + - [Code generation](code-generation.md) + - [Building your app](building-your-app.md) + +- ZModel reference + + - [Overview](zmodel-overview.md) + - [Data source](zmodel-data-source.md) + - [Enum](zmodel-enum.md) + - [Data model](zmodel-data-model.md) + - [Attribute](zmodel-attribute.md) + - [Field](zmodel-field.md) + - [Relation](zmodel-relation.md) + - [Access policy](zmodel-access-policy.md) + - [Field constraint](zmodel-field-constraint.md) + - [Referential action](zmodel-referential-action.md) + +- CLI reference + + - [Commands](cli-commands.md) + +- [Runtime API](runtime-api.md) + +- Guide + + - [Choosing a database](choosing-a-database.md) + - [Evolving model with migration](evolving-model-with-migration.md) + - [Integrating authentication](integrating-authentication.md) + - [Server-side rendering](server-side-rendering.md) + - [Set up logging](setup-logging.md) + - [Telemetry](telemetry.md) + +- [VSCode extension](vscode-extension.md) +- [Reach out to the developers](reach-out.md) +- [Changelog](changelog) diff --git a/doc-serve/public/building-your-app.md b/doc-serve/public/building-your-app.md new file mode 100644 index 000000000..e25d70ac6 --- /dev/null +++ b/doc-serve/public/building-your-app.md @@ -0,0 +1,149 @@ +# Building your app + +The code generated from your model covers everything you need to implement CRUD, frontend and backend. This section illustrates the steps of using them when building your app. + +## Mounting backend services + +First you should mount the generated server-side code as a Next.js API endpoint. Here's an example: + +```ts +// pages/api/zenstack/[...path].ts + +import { authOptions } from '@api/auth/[...nextauth]'; +import service from '@zenstackhq/runtime'; +import { + requestHandler, + type RequestHandlerOptions, +} from '@zenstackhq/runtime/server'; +import { NextApiRequest, NextApiResponse } from 'next'; +import { unstable_getServerSession } from 'next-auth'; + +const options: RequestHandlerOptions = { + // a callback for getting the current login user + async getServerUser(req: NextApiRequest, res: NextApiResponse) { + // here we use NextAuth is used as an example, and you can change it to + // suit the authentication solution you use + const session = await unstable_getServerSession(req, res, authOptions); + return session?.user; + }, +}; +export default requestHandler(service, options); +``` + +Please note that the services need to be configured with a callback `getServerUser` for getting the current login user. The example above uses NextAuth to do it, but you can also hand-code it based on the authentication approach you use, as long as it returns a user object that represents the current session's user. + +_NOTE_ Check out [this guide](integrating-authentication.md) for more details about integrating with authentication. + +Make sure the services are mounted at route `/api/zenstack/` with a catch all parameter named `path`, as this is required by the generate React hooks. + +## _optional_ Integrating with NextAuth + +If you use NextAuth for authentication, you can install the `@zenstackhq/next-auth` package for easier integration. This package provides an adapter and authorization helper that you can use to configure NextAuth. + +```ts +// pages/api/auth/[...nextauth].ts + +import service from '@zenstackhq/runtime'; +import { authorize, Adapter } from '@zenstackhq/next-auth'; +import NextAuth, { type NextAuthOptions } from 'next-auth'; + +export const authOptions: NextAuthOptions = { + // use ZenStack adapter for persistence + adapter: Adapter(service), + + providers: [ + CredentialsProvider({ + credentials: { ... }, + // use the generated "authorize" helper for credential based authentication + authorize: authorize(service), + }), + ] + + ... +}; + +export default NextAuth(authOptions); +``` + +Find more details [here](integrating-authentication.md) about integrating with different authentication schemes. + +## Using React hooks + +React hooks are generated for CRUD'ing each data model you defined. They save your time writing explicit HTTP requests to call the generated services. Internally the hooks use [SWR](https://swr.vercel.app/) for data fetching, so you'll also enjoy its built-in features, like caching, revalidation on interval, etc. + +_NOTE_ The generated service code is injected with the access policies you defined in the model, so it's already secure, regardless called directly or via hooks. A read operation only returns data that's supposed to be visible to the current user, and a write operation is rejected if the policies verdict so. + +### Read + +Call `find` and `get` hooks for listing entities or loading a specific one. If your entity has relations, you can request related entities to be loaded together. + +```ts +const { find } = usePost(); +// lists unpublished posts with their author's data +const posts = find({ + where: { published: false }, + include: { author: true }, + orderBy: { updatedAt: 'desc' }, +}); +``` + +```ts +const { get } = usePost(); +// fetches a post with its author's data +const post = get(id, { + include: { author: true }, +}); +``` + +### Create + +Call the async `create` method to create a new model entity. Note that if the model has relations, you can create related entities in a nested write. See example below: + +```ts +const { create } = usePost(); +// creating a new post for current user with a nested comment +const post = await create({ + data: { + title: 'My New Post', + author: { + connect: { id: session.user.id }, + }, + comments: { + create: [{ content: 'First comment' }], + }, + }, +}); +``` + +### Update + +Similar to `create`, the update hook also allows nested write. + +```ts +const { update } = usePost(); +// updating a post's content and create a new comment +const post = await update(id, { + data: { + const: 'My post content', + comments: { + create: [{ content: 'A new comment' }], + }, + }, +}); +``` + +### Delete + +```ts +const { del } = usePost(); +const post = await del(id); +``` + +## Server-side coding + +Since doing CRUD with hooks is already secure, in many cases, you can implement your business logic right in the frontend code. + +ZenStack also supports server-side programming for conducting CRUD without sending HTTP requests, or even direct database access (bypassing access policy checks). Please check the following documentation for details: + +- [Server runtime API](runtime-api.md#zenstackhqruntimeserver) +- [Server-side rendering](server-side-rendering.md) diff --git a/docs/ref/database-hosting-considerations.md b/doc-serve/public/choosing-a-database.md similarity index 84% rename from docs/ref/database-hosting-considerations.md rename to doc-serve/public/choosing-a-database.md index 438f8ed69..44bec5d16 100644 --- a/docs/ref/database-hosting-considerations.md +++ b/doc-serve/public/choosing-a-database.md @@ -1,11 +1,11 @@ -# Database Hosting Considerations +# Choosing a database -ZenStack is agnostic about where and how you deploy your web app, but hosting on serverless platforms like [Vercel](https://vercel.com/) is definitely a popular choice. +ZenStack is agnostic about where and how you deploy your web app, but hosting on serverless platforms like [Vercel](https://vercel.com/ ':target=blank') is definitely a popular choice. Serverless architecture has some implications on how you should care about your database hosting. Different from traditional architecture where you have a fixed number of long-running Node.js servers, in a serverless environment, a new Node.js context can potentially be created for each user request, and if traffic volume is high, this can quickly exhaust your database's connection limit, if you connect to the database directly without a proxy. You'll likely be OK if your app has a low number of concurrent users, otherwise you should consider using a proxy in front of your database server. Here's a number of (incomplete) solutions you can consider: -- [Prisma Data Proxy](https://www.prisma.io/data-platform/proxy) -- [Supabase](https://supabase.com/)'s [connection pool](https://supabase.com/docs/guides/database/connecting-to-postgres#connection-pool) -- [Deploy pgbouncer with Postgres on Heroku](https://devcenter.heroku.com/articles/postgres-connection-pooling) +- [Prisma Data Proxy](https://www.prisma.io/data-platform/proxy ':target=blank') +- [Supabase](https://supabase.com/)'s [connection pool](https://supabase.com/docs/guides/database/connecting-to-postgres#connection-pool ':target=blank') +- [Deploy pgbouncer with Postgres on Heroku](https://devcenter.heroku.com/articles/postgres-connection-pooling ':target=blank') diff --git a/doc-serve/public/cli-commands.md b/doc-serve/public/cli-commands.md new file mode 100644 index 000000000..92be36169 --- /dev/null +++ b/doc-serve/public/cli-commands.md @@ -0,0 +1,131 @@ +# CLI commands + +## `init` + +Set up ZenStack for an existing Next.js + Typescript project. + +```bash +npx zenstack init [options] [dir] +``` + +_Options_: + +``` + -p, --package-manager : package manager to use: "npm", "yarn", or "pnpm" (default: auto detect) +``` + +## `generate` + +Generates RESTful CRUD API and React hooks from your model. + +```bash +npx zenstack generate [options] +``` + +_Options_: + +``` + --schema : schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel") + + -p, --package-manager : package manager to use: "npm", "yarn", or "pnpm" (default: auto detect) +``` + +## `migrate` + +Update the database schema with migrations. + +**Sub-commands**: + +### `migrate dev` + +Create a migration from changes in Prisma schema, apply it to the database, trigger generation of database client. This command wraps `prisma migrate` command. + +```bash +npx zenstack migrate dev [options] +``` + +_Options_: + +``` + --schema schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel") +``` + +### `migrate reset` + +Reset your database and apply all migrations. + +```bash +npx zenstack migrate reset [options] +``` + +_Options_: + +``` + --schema schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel") +``` + +### `migrate deploy` + +Apply pending migrations to the database in production/staging. + +```bash +npx zenstack migrate deploy [options] +``` + +_Options_: + +``` + --schema schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel") +``` + +### `migrate status` + +Check the status of migrations in the production/staging database. + +```bash +npx zenstack migrate status [options] +``` + +_Options_: + +``` + --schema schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel") +``` + +## `db` + +Manage your database schema and lifecycle during development. This command wraps `prisma db` command. + +**Sub-commands**: + +### `db push` + +Push the state from model to the database during prototyping. + +```bash +npx zenstack db push [options] +``` + +_Options_: + +``` + --schema schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel") + --accept-data-loss Ignore data loss warnings +``` + +## `studio` + +Browse your data with Prisma Studio. This command wraps `prisma studio` command. + +```bash +npx zenstack studio [options] +``` + +_Options_: + +``` + --schema schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel") + -p --port Port to start Studio in + -b --browser Browser to open Studio in + -n --hostname Hostname to bind the Express server to +``` diff --git a/doc-serve/public/code-generation.md b/doc-serve/public/code-generation.md new file mode 100644 index 000000000..8db1cbe53 --- /dev/null +++ b/doc-serve/public/code-generation.md @@ -0,0 +1,15 @@ +# Code generation + +Code generation is where your modeling work pays off. To trigger it, simply run: + +```bash +npx zenstack generate +``` + +You should see an output similar to: + +![CLI screenshot](_media/cli-shot.png 'CLI screenshot') + +A full reference of the `zenstack` CLI can be found [here](cli-references.md), but for now knowing just this one command is good enough. + +As you see, several code generators are run to create pieces of code that help you build the app. Let's see how to use it in the [next section](building-your-app.md). diff --git a/doc-serve/public/entity-types-server.md b/doc-serve/public/entity-types-server.md new file mode 100644 index 000000000..189df5691 --- /dev/null +++ b/doc-serve/public/entity-types-server.md @@ -0,0 +1,84 @@ +# Types + +Module `@zenstackhq/runtime/types` contains type definitions of entities, filters, sorting, etc., generated from ZModel data models. The types can be used in both the front-end and the backend code. + +Suppose a `User` model is defined in ZModel: + +```zmodel +model User { + id String @id @default(cuid()) + email String @unique @email + password String @password @omit + name String? + posts Post[] +} +``` + +The following types are generated: + +## Entity type + +````ts +export type User = { + id: string + email: string + password: string | null + name: string | null + posts: Post[] +}``` + +This type serves as the return type of the generated React hooks: + +```ts +import { type User } from '@zenstackhq/runtime/types'; +import { useUser } from '@zenstackhq/runtime/client'; + +export function MyComponent() { + const { find } = useUser(); + const result = find(); + const users: User[] = result.data; + ... +} +```` + +Backend database access API also returns the same type: + +```ts +const users: User[] = await service.db.user.find(); +``` + +## Filter and sort type + +Types for filtering and sorting entites are also generated: + +```ts +export type UserFindManyArgs = { + select?: UserSelect | null; + include?: UserInclude | null; + where?: UserWhereInput; + orderBy?: Enumerable; + ... +}; +``` + +You can use it like: + +```ts +const { find } = useUser(); +const { data: users } = find({ + where: { + email: { + endsWith: '@zenstack.dev', + }, + }, + orderBy: [ + { + email: 'asc', + }, + ], + include: { + // include related Post entities + posts: true, + }, +}); +``` diff --git a/doc-serve/public/entity-types.md b/doc-serve/public/entity-types.md new file mode 100644 index 000000000..189df5691 --- /dev/null +++ b/doc-serve/public/entity-types.md @@ -0,0 +1,84 @@ +# Types + +Module `@zenstackhq/runtime/types` contains type definitions of entities, filters, sorting, etc., generated from ZModel data models. The types can be used in both the front-end and the backend code. + +Suppose a `User` model is defined in ZModel: + +```zmodel +model User { + id String @id @default(cuid()) + email String @unique @email + password String @password @omit + name String? + posts Post[] +} +``` + +The following types are generated: + +## Entity type + +````ts +export type User = { + id: string + email: string + password: string | null + name: string | null + posts: Post[] +}``` + +This type serves as the return type of the generated React hooks: + +```ts +import { type User } from '@zenstackhq/runtime/types'; +import { useUser } from '@zenstackhq/runtime/client'; + +export function MyComponent() { + const { find } = useUser(); + const result = find(); + const users: User[] = result.data; + ... +} +```` + +Backend database access API also returns the same type: + +```ts +const users: User[] = await service.db.user.find(); +``` + +## Filter and sort type + +Types for filtering and sorting entites are also generated: + +```ts +export type UserFindManyArgs = { + select?: UserSelect | null; + include?: UserInclude | null; + where?: UserWhereInput; + orderBy?: Enumerable; + ... +}; +``` + +You can use it like: + +```ts +const { find } = useUser(); +const { data: users } = find({ + where: { + email: { + endsWith: '@zenstack.dev', + }, + }, + orderBy: [ + { + email: 'asc', + }, + ], + include: { + // include related Post entities + posts: true, + }, +}); +``` diff --git a/docs/ref/evolving-data-model-with-migration.md b/doc-serve/public/evolving-model-with-migration.md similarity index 84% rename from docs/ref/evolving-data-model-with-migration.md rename to doc-serve/public/evolving-model-with-migration.md index 140648c5e..e4354324b 100644 --- a/docs/ref/evolving-data-model-with-migration.md +++ b/doc-serve/public/evolving-model-with-migration.md @@ -1,4 +1,4 @@ -# Evolving Data Model with Migration +# Evolving model with migration When using ZenStack, your schema.zmodel file represents the current status of your app's data model and your database's schema. When you make changes to schema.zmodel, however, your data model drifts away from database schema. At your app's deployment time, such drift needs to be "fixed", and so that your database schema stays synchronized with your data model. This processing of "fixing" is called migration. @@ -40,7 +40,9 @@ npx zenstack db push ```bash npx zenstack migrate reset +``` +```bash npx zenstack migrate dev -n [name] ``` @@ -58,6 +60,6 @@ If you've always been taking the "migrate dev" and "migrate deploy" loop during ## Summary -ZenStack is built over [Prisma](https://www.prisma.io) and it internally delegates all ORM tasks to Prisma. The migration workflow is exactly the same as Prisma's workflow, with the only exception that the source of input is schema.zmodel, and a Prisma schema is generated on the fly. The set of migration commands that ZModel CLI offers, like "migrate dev" and "migrate deploy", are simple wrappers around Prisma commands. +ZenStack is built over [Prisma](https://www.prisma.io ':target=blank') and it internally delegates all ORM tasks to Prisma. The migration workflow is exactly the same as Prisma's workflow, with the only exception that the source of input is schema.zmodel, and a Prisma schema is generated on the fly. The set of migration commands that ZModel CLI offers, like "migrate dev" and "migrate deploy", are simple wrappers around Prisma commands. -Prisma has [excellent documentation](https://www.prisma.io/docs/concepts/components/prisma-migrate) about migration. Make sure you look into those for a more thorough understanding. +Prisma has [excellent documentation](https://www.prisma.io/docs/concepts/components/prisma-migrate ':target=blank') about migration. Make sure you look into those for a more thorough understanding. diff --git a/doc-serve/public/index.html b/doc-serve/public/index.html new file mode 100644 index 000000000..65b47cac0 --- /dev/null +++ b/doc-serve/public/index.html @@ -0,0 +1,99 @@ + + + + + + ZenStack - toolkit for building CRUD apps with Next.js + Typescript + + + + + + + + + + + + + + + + + + + + + + + + + + +
Please wait...
+ + + + + + + + + + + + + diff --git a/doc-serve/public/integrating-authentication.md b/doc-serve/public/integrating-authentication.md new file mode 100644 index 000000000..bff6a3154 --- /dev/null +++ b/doc-serve/public/integrating-authentication.md @@ -0,0 +1,228 @@ +# Integrating authentication + +This documentation explains how to integrate ZenStack with popular authentication frameworks. + +## NextAuth + +[NextAuth](https://next-auth.js.org/) is a comprehensive framework for implementating authentication. It offers a pluggable mechanism for configuring how user data is persisted. You can find a full example using ZenStack with NextAuth [here](https://github.com/zenstackhq/zenstack/tree/main/samples/todo ':target=blank'). + +ZenStack provides an extension package `@zenstackhq/next-auth` for integrating with NextAuth, which includes: + +### Adapter + +Adapter is a NextAuth mechanism for hooking in custom persistence of auth related entities, like User, Account, etc. The ZenStack adapter can be configured to NextAuth as follows: + +```ts +// pages/api/auth/[...nextauth].ts + +import service from '@zenstackhq/runtime/server'; +import { Adapter } from '@zenstackhq/next-auth'; +import NextAuth, { type NextAuthOptions } from 'next-auth'; + +export const authOptions: NextAuthOptions = { + // install ZenStack adapter + adapter: Adapter(service), + ... +}; + +export default NextAuth(authOptions); +``` + +### `authorize` helper + +If you use [`CredentialsProvider`](https://next-auth.js.org/providers/credentials ':target=blank'), i.e. email/password based auth, you can also use the `authorize` helper to implement how credentials are verified against the database: + +```ts +// pages/api/auth/[...nextauth].ts + +import service from '@zenstackhq/runtime/server'; +import { authorize } from '@zenstackhq/next-auth'; +import NextAuth, { type NextAuthOptions } from 'next-auth'; + +export const authOptions: NextAuthOptions = { + ... + providers: [ + CredentialsProvider({ + credentials: { + email: { + label: 'Email Address', + type: 'email', + }, + password: { + label: 'Password', + type: 'password', + }, + }, + + // use ZenStack's default implementation to verify credentials + authorize: authorize(service), + }), + ]}; + +export default NextAuth(authOptions); +``` + +### Configuring ZenStack services + +ZenStack's CRUD services need to be configured with a `getServerUser` callback for fetching current login user from the backend. This can be easily done when using Next-Auth's `unstable_getServerSession` API: + +```ts +// pages/api/zenstack/[...path].ts + +... +import service, { + type RequestHandlerOptions, + requestHandler, +} from '@zenstackhq/runtime/server'; +import { authOptions } from '../auth/[...nextauth]'; +import { unstable_getServerSession } from 'next-auth'; + +const options: RequestHandlerOptions = { + async getServerUser(req: NextApiRequest, res: NextApiResponse) { + const session = await unstable_getServerSession(req, res, authOptions); + return session?.user; + }, +}; +export default requestHandler(service, options); + +``` + +_NOTE_ Although the name `unstable_getServerSession` looks suspicious, it's officially recommended by Next-Auth and is production-ready. + +### Data model requirement + +NextAuth is agnostic about the type of underlying database, but it requires certain table structures, depending on how you configure it. Your ZModel definitions should reflect these requirements. A sample `User` model is shown here (to be used with `CredentialsProvider`): + +```zmodel +model User { + id String @id @default(cuid()) + email String @unique @email + emailVerified DateTime? + password String @password @omit + name String? + image String? @url + + // open to signup + @@allow('create', true) + + // full access by oneself + @@allow('all', auth() == this) +} +``` + +You can find the detailed database model requirements [here](https://next-auth.js.org/adapters/models ':target=blank'). + +## Iron-session + +[Iron-session](https://www.npmjs.com/package/iron-session ':target=blank') is a lightweighted authentication toolkit. + +### Authentication endpoints + +Iron-session requires you to implement auth related API endpoints by yourself. Usually you need to at least have these three endpoints: **api/auth/login**, **/api/auth/logout**, and **/api/auth/user**. The following code shows how to use ZenStack backend service to implement them. + +- **/api/auth/login** + +```ts +... +import service from '@zenstackhq/runtime/server'; +import * as bcrypt from 'bcryptjs'; + +const loginRoute: NextApiHandler = async (req, res) => { + const { email, password } = req.body; + + const user = await service.db.user.findUnique({ where: { email } }); + if (!user || !bcrypt.compareSync(password, user.password)) { + res.status(401).json({ + message: 'invalid email and password combination', + }); + return; + } + + delete (user as any).password; + req.session.user = user; + await req.session.save(); + + res.json(user); +}; + +export default withIronSessionApiRoute(loginRoute, sessionOptions); +``` + +- **/api/auth/logout** + +```ts +... + +const logoutRoute: NextApiHandler = async (req, res) => { + req.session.destroy(); + res.json({}); +}; + +export default withIronSessionApiRoute(logoutRoute, sessionOptions); + +``` + +- **/api/auth/user** + +```ts +... +import service from '@zenstackhq/runtime/server'; + +const userRoute: NextApiHandler = async (req, res) => { + if (req.session?.user) { + // fetch user from db for fresh data + const user = await service.db.user.findUnique({ + where: { email: req.session.user.email }, + }); + if (!user) { + res.status(401).json({ message: 'invalid login status' }); + return; + } + + delete (user as any).password; + res.json(user); + } else { + res.status(401).json({ message: 'invalid login status' }); + } +}; + +export default withIronSessionApiRoute(userRoute, sessionOptions); +``` + +### Configuring ZenStack services + +ZenStack's CRUD services need to be configured with a `getServerUser` callback for fetching current login user from the backend. This can be easily done when using iron-session: + +```ts +// pages/api/zenstack/[...path].ts + +... +import service, { + requestHandler, + type RequestHandlerOptions, +} from '@zenstackhq/runtime/server'; + +const options: RequestHandlerOptions = { + async getServerUser(req: NextApiRequest, res: NextApiResponse) { + const user = req.session?.user; + if (!user) { + return undefined; + } + + const dbUser = await service.db.user.findUnique({ + where: { email: user.email }, + }); + + return dbUser ?? undefined; + }, +}; + +export default withIronSessionApiRoute( + requestHandler(service, options), + sessionOptions +); +``` + +## Custom-built authentication + +[TBD] diff --git a/doc-serve/public/modeling-your-app.md b/doc-serve/public/modeling-your-app.md new file mode 100644 index 000000000..5cb860652 --- /dev/null +++ b/doc-serve/public/modeling-your-app.md @@ -0,0 +1,168 @@ +# Modeling your app + +ZenStack provides an integrated DSL called **ZModel** for defining your data models, relations, and access policies. It may sounds scary to learn yet another new language, but trust me is simple and intuitive. + +**ZModel** DSL is extended from the schema language of [Prisma ORM](https://www.prisma.io/docs/concepts/components/prisma-schema ':target=_blank'). Familarity of Prisma will make it very easy to start, but it's not a prerequisite. + +## Configuring data source + +The very first thing to do is to configure how to connect to your database. + +Here's an example for using a PosgreSQL with is connection string read from `DATABASE_URL` environment variable: + +```zmodel +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +The generated CRUD services use the data source settings to connect to the database. Also, the migration workflow relies on it to synchronize database schema with the model. + +## Adding data models + +Data models define the shapes of business entities in your app. A data model consists of fields and attributes (which attach extra behavior to fields). + +Here's an example of a blog post model: + +```zmodel +model Post { + // @id attribute marks a field as unique identifier, + // mapped to database table's primary key + id String @id @default(cuid()) + + // fields can be DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // or string + title String + + // or integer + viewCount Int @default(0) + + // and optional + content String? + + // and a list too + tags String[] +} +``` + +Check [here](zmodel-field.md) for more details about defining fields. + +## Adding relations + +An app is usually made up of a bunch of interconnected data models. You can define their relations with the special `@relation` attibute. + +Here are some examples: + +- One-to-one + +```zmodel +model User { + id String @id + profile Profile? +} + +model Profile { + id String @id + user @relation(fields: [userId], references: [id]) + userId String @unique +} +``` + +- One-to-many + +```zmodel +model User { + id String @id + posts Post[] +} + +model Post { + id String @id + author User? @relation(fields: [authorId], references: [id]) + authorId String? +} +``` + +- Many-to-many + +```zmodel +model Space { + id String @id + members Membership[] +} + +// Membership is the "join-model" between User and Space +model Membership { + id String @id() + + // one-to-many from Space + space Space @relation(fields: [spaceId], references: [id]) + spaceId String + + // one-to-many from User + user User @relation(fields: [userId], references: [id]) + userId String + + // a user can be member of a space for only once + @@unique([userId, spaceId]) +} + +model User { + id String @id + membership Membership[] +} +``` + +Check [here](zmodel-relation.md) for more details about defining relations. + +## Adding access policies + +It's great to see our app's business model is in place now, but it's still missing an important aspect: **access policy**, i.e., who can take what action to which data. + +Access policies are defined using `@@allow` and `@@deny` attributes. _NOTE_ attributes with `@@` prefix are to be used at model level. + +A few quick notes before diving into examples: + +- Access kinds include `create`, `read`, `update` and `delete`, and you can use `all` to abbreviate full grant. + +- By default, all access kinds are denied for a model. You can use arbitrary number of `@@allow` and `@@deny` rules in a model. See [here](zmodel-access-policy.md#combining-multiple-rules) for the semantic of combining them. + +- You can access current login user with the builtin `auth()` function. See [here](integrating-authentication.md) for how authentication is integrated. + +Let's look at a few examples now: + +```zmodel +model User { + id String @id + posts Post[] + ... + + // User can be created unconditionally (sign-up) + @@allow("create", true) +} + +model Post { + id String @id + author User @relation(fields: [authorId], references: [id]) + authorId String + published Boolean @default(false) + ... + + // deny all unauthenticated write access + @@deny("create,update,delete", auth() == null) + + // published posts can be read by all + @@allow("read", published) + + // grant full access to author + @@allow("all", auth() == author) +} +``` + +You can find more details about access policy [here](zmodel-access-policy.md). Also, check out the [Collaborative Todo App](https://github.com/zenstackhq/todo-demo-sqlite) sample for a more sophisticated policy design. + +Now you've got a fairly complete model for the app. Let's go ahead with [generating code](code-generation.md) from it then. diff --git a/doc-serve/public/quick-start.md b/doc-serve/public/quick-start.md new file mode 100644 index 000000000..3e71dc6fc --- /dev/null +++ b/doc-serve/public/quick-start.md @@ -0,0 +1,134 @@ +# Quick start + +Please check out the corresponding guide for [creating a new project](#creating-a-new-project) or [adding to an existing project](#adding-to-an-existing-project). + +## Creating a new project + +You can choose from these preconfigured starter to create a new project: + +- [Using Next-Auth for authentication](#with-next-auth) +- [Using iron-session for authentication](#with-iron-session) +- [Without integrating with authentication](#without-integrating-authentication) + +### With Next-Auth + +Follow these steps to create a new project from a preconfigured template using [Next-Auth](https://next-auth.js.org/ ':target=blank') for authentication: + +1. Clone from starter template + +```bash +npx create-next-app --use-npm -e https://github.com/zenstackhq/nextjs-auth-starter +``` + +2. Install dependencies + +```bash +npm install +``` + +3. Generate CRUD services and hooks code from the starter model + +```bash +npm run generate +``` + +4. push database schema to the local sqlite db + +```bash +npm run db:push +``` + +5. start dev server + +``` +npm run dev +``` + +### With iron-session + +Follow these steps to create a new project from a preconfigured template using [iron-session](https://www.npmjs.com/package/iron-session ':target=blank') for authentication: + +1. Clone from starter template + +```bash +npx create-next-app --use-npm -e https://github.com/zenstackhq/nextjs-iron-session-starter +``` + +2. Install dependencies + +```bash +npm install +``` + +3. Generate CRUD services and hooks code from the starter model + +```bash +npm run generate +``` + +4. push database schema to the local sqlite db + +```bash +npm run db:push +``` + +5. start dev server + +``` +npm run dev +``` + +### Without integrating authentication + +If you would rather not use a template preconfigured with authentication, you can use the barebone starter instead. You can add an authentication solution later or hand-code it by yourself. + +1. Clone from starter template + +```bash +npx create-next-app --use-npm -e https://github.com/zenstackhq/nextjs-barebone-starter +``` + +2. Install dependencies + +```bash +npm install +``` + +3. Generate CRUD services and hooks code from the starter model + +```bash +npm run generate +``` + +4. push database schema to the local sqlite db + +```bash +npm run db:push +``` + +5. start dev server + +``` +npm run dev +``` + +### Check result + +If everything worked, you should see a simple blog app like this: +![starter screen shot](_media/starter-shot.png 'Starter project screenshot') + +No worries if a blogger app doesn't suit you. The created project contains a starter model at `/zenstack/schema.zmodel`. You can modify it and build up your application's own model following [this guide](modeling-your-app.md). + +## Adding to an existing project + +To add ZenStack to an existing Next.js + Typescript project, run command below: + +```bash +npx zenstack init +``` + +You should find a `/zenstack/schema.model` file created, containing a simple blogger model in it. No worries if a blogger app doesn't suit you. You can modify it and build up your application's own model following [this guide](modeling-your-app.md). + +## Installing VSCode extension + +It's good idea to install the [VSCode extension](https://marketplace.visualstudio.com/items?itemName=zenstack.zenstack ':target=_blank') so you get syntax highlighting and error checking when authoring model files. diff --git a/doc-serve/public/reach-out.md b/doc-serve/public/reach-out.md new file mode 100644 index 000000000..e57290e72 --- /dev/null +++ b/doc-serve/public/reach-out.md @@ -0,0 +1,9 @@ +# Reach out to the developers + +As developers of ZenStack, we hope this toolkit can assist you to build a cool app. +Should you have any questions or ideas, please feel free to reach out to us by any of the following methods. We'll be happy to help you out. + +- [Discord](https://go.zenstack.dev/chat) +- [GitHub Discussions](https://github.com/zenstackhq/zenstack/discussions) +- [Twitter](https://twitter.com/zenstackhq) +- Email us: [contact@zenstack.dev](mailto:contact@zenstack.dev) diff --git a/doc-serve/public/robots.txt b/doc-serve/public/robots.txt new file mode 100644 index 000000000..c2a49f4fb --- /dev/null +++ b/doc-serve/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Allow: / diff --git a/doc-serve/public/runtime-api.md b/doc-serve/public/runtime-api.md new file mode 100644 index 000000000..07d7b4833 --- /dev/null +++ b/doc-serve/public/runtime-api.md @@ -0,0 +1,231 @@ +# Runtime API + +## `@zenstackhq/runtime/types` + +This module contains types generated from ZModel data models. These types are shared by both the client-side and the server-side code. + +The generated types include (for each data model defined): + +- Entity type +- Data structure for creating/updating entities +- Data structure for selecting entities - including filtering and sorting + +Take `User` model as an example, here're some of the most commonly used types: + +- `User` + + The entity type which directly corresponds to the data mdoel. + +- `UserFindUniqueArgs` + + Argument type for finding a unique `User`. + +- `UserFindManyArgs` + + Argument type for finding a list of `User`s. + +- `UserCreateArgs` + + Argument for creating a new `User`. + +- `UserUpdateArgs` + + Argument for updating an existing `User`. + +## `@zenstackhq/runtime/client` + +This module contains API for client-side programming, including the generated React hooks and auxiliary types, like options and error types. + +_NOTE_ You should not import this module into server-side code, like getServerSideProps, or API endpoint. + +A `useXXX` API is generated fo each data model for getting the React hooks. The following code uses `User` model as an example. + +```ts +const { get, find, create, update, del } = useUser(); +``` + +### `RequestOptions` + +Options controlling hooks' fetch behavior. + +```ts +type RequestOptions = { + // indicates if fetch should be disabled + disabled?: boolean; + + // provides initial data, which is immediately available + // before fresh data is fetched (usually used with SSR) + initialData?: T; +}; +``` + +### `HooksError` + +Error thrown for failure of `create`, `update` and `delete` hooks. + +```ts +export type HooksError = { + status: number; + info: { + code: ServerErrorCode; + message: string; + }; +}; +``` + +#### `ServerErrorCode` + +| Code | Description | +| ------------------------------ | --------------------------------------------------------------------------------------------- | +| ENTITY_NOT_FOUND | The specified entity cannot be found | +| INVALID_REQUEST_PARAMS | The request parameter is invalid, either containing invalid fields or missing required fields | +| DENIED_BY_POLICY | The request is rejected by policy checks | +| UNIQUE_CONSTRAINT_VIOLATION | Violation of database unique constraints | +| REFERENCE_CONSTRAINT_VIOLATION | Violation of database reference constraint (aka. foreign key constraints) | +| READ_BACK_AFTER_WRITE_DENIED | A write operation succeeded but the result cannot be read back due to policy control | + +### `get` + +```ts +function get( + id: string | undefined, + args?: UserFindFirstArgs, + options?: RequestOptions +): SWRResponse; +``` + +### `find` + +```ts +function find( + args?: UserFindManyArgs, + options?: RequestOptions +): SWRResponse; +``` + +### `create` + +```ts +function create(args?: UserCreateArgs): Promise; +``` + +### `update` + +```ts +function update(id: string, args?: UserUpdateArgs): Promise; +``` + +### `del` + +```ts +function del(id: string, args?: UserDeleteArgs): Promise; +``` + +## `@zenstackhq/runtime/server` + +This module contains API for server-side programming. The following declarations are exported: + +### `service` + +The default export of this module is a `service` object which encapsulates most of the server-side APIs. + +#### Server-side CRUD + +The `service` object contains members for each of the data models, each containing server-side CRUD APIs. These APIs can be used for doing CRUD operations without HTTP request overhead, while still fully protected by access policies. + +The server-side CRUD APIs have similar signature with client-side hooks, except that they take an extra `queryContext` parameter for passing in the current login user. They're usually used for implementing SSR or custom API endpoints. + +- get + + ```ts + async get( + context: QueryContext, + id: string, + args?: UserFindFirstArgs + ): Promise; + ``` + +- find + + ```ts + async find( + context: QueryContext, + args?: UserFindManyArgs + ): Promise; + ``` + +- create + + ```ts + async create( + context: QueryContext, + args?: UserCreateArgs + ): Promise; + ``` + +- update + + ```ts + async update( + context: QueryContext, + id: string, + args?: UserUpdateArgs + ): Promise; + ``` + +- del + ```ts + async del( + context: QueryContext, + id: string, + args?: UserDeleteArgs + ): Promise; + ``` + +#### Direct database access + +The `service.db` object contains a member field for each data model defined, which you can use to conduct database operations for that model. + +_NOTE_ These database operations are **NOT** protected by access policies. + +Take `User` model for example: + +```ts +import service from '@zenstackhq/runtime/server'; + +// find all users +const users = service.db.user.find(); + +// update a user +await service.db.user.update({ + where: { id: userId }, + data: { email: newEmail }, +}); +``` + +The server-side database access API uses the [same set of typing](#zenstackhqruntimetypes) as the client side. The `service.db` object is a Prisma Client, and you can find all API documentations [here](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference ':target=blank'). + +### `requestHandler` + +Function for handling API endpoint requests. Used for installing the generated CRUD services onto an API route: + +```ts +// pages/api/zenstack/[...path].ts + +import service from '@zenstackhq/runtime'; +import { + requestHandler, + type RequestHandlerOptions, +} from '@zenstackhq/runtime/server'; +import { NextApiRequest, NextApiResponse } from 'next'; + +const options: RequestHandlerOptions = { + // a callback for getting the current login user + async getServerUser(req: NextApiRequest, res: NextApiResponse) { + ... + }, +}; +export default requestHandler(service, options); +``` + +The `getServerUser` callback method is used for getting the current login user on the server side. Its implementation depends on how you authenticate users. diff --git a/doc-serve/public/server-side-rendering.md b/doc-serve/public/server-side-rendering.md new file mode 100644 index 000000000..e2ce76829 --- /dev/null +++ b/doc-serve/public/server-side-rendering.md @@ -0,0 +1,26 @@ +# Server-side rendering + +You can use the `service` object to conduct CRUD operations on the server side directly without the overhead of HTTP requests. The `service` object contains members for each of the data model defined. + +The server-side CRUD methods are similar signature with client-side hooks, except that they take an extra `queryContext` parameter for passing in the current login user. Like client-side hooks, the CRUD operations are fully protected by access policies defined in ZModel. + +These methods are handy for implementing SSR (or custom API endpoints). Here's an example (using Next-Auth for authentication): + +```ts +import service from '@zenstackhq/runtime/server'; +import { unstable_getServerSession } from 'next-auth'; +... + +export const getServerSideProps = async ({ + req, + res, + params, +}) => { + const session = await unstable_getServerSession(req, res, authOptions); + const queryContext = { user: session?.user }; + const posts = await service.post.find(queryContext); + return { + props: { posts }, + }; +}; +``` diff --git a/docs/ref/setup-logging.md b/doc-serve/public/setup-logging.md similarity index 95% rename from docs/ref/setup-logging.md rename to doc-serve/public/setup-logging.md index ee8c0cfdd..b3c2b4099 100644 --- a/docs/ref/setup-logging.md +++ b/doc-serve/public/setup-logging.md @@ -1,24 +1,24 @@ -# Setting Up Logging +# Set up logging ZenStack uses the following levels to control server-side logging: -- error +- `error` Error level logging -- warn +- `warn` Warning level logging -- info +- `info` Info level logging -- verbose +- `verbose` Verbose level logging -- query +- `query` Detailed database query logging diff --git a/doc-serve/public/sitemap.xml b/doc-serve/public/sitemap.xml new file mode 100644 index 000000000..c15f0c84a --- /dev/null +++ b/doc-serve/public/sitemap.xml @@ -0,0 +1 @@ +https://zenstack.dev/dailyhttps://zenstack.dev/changelogdailyhttps://zenstack.dev/building-your-appdailyhttps://zenstack.dev/choosing-a-databasedailyhttps://zenstack.dev/cli-commandsdailyhttps://zenstack.dev/code-generationdailyhttps://zenstack.dev/entity-types-serverdailyhttps://zenstack.dev/entity-typesdailyhttps://zenstack.dev/evolving-model-with-migrationdailyhttps://zenstack.dev/integrating-authenticationdailyhttps://zenstack.dev/modeling-your-appdailyhttps://zenstack.dev/quick-startdailyhttps://zenstack.dev/reach-outdailyhttps://zenstack.dev/runtime-apidailyhttps://zenstack.dev/server-side-renderingdailyhttps://zenstack.dev/setup-loggingdailyhttps://zenstack.dev/telemetrydailyhttps://zenstack.dev/vscode-extensiondailyhttps://zenstack.dev/zmodel-access-policydailyhttps://zenstack.dev/zmodel-attributedailyhttps://zenstack.dev/zmodel-data-modeldailyhttps://zenstack.dev/zmodel-data-sourcedailyhttps://zenstack.dev/zmodel-enumdailyhttps://zenstack.dev/zmodel-field-constraintdailyhttps://zenstack.dev/zmodel-fielddailyhttps://zenstack.dev/zmodel-overviewdailyhttps://zenstack.dev/zmodel-referential-actiondailyhttps://zenstack.dev/zmodel-relationdaily \ No newline at end of file diff --git a/doc-serve/public/static/building-your-app.html b/doc-serve/public/static/building-your-app.html new file mode 100644 index 000000000..9a1acd551 --- /dev/null +++ b/doc-serve/public/static/building-your-app.html @@ -0,0 +1,231 @@ + + + Building your app + + + + + + + + + + + + + + + + + + + + + + + + + +

Building your app

The code generated from your model covers everything you need to implement CRUD, frontend and backend. This section illustrates the steps of using them when building your app.

Mounting backend services

First you should mount the generated server-side code as a Next.js API endpoint. Here's an example:

// pages/api/zenstack/[...path].ts
+
+import { authOptions } from '@api/auth/[...nextauth]';
+import service from '@zenstackhq/runtime';
+import {
+    requestHandler,
+    type RequestHandlerOptions,
+} from '@zenstackhq/runtime/server';
+import { NextApiRequest, NextApiResponse } from 'next';
+import { unstable_getServerSession } from 'next-auth';
+
+const options: RequestHandlerOptions = {
+    // a callback for getting the current login user
+    async getServerUser(req: NextApiRequest, res: NextApiResponse) {
+        // here we use NextAuth is used as an example, and you can change it to
+        // suit the authentication solution you use
+        const session = await unstable_getServerSession(req, res, authOptions);
+        return session?.user;
+    },
+};
+export default requestHandler(service, options);

Please note that the services need to be configured with a callback getServerUser for getting the current login user. The example above uses NextAuth to do it, but you can also hand-code it based on the authentication approach you use, as long as it returns a user object that represents the current session's user.

NOTE Check out this guide for more details about integrating with authentication.

Make sure the services are mounted at route /api/zenstack/ with a catch all parameter named path, as this is required by the generate React hooks.

optional Integrating with NextAuth

If you use NextAuth for authentication, you can install the @zenstackhq/next-auth package for easier integration. This package provides an adapter and authorization helper that you can use to configure NextAuth.

// pages/api/auth/[...nextauth].ts
+
+import service from '@zenstackhq/runtime';
+import { authorize, Adapter } from '@zenstackhq/next-auth';
+import NextAuth, { type NextAuthOptions } from 'next-auth';
+
+export const authOptions: NextAuthOptions = {
+    // use ZenStack adapter for persistence
+    adapter: Adapter(service),
+
+    providers: [
+        CredentialsProvider({
+            credentials: { ... },
+            // use the generated "authorize" helper for credential based authentication
+            authorize: authorize(service),
+        }),
+    ]
+
+    ...
+};
+
+export default NextAuth(authOptions);

Find more details here about integrating with different authentication schemes.

Using React hooks

React hooks are generated for CRUD'ing each data model you defined. They save your time writing explicit HTTP requests to call the generated services. Internally the hooks use SWR for data fetching, so you'll also enjoy its built-in features, like caching, revalidation on interval, etc.

NOTE The generated service code is injected with the access policies you defined in the model, so it's already secure, regardless called directly or via hooks. A read operation only returns data that's supposed to be visible to the current user, and a write operation is rejected if the policies verdict so.

Read

Call find and get hooks for listing entities or loading a specific one. If your entity has relations, you can request related entities to be loaded together.

const { find } = usePost();
+// lists unpublished posts with their author's data
+const posts = find({
+    where: { published: false },
+    include: { author: true },
+    orderBy: { updatedAt: 'desc' },
+});
const { get } = usePost();
+// fetches a post with its author's data
+const post = get(id, {
+    include: { author: true },
+});

Create

Call the async create method to create a new model entity. Note that if the model has relations, you can create related entities in a nested write. See example below:

const { create } = usePost();
+// creating a new post for current user with a nested comment
+const post = await create({
+    data: {
+        title: 'My New Post',
+        author: {
+            connect: { id: session.user.id },
+        },
+        comments: {
+            create: [{ content: 'First comment' }],
+        },
+    },
+});

Update

Similar to create, the update hook also allows nested write.

const { update } = usePost();
+// updating a post's content and create a new comment
+const post = await update(id, {
+    data: {
+        const: 'My post content',
+        comments: {
+            create: [{ content: 'A new comment' }],
+        },
+    },
+});

Delete

const { del } = usePost();
+const post = await del(id);

Server-side coding

Since doing CRUD with hooks is already secure, in many cases, you can implement your business logic right in the frontend code.

ZenStack also supports server-side programming for conducting CRUD without sending HTTP requests, or even direct database access (bypassing access policy checks). Please check the following documentation for details:

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/changelog.html b/doc-serve/public/static/changelog.html new file mode 100644 index 000000000..86e659943 --- /dev/null +++ b/doc-serve/public/static/changelog.html @@ -0,0 +1,158 @@ + + + Changelog + + + + + + + + + + + + + + + + + + + + + + + + + +

0.4.0 (2022-12-01)

Features

  • zenstack init command for initializing a project, #109, doc.

  • Field constraint suport, #94, doc.

  • Support for server-side CRUD with access policy check (SSR), #126, doc.

  • Options for disabling fetching in hooks (useful when arguments are not ready), #57, doc.

  • Telemetry in CLI, #102, doc.

  • Iron-session based starter, #95, link.

  • Barebone starter (without authentication), link.

  • Website is live!

Fixes and improvements

  • Merge @zenstackhq/internal into @zenstackhq/runtime so as to have a single runtime dependency, #70.

  • More accurate log for access policy violation, #71.

  • auth() function's return type is now resolved to User model in ZModel, instead of Any, #65.

  • Improved ZModel type checking, #67, #46, #99.

  • Upgraded to Prisma 4.7.

Breaking changes

  • @zenstackhq/runtime doesn't export anything now.

    Use @zenstackhq/runtime/types for type definitions shared between client and server, @zenstackhq/runtime/client for client-specific libaries (like React hooks), and @zenstackhq/runtime/server for server-specific libraries.

0.3.0 (2022-11-08)

Features

  • @password and @omit attribute support

  • Configurable logging (to stdout and emitting as events)

Fixes and improvements

  • More robust policy checks

  • Properly handles complex types like BigInt, Date, Decimal, etc.

  • Makes sure Prisma schema is regenerated for related CLI commands

  • Lower VSCode engine version requirement for the extension

  • Better overall documentation

0.2.0 (2022-10-29)

Features

  • ZModel data modeling schema (an extension to Prisma Schema)

  • zenstack cli for generating RESTful services, auth adapters and React hooks from ZModel

  • Policy engine that transforms policy rules into Prisma query conditions

  • Runtime packages

  • An initial set of tests

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/choosing-a-database.html b/doc-serve/public/static/choosing-a-database.html new file mode 100644 index 000000000..a0010cf5d --- /dev/null +++ b/doc-serve/public/static/choosing-a-database.html @@ -0,0 +1,158 @@ + + + Choosing a database + + + + + + + + + + + + + + + + + + + + + + + + + +

Choosing a database

ZenStack is agnostic about where and how you deploy your web app, but hosting on serverless platforms like Vercel is definitely a popular choice.

Serverless architecture has some implications on how you should care about your database hosting. Different from traditional architecture where you have a fixed number of long-running Node.js servers, in a serverless environment, a new Node.js context can potentially be created for each user request, and if traffic volume is high, this can quickly exhaust your database's connection limit, if you connect to the database directly without a proxy.

You'll likely be OK if your app has a low number of concurrent users, otherwise you should consider using a proxy in front of your database server. Here's a number of (incomplete) solutions you can consider:

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/cli-commands.html b/doc-serve/public/static/cli-commands.html new file mode 100644 index 000000000..512bd925d --- /dev/null +++ b/doc-serve/public/static/cli-commands.html @@ -0,0 +1,164 @@ + + + Commands + + + + + + + + + + + + + + + + + + + + + + + + + +

CLI commands

init

Set up ZenStack for an existing Next.js + Typescript project.

npx zenstack init [options] [dir]

Options:

    -p, --package-manager <pm>: package manager to use: "npm", "yarn", or "pnpm" (default: auto detect)

generate

Generates RESTful CRUD API and React hooks from your model.

npx zenstack generate [options]

Options:

    --schema <file>: schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel")
+
+    -p, --package-manager <pm>: package manager to use: "npm", "yarn", or "pnpm" (default: auto detect)

migrate

Update the database schema with migrations.

Sub-commands:

migrate dev

Create a migration from changes in Prisma schema, apply it to the database, trigger generation of database client. This command wraps prisma migrate command.

npx zenstack migrate dev [options]

Options:

    --schema <file> schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel")

migrate reset

Reset your database and apply all migrations.

npx zenstack migrate reset [options]

Options:

    --schema <file> schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel")

migrate deploy

Apply pending migrations to the database in production/staging.

npx zenstack migrate deploy [options]

Options:

    --schema <file> schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel")

migrate status

Check the status of migrations in the production/staging database.

npx zenstack migrate status [options]

Options:

    --schema <file> schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel")

db

Manage your database schema and lifecycle during development. This command wraps prisma db command.

Sub-commands:

db push

Push the state from model to the database during prototyping.

npx zenstack db push [options]

Options:

    --schema <file> schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel")
+    --accept-data-loss  Ignore data loss warnings

studio

Browse your data with Prisma Studio. This command wraps prisma studio command.

npx zenstack studio [options]

Options:

    --schema <file>         schema file (with extension .zmodel) (default: "./zenstack/schema.zmodel")
+    -p --port <port>        Port to start Studio in
+    -b --browser <browser>  Browser to open Studio in
+    -n --hostname           Hostname to bind the Express server to
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/code-generation.html b/doc-serve/public/static/code-generation.html new file mode 100644 index 000000000..779616d17 --- /dev/null +++ b/doc-serve/public/static/code-generation.html @@ -0,0 +1,158 @@ + + + Code generation + + + + + + + + + + + + + + + + + + + + + + + + + +

Code generation

Code generation is where your modeling work pays off. To trigger it, simply run:

npx zenstack generate

You should see an output similar to:

CLI screenshot

A full reference of the zenstack CLI can be found here, but for now knowing just this one command is good enough.

As you see, several code generators are run to create pieces of code that help you build the app. Let's see how to use it in the next section.

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/entity-types-server.html b/doc-serve/public/static/entity-types-server.html new file mode 100644 index 000000000..957f4b3a7 --- /dev/null +++ b/doc-serve/public/static/entity-types-server.html @@ -0,0 +1,205 @@ + + + ZenStack - toolkit for building CRUD apps with Next.js + Typescript + + + + + + + + + + + + + + + + + + + + + + + + + +

Types

Module @zenstackhq/runtime/types contains type definitions of entities, filters, sorting, etc., generated from ZModel data models. The types can be used in both the front-end and the backend code.

Suppose a User model is defined in ZModel:

model User {
+    id String @id @default(cuid())
+    email String @unique @email
+    password String @password @omit
+    name String?
+    posts Post[]
+}

The following types are generated:

Entity type

export type User = {
+  id: string
+  email: string
+  password: string | null
+  name: string | null
+  posts: Post[]
+}```
+
+This type serves as the return type of the generated React hooks:
+
+```ts
+import { type User } from '@zenstackhq/runtime/types';
+import { useUser } from '@zenstackhq/runtime/client';
+
+export function MyComponent() {
+    const { find } = useUser();
+    const result = find();
+    const users: User[] = result.data;
+    ...
+}

Backend database access API also returns the same type:

const users: User[] = await service.db.user.find();

Filter and sort type

Types for filtering and sorting entites are also generated:

export type UserFindManyArgs = {
+    select?: UserSelect | null;
+    include?: UserInclude | null;
+    where?: UserWhereInput;
+    orderBy?: Enumerable<UserOrderByWithRelationInput>;
+    ...
+};

You can use it like:

const { find } = useUser();
+const { data: users } = find({
+    where: {
+        email: {
+            endsWith: '@zenstack.dev',
+        },
+    },
+    orderBy: [
+        {
+            email: 'asc',
+        },
+    ],
+    include: {
+        // include related Post entities
+        posts: true,
+    },
+});
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/entity-types.html b/doc-serve/public/static/entity-types.html new file mode 100644 index 000000000..4deb7b333 --- /dev/null +++ b/doc-serve/public/static/entity-types.html @@ -0,0 +1,205 @@ + + + ZenStack - toolkit for building CRUD apps with Next.js + Typescript + + + + + + + + + + + + + + + + + + + + + + + + + +

Types

Module @zenstackhq/runtime/types contains type definitions of entities, filters, sorting, etc., generated from ZModel data models. The types can be used in both the front-end and the backend code.

Suppose a User model is defined in ZModel:

model User {
+    id String @id @default(cuid())
+    email String @unique @email
+    password String @password @omit
+    name String?
+    posts Post[]
+}

The following types are generated:

Entity type

export type User = {
+  id: string
+  email: string
+  password: string | null
+  name: string | null
+  posts: Post[]
+}```
+
+This type serves as the return type of the generated React hooks:
+
+```ts
+import { type User } from '@zenstackhq/runtime/types';
+import { useUser } from '@zenstackhq/runtime/client';
+
+export function MyComponent() {
+    const { find } = useUser();
+    const result = find();
+    const users: User[] = result.data;
+    ...
+}

Backend database access API also returns the same type:

const users: User[] = await service.db.user.find();

Filter and sort type

Types for filtering and sorting entites are also generated:

export type UserFindManyArgs = {
+    select?: UserSelect | null;
+    include?: UserInclude | null;
+    where?: UserWhereInput;
+    orderBy?: Enumerable<UserOrderByWithRelationInput>;
+    ...
+};

You can use it like:

const { find } = useUser();
+const { data: users } = find({
+    where: {
+        email: {
+            endsWith: '@zenstack.dev',
+        },
+    },
+    orderBy: [
+        {
+            email: 'asc',
+        },
+    ],
+    include: {
+        // include related Post entities
+        posts: true,
+    },
+});
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/evolving-model-with-migration.html b/doc-serve/public/static/evolving-model-with-migration.html new file mode 100644 index 000000000..6fbc8ae63 --- /dev/null +++ b/doc-serve/public/static/evolving-model-with-migration.html @@ -0,0 +1,158 @@ + + + Evolving model with migration + + + + + + + + + + + + + + + + + + + + + + + + + +

Evolving model with migration

When using ZenStack, your schema.zmodel file represents the current status of your app's data model and your database's schema. When you make changes to schema.zmodel, however, your data model drifts away from database schema. At your app's deployment time, such drift needs to be "fixed", and so that your database schema stays synchronized with your data model. This processing of "fixing" is called migration.

Here we summarize a few common scenarios and show how you should work on migration.

For a newly created schema.zmodel

When you're just starting out a ZenStack project, you have an empty migration history. After creating schema.zmodel, adding a development datasource and adding some models, run the following command to bootstrap your migration history and synchronize your development database schema:

npx zenstack migrate dev -n init

After it's run, you should find a folder named migrations created under zenstack folder, inside of which you can find a .sql file containing script that initializes your database. Please note that when you run "migration dev", the generated migration script is automatically run agains your datasource specified in schema.zmodel.

Make sure you commit the migrations folder into source control.

After updating an existing schema.zmodel

After making update to schema.zmodel, run the "migrate dev" command to generate an incremental migration record:

npx zenstack migrate dev -n [short-name-for-the-change]

If any database schema change is needed based on the previous version of data model, a new .sql file will be generated under zenstack/migrations folder. Your development database's schema is automatically synchronized after running the command.

Make sure you review that the generated .sql script reflects your intention before committing it to source control.

Pushing model changes to database without creating migration

This is helpful when you're prototyping locally and don't want to create migration records. Simply run:

npx zenstack db push

, and your database schema will be synced with schema.zmodel. After prototyping, reset your local database and generate migration records:

npx zenstack migrate reset
npx zenstack migrate dev -n [name]

During deployment

When deploying your app to an official environment (a shared dev environment, staging, or production), DO NOT run migrate dev command in CI scripts. Instead, run migrate deploy.

npx zenstack migrate deploy

The migrate deploy command does not generate new migration records. It simply detects records that are created after the previous deployment and execute them in order. As a result, your database schema is synchronized with data model.

If you've always been taking the "migrate dev" and "migrate deploy" loop during development, your migration should run smoothly. However manually changing db schema, manually changing/deleting migration records can result in failure during migration. Please refer to this documentation for troubleshooting migration issues in production.

Summary

ZenStack is built over Prisma and it internally delegates all ORM tasks to Prisma. The migration workflow is exactly the same as Prisma's workflow, with the only exception that the source of input is schema.zmodel, and a Prisma schema is generated on the fly. The set of migration commands that ZModel CLI offers, like "migrate dev" and "migrate deploy", are simple wrappers around Prisma commands.

Prisma has excellent documentation about migration. Make sure you look into those for a more thorough understanding.

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/index.html b/doc-serve/public/static/index.html new file mode 100644 index 000000000..271af7497 --- /dev/null +++ b/doc-serve/public/static/index.html @@ -0,0 +1,163 @@ + + + ZenStack - toolkit for building CRUD apps with Next.js + Typescript + + + + + + + + + + + + + + + + + + + + + + + + + +

cover-logo

ZenStack 0.4.0

+

A toolkit for building secure CRUD apps with Next.js + Typescript.

+
  • Full-stack toolkit made for front-end developers
  • Intuitive and flexible data modeling
  • No more boilerplate CRUD code

GitHub +Get Started

ZenStack

+

A toolkit for building secure CRUD apps with Next.js.

+

What it is

ZenStack is a schema-first toolkit for defining data models, relations and access policies. It generates database schema, backend CRUD services and frontend React hooks for you automatically from the model. Our goal is to let you save time writing boilerplate code and focus on building real features!

NOTE: ZenStack is built above Prisma ORM - the greatest ORM solution for Typescript. It extends Prisma's power from database handling to full-stack development.

See the Quick start guide for more details.

Features

Examples

Check out the Collaborative Todo App for a running example. You can find the source code here.

Community

Join our discord server for chat and updates!

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/integrating-authentication.html b/doc-serve/public/static/integrating-authentication.html new file mode 100644 index 000000000..799bc300b --- /dev/null +++ b/doc-serve/public/static/integrating-authentication.html @@ -0,0 +1,303 @@ + + + Integrating authentication + + + + + + + + + + + + + + + + + + + + + + + + + +

Integrating authentication

This documentation explains how to integrate ZenStack with popular authentication frameworks.

NextAuth

NextAuth is a comprehensive framework for implementating authentication. It offers a pluggable mechanism for configuring how user data is persisted. You can find a full example using ZenStack with NextAuth here.

ZenStack provides an extension package @zenstackhq/next-auth for integrating with NextAuth, which includes:

Adapter

Adapter is a NextAuth mechanism for hooking in custom persistence of auth related entities, like User, Account, etc. The ZenStack adapter can be configured to NextAuth as follows:

// pages/api/auth/[...nextauth].ts
+
+import service from '@zenstackhq/runtime/server';
+import { Adapter } from '@zenstackhq/next-auth';
+import NextAuth, { type NextAuthOptions } from 'next-auth';
+
+export const authOptions: NextAuthOptions = {
+    // install ZenStack adapter
+    adapter: Adapter(service),
+    ...
+};
+
+export default NextAuth(authOptions);

authorize helper

If you use CredentialsProvider, i.e. email/password based auth, you can also use the authorize helper to implement how credentials are verified against the database:

// pages/api/auth/[...nextauth].ts
+
+import service from '@zenstackhq/runtime/server';
+import { authorize } from '@zenstackhq/next-auth';
+import NextAuth, { type NextAuthOptions } from 'next-auth';
+
+export const authOptions: NextAuthOptions = {
+    ...
+    providers: [
+        CredentialsProvider({
+            credentials: {
+                email: {
+                    label: 'Email Address',
+                    type: 'email',
+                },
+                password: {
+                    label: 'Password',
+                    type: 'password',
+                },
+            },
+
+            // use ZenStack's default implementation to verify credentials
+            authorize: authorize(service),
+        }),
+    ]};
+
+export default NextAuth(authOptions);

Configuring ZenStack services

ZenStack's CRUD services need to be configured with a getServerUser callback for fetching current login user from the backend. This can be easily done when using Next-Auth's unstable_getServerSession API:

// pages/api/zenstack/[...path].ts
+
+...
+import service, {
+    type RequestHandlerOptions,
+    requestHandler,
+} from '@zenstackhq/runtime/server';
+import { authOptions } from '../auth/[...nextauth]';
+import { unstable_getServerSession } from 'next-auth';
+
+const options: RequestHandlerOptions = {
+    async getServerUser(req: NextApiRequest, res: NextApiResponse) {
+        const session = await unstable_getServerSession(req, res, authOptions);
+        return session?.user;
+    },
+};
+export default requestHandler(service, options);
+

NOTE Although the name unstable_getServerSession looks suspicious, it's officially recommended by Next-Auth and is production-ready.

Data model requirement

NextAuth is agnostic about the type of underlying database, but it requires certain table structures, depending on how you configure it. Your ZModel definitions should reflect these requirements. A sample User model is shown here (to be used with CredentialsProvider):

model User {
+    id String @id @default(cuid())
+    email String @unique @email
+    emailVerified DateTime?
+    password String @password @omit
+    name String?
+    image String? @url
+
+    // open to signup
+    @@allow('create', true)
+
+    // full access by oneself
+    @@allow('all', auth() == this)
+}

You can find the detailed database model requirements here.

Iron-session

Iron-session is a lightweighted authentication toolkit.

Authentication endpoints

Iron-session requires you to implement auth related API endpoints by yourself. Usually you need to at least have these three endpoints: api/auth/login, /api/auth/logout, and /api/auth/user. The following code shows how to use ZenStack backend service to implement them.

  • /api/auth/login
...
+import service from '@zenstackhq/runtime/server';
+import * as bcrypt from 'bcryptjs';
+
+const loginRoute: NextApiHandler = async (req, res) => {
+    const { email, password } = req.body;
+
+    const user = await service.db.user.findUnique({ where: { email } });
+    if (!user || !bcrypt.compareSync(password, user.password)) {
+        res.status(401).json({
+            message: 'invalid email and password combination',
+        });
+        return;
+    }
+
+    delete (user as any).password;
+    req.session.user = user;
+    await req.session.save();
+
+    res.json(user);
+};
+
+export default withIronSessionApiRoute(loginRoute, sessionOptions);
  • /api/auth/logout
...
+
+const logoutRoute: NextApiHandler = async (req, res) => {
+    req.session.destroy();
+    res.json({});
+};
+
+export default withIronSessionApiRoute(logoutRoute, sessionOptions);
+
  • /api/auth/user
...
+import service from '@zenstackhq/runtime/server';
+
+const userRoute: NextApiHandler<AuthResponseType> = async (req, res) => {
+    if (req.session?.user) {
+        // fetch user from db for fresh data
+        const user = await service.db.user.findUnique({
+            where: { email: req.session.user.email },
+        });
+        if (!user) {
+            res.status(401).json({ message: 'invalid login status' });
+            return;
+        }
+
+        delete (user as any).password;
+        res.json(user);
+    } else {
+        res.status(401).json({ message: 'invalid login status' });
+    }
+};
+
+export default withIronSessionApiRoute(userRoute, sessionOptions);

Configuring ZenStack services

ZenStack's CRUD services need to be configured with a getServerUser callback for fetching current login user from the backend. This can be easily done when using iron-session:

// pages/api/zenstack/[...path].ts
+
+...
+import service, {
+    requestHandler,
+    type RequestHandlerOptions,
+} from '@zenstackhq/runtime/server';
+
+const options: RequestHandlerOptions = {
+    async getServerUser(req: NextApiRequest, res: NextApiResponse) {
+        const user = req.session?.user;
+        if (!user) {
+            return undefined;
+        }
+
+        const dbUser = await service.db.user.findUnique({
+            where: { email: user.email },
+        });
+
+        return dbUser ?? undefined;
+    },
+};
+
+export default withIronSessionApiRoute(
+    requestHandler(service, options),
+    sessionOptions
+);

Custom-built authentication

[TBD]

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/modeling-your-app.html b/doc-serve/public/static/modeling-your-app.html new file mode 100644 index 000000000..41b82b237 --- /dev/null +++ b/doc-serve/public/static/modeling-your-app.html @@ -0,0 +1,247 @@ + + + Modeling your app + + + + + + + + + + + + + + + + + + + + + + + + + +

Modeling your app

ZenStack provides an integrated DSL called ZModel for defining your data models, relations, and access policies. It may sounds scary to learn yet another new language, but trust me is simple and intuitive.

ZModel DSL is extended from the schema language of Prisma ORM. Familarity of Prisma will make it very easy to start, but it's not a prerequisite.

Configuring data source

The very first thing to do is to configure how to connect to your database.

Here's an example for using a PosgreSQL with is connection string read from DATABASE_URL environment variable:

datasource db {
+    provider = "postgresql"
+    url = env("DATABASE_URL")
+}

The generated CRUD services use the data source settings to connect to the database. Also, the migration workflow relies on it to synchronize database schema with the model.

Adding data models

Data models define the shapes of business entities in your app. A data model consists of fields and attributes (which attach extra behavior to fields).

Here's an example of a blog post model:

model Post {
+    // @id attribute marks a field as unique identifier,
+    // mapped to database table's primary key
+    id String @id @default(cuid())
+
+    // fields can be DateTime
+    createdAt DateTime @default(now())
+    updatedAt DateTime @updatedAt
+
+    // or string
+    title String
+
+    // or integer
+    viewCount Int @default(0)
+
+    // and optional
+    content String?
+
+    // and a list too
+    tags String[]
+}

Check here for more details about defining fields.

Adding relations

An app is usually made up of a bunch of interconnected data models. You can define their relations with the special @relation attibute.

Here are some examples:

  • One-to-one
model User {
+    id String @id
+    profile Profile?
+}
+
+model Profile {
+    id String @id
+    user @relation(fields: [userId], references: [id])
+    userId String @unique
+}
  • One-to-many
model User {
+    id String @id
+    posts Post[]
+}
+
+model Post {
+    id String @id
+    author User? @relation(fields: [authorId], references: [id])
+    authorId String?
+}
  • Many-to-many
model Space {
+    id String @id
+    members Membership[]
+}
+
+// Membership is the "join-model" between User and Space
+model Membership {
+    id String @id()
+
+    // one-to-many from Space
+    space Space @relation(fields: [spaceId], references: [id])
+    spaceId String
+
+    // one-to-many from User
+    user User @relation(fields: [userId], references: [id])
+    userId String
+
+    // a user can be member of a space for only once
+    @@unique([userId, spaceId])
+}
+
+model User {
+    id String @id
+    membership Membership[]
+}

Check here for more details about defining relations.

Adding access policies

It's great to see our app's business model is in place now, but it's still missing an important aspect: access policy, i.e., who can take what action to which data.

Access policies are defined using @@allow and @@deny attributes. NOTE attributes with @@ prefix are to be used at model level.

A few quick notes before diving into examples:

  • Access kinds include create, read, update and delete, and you can use all to abbreviate full grant.

  • By default, all access kinds are denied for a model. You can use arbitrary number of @@allow and @@deny rules in a model. See here for the semantic of combining them.

  • You can access current login user with the builtin auth() function. See here for how authentication is integrated.

Let's look at a few examples now:

model User {
+    id String @id
+    posts Post[]
+    ...
+
+    // User can be created unconditionally (sign-up)
+    @@allow("create", true)
+}
+
+model Post {
+    id String @id
+    author User @relation(fields: [authorId], references: [id])
+    authorId String
+    published Boolean @default(false)
+    ...
+
+    // deny all unauthenticated write access
+    @@deny("create,update,delete", auth() == null)
+
+    // published posts can be read by all
+    @@allow("read", published)
+
+    // grant full access to author
+    @@allow("all", auth() == author)
+}

You can find more details about access policy here. Also, check out the Collaborative Todo App sample for a more sophisticated policy design.

Now you've got a fairly complete model for the app. Let's go ahead with generating code from it then.

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/quick-start.html b/doc-serve/public/static/quick-start.html new file mode 100644 index 000000000..3a323afaf --- /dev/null +++ b/doc-serve/public/static/quick-start.html @@ -0,0 +1,159 @@ + + + Quick start + + + + + + + + + + + + + + + + + + + + + + + + + +

Quick start

Please check out the corresponding guide for creating a new project or adding to an existing project.

Creating a new project

You can choose from these preconfigured starter to create a new project:

With Next-Auth

Follow these steps to create a new project from a preconfigured template using Next-Auth for authentication:

  1. Clone from starter template
npx create-next-app --use-npm -e https://github.com/zenstackhq/nextjs-auth-starter
  1. Install dependencies
npm install
  1. Generate CRUD services and hooks code from the starter model
npm run generate
  1. push database schema to the local sqlite db
npm run db:push
  1. start dev server
npm run dev

With iron-session

Follow these steps to create a new project from a preconfigured template using iron-session for authentication:

  1. Clone from starter template
npx create-next-app --use-npm -e https://github.com/zenstackhq/nextjs-iron-session-starter
  1. Install dependencies
npm install
  1. Generate CRUD services and hooks code from the starter model
npm run generate
  1. push database schema to the local sqlite db
npm run db:push
  1. start dev server
npm run dev

Without integrating authentication

If you would rather not use a template preconfigured with authentication, you can use the barebone starter instead. You can add an authentication solution later or hand-code it by yourself.

  1. Clone from starter template
npx create-next-app --use-npm -e https://github.com/zenstackhq/nextjs-barebone-starter
  1. Install dependencies
npm install
  1. Generate CRUD services and hooks code from the starter model
npm run generate
  1. push database schema to the local sqlite db
npm run db:push
  1. start dev server
npm run dev

Check result

If everything worked, you should see a simple blog app like this: +starter screen shot

No worries if a blogger app doesn't suit you. The created project contains a starter model at /zenstack/schema.zmodel. You can modify it and build up your application's own model following this guide.

Adding to an existing project

To add ZenStack to an existing Next.js + Typescript project, run command below:

npx zenstack init

You should find a /zenstack/schema.model file created, containing a simple blogger model in it. No worries if a blogger app doesn't suit you. You can modify it and build up your application's own model following this guide.

Installing VSCode extension

It's good idea to install the VSCode extension so you get syntax highlighting and error checking when authoring model files.

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/reach-out.html b/doc-serve/public/static/reach-out.html new file mode 100644 index 000000000..eaac22d83 --- /dev/null +++ b/doc-serve/public/static/reach-out.html @@ -0,0 +1,159 @@ + + + Reach out to the developers + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/runtime-api.html b/doc-serve/public/static/runtime-api.html new file mode 100644 index 000000000..7482fcca3 --- /dev/null +++ b/doc-serve/public/static/runtime-api.html @@ -0,0 +1,252 @@ + + + Runtime API + + + + + + + + + + + + + + + + + + + + + + + + + +

Runtime API

@zenstackhq/runtime/types

This module contains types generated from ZModel data models. These types are shared by both the client-side and the server-side code.

The generated types include (for each data model defined):

  • Entity type
  • Data structure for creating/updating entities
  • Data structure for selecting entities - including filtering and sorting

Take User model as an example, here're some of the most commonly used types:

  • User

    The entity type which directly corresponds to the data mdoel.

  • UserFindUniqueArgs

    Argument type for finding a unique User.

  • UserFindManyArgs

    Argument type for finding a list of Users.

  • UserCreateArgs

    Argument for creating a new User.

  • UserUpdateArgs

    Argument for updating an existing User.

@zenstackhq/runtime/client

This module contains API for client-side programming, including the generated React hooks and auxiliary types, like options and error types.

NOTE You should not import this module into server-side code, like getServerSideProps, or API endpoint.

A useXXX API is generated fo each data model for getting the React hooks. The following code uses User model as an example.

const { get, find, create, update, del } = useUser();

RequestOptions

Options controlling hooks' fetch behavior.

type RequestOptions<T> = {
+    // indicates if fetch should be disabled
+    disabled?: boolean;
+
+    // provides initial data, which is immediately available
+    // before fresh data is fetched (usually used with SSR)
+    initialData?: T;
+};

HooksError

Error thrown for failure of create, update and delete hooks.

export type HooksError = {
+    status: number;
+    info: {
+        code: ServerErrorCode;
+        message: string;
+    };
+};

ServerErrorCode

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CodeDescription
ENTITY_NOT_FOUNDThe specified entity cannot be found
INVALID_REQUEST_PARAMSThe request parameter is invalid, either containing invalid fields or missing required fields
DENIED_BY_POLICYThe request is rejected by policy checks
UNIQUE_CONSTRAINT_VIOLATIONViolation of database unique constraints
REFERENCE_CONSTRAINT_VIOLATIONViolation of database reference constraint (aka. foreign key constraints)
READ_BACK_AFTER_WRITE_DENIEDA write operation succeeded but the result cannot be read back due to policy control
+

get

function get(
+    id: string | undefined,
+    args?: UserFindFirstArgs,
+    options?: RequestOptions
+): SWRResponse<User>;

find

function find(
+    args?: UserFindManyArgs,
+    options?: RequestOptions
+): SWRResponse<User[]>;

create

function create(args?: UserCreateArgs): Promise<User | undefined>;

update

function update(id: string, args?: UserUpdateArgs): Promise<User | undefined>;

del

function del(id: string, args?: UserDeleteArgs): Promise<User | undefined>;

@zenstackhq/runtime/server

This module contains API for server-side programming. The following declarations are exported:

service

The default export of this module is a service object which encapsulates most of the server-side APIs.

Server-side CRUD

The service object contains members for each of the data models, each containing server-side CRUD APIs. These APIs can be used for doing CRUD operations without HTTP request overhead, while still fully protected by access policies.

The server-side CRUD APIs have similar signature with client-side hooks, except that they take an extra queryContext parameter for passing in the current login user. They're usually used for implementing SSR or custom API endpoints.

  • get

    async get(
    +    context: QueryContext,
    +    id: string,
    +    args?: UserFindFirstArgs
    +): Promise<User | undefined>;
  • find

    async find(
    +    context: QueryContext,
    +    args?: UserFindManyArgs
    +): Promise<User[]>;
  • create

    async create(
    +    context: QueryContext,
    +    args?: UserCreateArgs
    +): Promise<User>;
  • update

    async update(
    +    context: QueryContext,
    +    id: string,
    +    args?: UserUpdateArgs
    +): Promise<User>;
  • del

    async del(
    +    context: QueryContext,
    +    id: string,
    +    args?: UserDeleteArgs
    +): Promise<User>;

Direct database access

The service.db object contains a member field for each data model defined, which you can use to conduct database operations for that model.

NOTE These database operations are NOT protected by access policies.

Take User model for example:

import service from '@zenstackhq/runtime/server';
+
+// find all users
+const users = service.db.user.find();
+
+// update a user
+await service.db.user.update({
+    where: { id: userId },
+    data: { email: newEmail },
+});

The server-side database access API uses the same set of typing as the client side. The service.db object is a Prisma Client, and you can find all API documentations here.

requestHandler

Function for handling API endpoint requests. Used for installing the generated CRUD services onto an API route:

// pages/api/zenstack/[...path].ts
+
+import service from '@zenstackhq/runtime';
+import {
+    requestHandler,
+    type RequestHandlerOptions,
+} from '@zenstackhq/runtime/server';
+import { NextApiRequest, NextApiResponse } from 'next';
+
+const options: RequestHandlerOptions = {
+    // a callback for getting the current login user
+    async getServerUser(req: NextApiRequest, res: NextApiResponse) {
+        ...
+    },
+};
+export default requestHandler(service, options);

The getServerUser callback method is used for getting the current login user on the server side. Its implementation depends on how you authenticate users.

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/server-side-rendering.html b/doc-serve/public/static/server-side-rendering.html new file mode 100644 index 000000000..122299332 --- /dev/null +++ b/doc-serve/public/static/server-side-rendering.html @@ -0,0 +1,173 @@ + + + Server-side rendering + + + + + + + + + + + + + + + + + + + + + + + + + +

Server-side rendering

You can use the service object to conduct CRUD operations on the server side directly without the overhead of HTTP requests. The service object contains members for each of the data model defined.

The server-side CRUD methods are similar signature with client-side hooks, except that they take an extra queryContext parameter for passing in the current login user. Like client-side hooks, the CRUD operations are fully protected by access policies defined in ZModel.

These methods are handy for implementing SSR (or custom API endpoints). Here's an example (using Next-Auth for authentication):

import service from '@zenstackhq/runtime/server';
+import { unstable_getServerSession } from 'next-auth';
+...
+
+export const getServerSideProps = async ({
+    req,
+    res,
+    params,
+}) => {
+    const session = await unstable_getServerSession(req, res, authOptions);
+    const queryContext = { user: session?.user };
+    const posts = await service.post.find(queryContext);
+    return {
+        props: { posts },
+    };
+};
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/setup-logging.html b/doc-serve/public/static/setup-logging.html new file mode 100644 index 000000000..2a993404f --- /dev/null +++ b/doc-serve/public/static/setup-logging.html @@ -0,0 +1,193 @@ + + + Set up logging + + + + + + + + + + + + + + + + + + + + + + + + + +

Set up logging

ZenStack uses the following levels to control server-side logging:

  • error

    Error level logging

  • warn

    Warning level logging

  • info

    Info level logging

  • verbose

    Verbose level logging

  • query

    Detailed database query logging

By default, ZenStack prints error and warn level of logging with console.error and console.log, respectively. You can also control the logging behavior by providing a zenstack.config.json file at the root of your project.

You can turn log levels on and off in zenstack.config.json:

{
+    "log": ["verbose", "info"]
+}

The settings shown above is an shorthand for:

{
+    "log": [
+        {
+            "level": "verbose",
+            "emit": "stdout"
+        },
+        {
+            "level": "info",
+            "emit": "stdout"
+        }
+    ]
+}

You can also configure ZenStack to emit log as event instead of dumping to stdout, like:

{
+    "log": [
+        {
+            "level": "info",
+            "emit": "event"
+        }
+    ]
+}

To consume the events:

import service from '@zenstackhq/runtime';
+
+service.$on('info', (event) => {
+    console.log(event.timestamp, event.message);
+});

You can also mix and match stdout output with event emitting, like:

{
+    "log": [
+        {
+            "level": "info",
+            "emit": "stdout"
+        },
+        {
+            "level": "info",
+            "emit": "event"
+        }
+    ]
+}

The settings in zenstack.config.json controls logging of both ZenStack and the underlying Prisma instance.

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/telemetry.html b/doc-serve/public/static/telemetry.html new file mode 100644 index 000000000..b0613b01d --- /dev/null +++ b/doc-serve/public/static/telemetry.html @@ -0,0 +1,158 @@ + + + Telemetry + + + + + + + + + + + + + + + + + + + + + + + + + +

Telemetry

ZenStack CLI and VSCode extension sends anonymous telemetry for analyzing usage stats and finding bugs.

The information collected includes:

  • OS
  • Node.js version
  • CLI version
  • CLI command and arguments
  • CLI errors
  • Duration of command run
  • Region (based on IP)

We don't collect any telemetry at the runtime of apps using ZenStack.

We appreciate that you keep the telemetry ON so we can keep improving the toolkit. We follow the Console Do Not Track convention, and you can turn off the telemetry by setting environment variable DO_NOT_TRACK to 1:

DO_NOT_TRACK=1 npx zenstack ...
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/vscode-extension.html b/doc-serve/public/static/vscode-extension.html new file mode 100644 index 000000000..41c0614a9 --- /dev/null +++ b/doc-serve/public/static/vscode-extension.html @@ -0,0 +1,158 @@ + + + VSCode extension + + + + + + + + + + + + + + + + + + + + + + + + + +

VSCode extension

ZenStack VSCode extension provides syntax highlighting and error checking to improve the efficiency of your modeling work.

You can install by searching "ZenStack Language Tools" inside of VSCode, or from here directly.

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/zmodel-access-policy.html b/doc-serve/public/static/zmodel-access-policy.html new file mode 100644 index 000000000..67aef1471 --- /dev/null +++ b/doc-serve/public/static/zmodel-access-policy.html @@ -0,0 +1,264 @@ + + + Access policy + + + + + + + + + + + + + + + + + + + + + + + + + +

Access policy

Access policies use @@allow and @@deny rules to specify the eligibility of an operation over a model entity. The signatures of the attributes are:

  • @@allow

        attribute @@allow(_ operation: String, _ condition: Boolean)

    Params:

    + + + + + + + + + + + + + + +
    NameDescription
    operationComma separated list of operations to control, including "create", "read", "update", and "delete". Pass "all" as an abbriviation for including all operations.
    conditionBoolean expression indicating if the operations should be allowed
    +
  • @@deny

        attribute @@deny(_ operation: String, _ condition: Boolean)

    Params:

    + + + + + + + + + + + + + + +
    NameDescription
    operationComma separated list of operations to control, including "create", "read", "update", and "delete". Pass "all" as an abbriviation for including all operations.
    conditionBoolean expression indicating if the operations should be denied
    +

Using authentication in policy rules

It's very common to use the current login user to verdict if an operation should be permitted. Therefore, ZenStack provides a built-in auth() attribute function that evaluates to the User entity corresponding to the current user. To use the function, your ZModel file must define a User data model.

You can use auth() to:

  • Check if a user is logged in

    @@deny('all', auth() == null)
  • Access user's fields

    @@allow('update', auth().role == 'ADMIN')
  • Compare user identity

    // owner is a relation field to User model
    +@@allow('update', auth() == owner)

Accessing relation fields in policy

As you've seen in the examples above, you can access fields from relations in policy expressions. For example, to express "a user can be read by any user sharing a space" in the User model, you can directly read into its membership field.

    @@allow('read', membership?[space.members?[user == auth()]])

In most cases, when you use a "to-many" relation in a policy rule, you'll use "Collection Predicate" to express a condition. See next section for details.

Collection predicate expressions

Collection predicate expressions are boolean expressions used to express conditions over a list. It's mainly designed for building policy rules for "to-many" relations. It has three forms of syntaxes:

  • Any

    <collection>?[condition]

    Any element in collection matches condition

  • All

    <collection>![condition]

    All elements in collection match condition

  • None

    <collection>^[condition]

    None element in collection matches condition

The condition expression has direct access to fields defined in the model of collection. E.g.:

    @@allow('read', members?[user == auth()])

, in condition user == auth(), user refers to the user field in model Membership, because the collection members is resolved to Membership model.

Also, collection predicates can be nested to express complex conditions involving multi-level relation lookup. E.g.:

    @@allow('read', membership?[space.members?[user == auth()]])

In this example, user refers to user field of Membership model because space.members is resolved to Membership model.

Combining multiple rules

A data model can contain arbitrary number of policy rules. The logic of combining them is as follows:

  • The operation is rejected if any of the conditions in @@deny rules evaluate to true
  • Otherwise, the operation is permitted if any of the conditions in @@allow rules evaluate to true
  • Otherwise, the operation is rejected

Example

A simple example with Post model

model Post {
+    // reject all operations if user's not logged in
+    @@deny('all', auth() == null)
+
+    // allow all operations if the entity's owner matches the current user
+    @@allow('all', auth() == owner)
+
+    // posts are readable to anyone
+    @allow('read', true)
+}

A more complex example with multi-user spaces

model Space {
+    id String @id
+    members Membership[]
+    owner User @relation(fields: [ownerId], references: [id])
+    ownerId String
+
+    // require login
+    @@deny('all', auth() == null)
+
+    // everyone can create a space
+    @@allow('create', true)
+
+    // owner can do everything
+    @@allow('all', auth() == owner)
+
+    // any user in the space can read the space
+    //
+    // Here the <collection>?[condition] syntax is called
+    // "Collection Predicate", used to check if any element
+    // in the "collection" matches the "condition"
+    @@allow('read', members?[user == auth()])
+}
+
+// Membership is the "join-model" between User and Space
+model Membership {
+    id String @id()
+
+    // one-to-many from Space
+    space Space @relation(fields: [spaceId], references: [id])
+    spaceId String
+
+    // one-to-many from User
+    user User @relation(fields: [userId], references: [id])
+    userId String
+
+    // a user can be member of a space for only once
+    @@unique([userId, spaceId])
+
+    // require login
+    @@deny('all', auth() == null)
+
+    // space owner can create/update/delete
+    @@allow('create,update,delete', space.owner == auth())
+
+    // user can read entries for spaces which he's a member of
+    @@allow('read', space.members?[user == auth()])
+}
+
+model User {
+    id String @id
+    email String @unique
+    membership Membership[]
+    ownedSpaces Space[]
+
+    // allow signup
+    @@allow('create', true)
+
+    // user can do everything to herself; note that "this" represents
+    // the current entity
+    @@allow('all', auth() == this)
+
+    // can be read by users sharing a space
+    @@allow('read', membership?[space.members?[user == auth()]])
+}
+
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/zmodel-attribute.html b/doc-serve/public/static/zmodel-attribute.html new file mode 100644 index 000000000..913359335 --- /dev/null +++ b/doc-serve/public/static/zmodel-attribute.html @@ -0,0 +1,391 @@ + + + Attribute + + + + + + + + + + + + + + + + + + + + + + + + + +

Attribute

Attributes decorate fields and data models and attach extra behaviors or constraints to them.

Syntax

Field attribute

Field attribute name is prefixed by a single @. Its application takes the following form:

id String @[ATTR_NAME](ARGS)?
  • [ATTR_NAME]

Attribute name. See below for a full list of attributes.

  • [ARGS]

See attribute arguments.

Data model attribute

Field attribute name is prefixed double @@. Its application takes the following form:

model Model {
+    @@[ATTR_NAME](ARGS)?
+}
  • [ATTR_NAME]

Attribute name. See below for a full list of attributes.

  • [ARGS]

See attribute arguments.

Arguments

Attribute can be declared with a list of parameters, and applied with an optional comma-separated list of arguments.

Arguments are mapped to parameters by position or by name. For example, for the @default attribute declared as:

attribute @default(_ value: ContextType)

, the following two ways of applying it are equivalent:

published Boolean @default(value: false)
published Boolean @default(false)

Parameter types

Attribute parameters are typed. The following types are supported:

  • Int

    Integer literal can be passed as argument.

    E.g., declaration:

    attribute @password(saltLength: Int?, salt: String?)
    +

    application:

    password String @password(saltLength: 10)
  • String

    String literal can be passed as argument.

    E.g., declaration:

    attribute @id(map: String?)

    application:

    id String @id(map: "_id")
  • Boolean

    Boolean literal or expression can be passed as argument.

    E.g., declaration:

    attribute @@allow(_ operation: String, _ condition: Boolean)

    application:

    @@allow("read", true)
    +@@allow("update", auth() != null)
  • ContextType

    A special type that represents the type of the field onto which the attribute is attached.

    E.g., declaration:

    attribute @default(_ value: ContextType)

    application:

    f1 String @default("hello")
    +f2 Int @default(1)
  • FieldReference

    References to fields defined in the current model.

    E.g., declaration:

    attribute @relation(
    +    _ name: String?,
    +    fields: FieldReference[]?,
    +    references: FieldReference[]?,
    +    onDelete: ReferentialAction?,
    +    onUpdate: ReferentialAction?,
    +    map: String?)

    application:

    model Model {
    +    ...
    +    // [ownerId] is a list of FieldReference
    +    owner Owner @relation(fields: [ownerId], references: [id])
    +    ownerId
    +}
  • Enum

    Attribute parameter can also be typed as predefined enum.

    E.g., declaration:

    attribute @relation(
    +    _ name: String?,
    +    fields: FieldReference[]?,
    +    references: FieldReference[]?,
    +    // ReferentialAction is a predefined enum
    +    onDelete: ReferentialAction?,
    +    onUpdate: ReferentialAction?,
    +    map: String?)

    application:

    model Model {
    +    // 'Cascade' is a predefined enum value
    +    owner Owner @relation(..., onDelete: Cascade)
    +}

An attribute parameter can be typed as any of the above type, a list of the above type, or an optional of the above type.

    model Model {
+        ...
+        f1 String
+        f2 String
+        // a list of FieldReference
+        @@unique([f1, f2])
+    }

Attribute functions

Attribute functions are used for providing values for attribute arguments, e.g., current DateTime, an autoincrement Int, etc. They can be used in place of attribute argument, like:

model Model {
+    ...
+    serial Int @default(autoincrement())
+    createdAt DateTime @default(now())
+}

You can find a list of predefined attribute functions here.

Predefined attributes

Field attributes

  • @id

    attribute @id(map: String?)

    Defines an ID on the model.

    Params:

    + + + + + + + + + + +
    NameDescription
    mapThe name of the underlying primary key constraint in the database
    +
  • @default

        attribute @default(_ value: ContextType)

    Defines a default value for a field.

    Params:

    + + + + + + + + + + +
    NameDescription
    valueThe default value expression
    +
  • @unique

        attribute @unique(map: String?)

    Defines a unique constraint for this field.

    Params:

    + + + + + + + + + + +
    NameDescription
    mapThe name of the underlying primary key constraint in the database
    +
  • @relation

        attribute @relation(_ name: String?, fields: FieldReference[]?, references: FieldReference[]?, onDelete: ReferentialAction?, onUpdate: ReferentialAction?, map: String?)

    Defines meta information about a relation.

    Params:

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDescription
    nameThe name of the relationship
    fieldsA list of fields defined in the current model
    referencesA list of fields of the model on the other side of the relation
    onDeleteReferential action to take on delete. See details here.
    onUpdateReferential action to take on update. See details here.
    +
  • @map

        attribute @map(_ name: String)

    Maps a field name or enum value from the schema to a column with a different name in the database.

    Params:

    + + + + + + + + + + +
    NameDescription
    mapThe name of the underlying column in the database
    +
  • @updatedAt

        attribute @updatedAt()

    Automatically stores the time when a record was last updated.

  • @password

        attribute @password(saltLength: Int?, salt: String?)

    Indicates that the field is a password field and needs to be hashed before persistence.

    NOTE: ZenStack uses bcryptjs library to hash password. You can use the saltLength parameter to configure the cost of hashing, or use salt parameter to provide an explicit salt. By default, salt length of 12 is used. See bcryptjs for more details.

    Params:

    + + + + + + + + + + + + + + +
    NameDescription
    saltLengthThe length of salt to use (cost factor for the hash function)
    saltThe salt to use (a pregenerated valid salt)
    +
  • @omit

        attribute @omit()

    Indicates that the field should be omitted when read from the generated services. Commonly used together with @password attribute.

Model attributes

  • @@unique

        attribute @@unique(_ fields: FieldReference[], name: String?, map: String?)

    Defines a compound unique constraint for the specified fields.

    Params:

    + + + + + + + + + + + + + + + + + + +
    NameDescription
    fieldsA list of fields defined in the current model
    nameThe name of the unique combination of fields
    mapThe name of the underlying unique constraint in the database
    +
  • @@index

        attribute @@index(_ fields: FieldReference[], map: String?)

    Defines an index in the database.

    Params:

    + + + + + + + + + + + + + + +
    NameDescription
    fieldsA list of fields defined in the current model
    mapThe name of the underlying index in the database
    +
  • @@map

        attribute @@map(_ name: String)

    Maps the schema model name to a table with a different name, or an enum name to a different underlying enum in the database.

    Params:

    + + + + + + + + + + +
    NameDescription
    nameThe name of the underlying table or enum in the database
    +
  • @@allow

        attribute @@allow(_ operation: String, _ condition: Boolean)

    Defines an access policy that allows a set of operations when the given condition is true.

    Params:

    + + + + + + + + + + + + + + +
    NameDescription
    operationComma separated list of operations to control, including "create", "read", "update", and "delete". Pass "all" as an abbriviation for including all operations.
    conditionBoolean expression indicating if the operations should be allowed
    +
  • @@deny

        attribute @@deny(_ operation: String, _ condition: Boolean)

    Defines an access policy that denies a set of operations when the given condition is true.

    Params:

    + + + + + + + + + + + + + + +
    NameDescription
    operationComma separated list of operations to control, including "create", "read", "update", and "delete". Pass "all" as an abbriviation for including all operations.
    conditionBoolean expression indicating if the operations should be denied
    +

Predefined attribute functions

  • uuid

        function uuid(): String {}

    Generates a globally unique identifier based on the UUID spec.

  • cuid

        function cuid(): String {}

    Generates a globally unique identifier based on the CUID spec.

  • now

        function now(): DateTime {}

    Gets current date-time.

  • autoincrement

        function autoincrement(): Int {}

    Creates a sequence of integers in the underlying database and assign the incremented + values to the ID values of the created records based on the sequence.

  • dbgenerated

        function dbgenerated(expr: String): Any {}

    Represents default values that cannot be expressed in the Prisma schema (such as random()).

  • auth

        function auth(): User {}

    Gets the current login user. The return type of the function is the User data model defined in the current ZModel.

Examples

Here're some examples on using field and model attributes:

model User {
+    // unique id field with a default UUID value
+    id String @id @default(uuid())
+
+    // require email field to be unique
+    email String @unique
+
+    // password is hashed with bcrypt with length of 16, omitted when returned from the CRUD services
+    password String @password(saltLength: 16) @omit
+
+    // default to current date-time
+    createdAt DateTime @default(now())
+
+    // auto-updated when the entity is modified
+    updatedAt DateTime @updatedAt
+
+    // mapping to a different column name in database
+    description String @map("desc")
+
+    // mapping to a different table name in database
+    @@map("users")
+
+    // use @@index to specify fields to create database index for
+    @@index([email])
+}
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/zmodel-data-model.html b/doc-serve/public/static/zmodel-data-model.html new file mode 100644 index 000000000..91e69bd6a --- /dev/null +++ b/doc-serve/public/static/zmodel-data-model.html @@ -0,0 +1,162 @@ + + + Data model + + + + + + + + + + + + + + + + + + + + + + + + + +

Data model

Data models represent business entities of your application.

Syntax

A data model declaration takes the following form:

model [NAME] {
+    [FIELD]*
+}
  • [NAME]:

    Name of the data model. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression [A-Za-z][a-za-z0-9_]\*.

  • [FIELD]:

    Arbitrary number of fields. See next section for details.

Note

A data model must include a String typed field named id, marked with @id attribute. The id field serves as a unique identifier for a model entity, and is mapped to the database table's primary key.

See here for more details about attributes.

Example

model User {
+    id String @id
+}
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/zmodel-data-source.html b/doc-serve/public/static/zmodel-data-source.html new file mode 100644 index 000000000..a86eeb9e9 --- /dev/null +++ b/doc-serve/public/static/zmodel-data-source.html @@ -0,0 +1,251 @@ + + + Data source + + + + + + + + + + + + + + + + + + + + + + + + + +

Data source

Every model needs to include exactly one datasource declaration, providing information on how to connect to the underlying database.

Syntax

A data source declaration takes the following form:

datasource [NAME] {
+    provider = [PROVIDER]
+    url = [DB_URL]
+}
  • [NAME]:

    Name of the data source. Needs to be a valid identifier matching regular expression [A-Za-z][a-za-z0-9_]\*. Name is only informational and serves no other purposes.

  • [PROVIDER]:

    Name of database connector. Valid values:

    • sqlite
    • postgresql
    • mysql
    • sqlserver
    • cockroachdb
  • [DB_URL]:

    Database connection string. Either a plain string or an invocation of env function to fetch from an environment variable.

Examples

datasource db {
+    provider = "postgresql"
+    url = "postgresql://postgres:abc123@localhost:5432/todo?schema=public"
+}

It's highly recommended that you don't commit sensitive database connection string into source control. Alternatively, you can load it from an environment variable:

datasource db {
+    provider = "postgresql"
+    url = env("DATABASE_URL")
+}

Supported databases

ZenStack uses Prisma to talk to databases, so all relational databases supported by Prisma is supported by ZenStack as well.

Here's a list for your reference:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DatabaseVersion
PostgreSQL9.6
PostgreSQL10
PostgreSQL11
PostgreSQL12
PostgreSQL13
PostgreSQL14
PostgreSQL15
MySQL5.6
MySQL5.7
MySQL8
MariaDB10
SQLite*
AWS Aurora*
AWS Aurora Serverless*
Microsoft SQL Server2022
Microsoft SQL Server2019
Microsoft SQL Server2017
Azure SQL*
CockroachDB21.2.4+
+

You can find the orignal list here.

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/zmodel-enum.html b/doc-serve/public/static/zmodel-enum.html new file mode 100644 index 000000000..82814af11 --- /dev/null +++ b/doc-serve/public/static/zmodel-enum.html @@ -0,0 +1,163 @@ + + + Enum + + + + + + + + + + + + + + + + + + + + + + + + + +

Enum

Enums are container declarations for grouping constant identifiers. You can use them to express concepts like user roles, product categories, etc.

Syntax

Enum declarations take the following form:

enum [ENUM_NAME] {
+    [FIELD]*
+}
  • [ENUM_NAME]

    Name of the enum. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression [A-Za-z][a-za-z0-9_]\*.

  • [FIELD]

    Field identifier. Needs to be unique in the data model. Needs to be a valid identifier matching regular expression [A-Za-z][a-za-z0-9_]\*.

Example

enum UserRole {
+    USER
+    ADMIN
+}
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/zmodel-field-constraint.html b/doc-serve/public/static/zmodel-field-constraint.html new file mode 100644 index 000000000..8a9955c6a --- /dev/null +++ b/doc-serve/public/static/zmodel-field-constraint.html @@ -0,0 +1,164 @@ + + + Field constraint + + + + + + + + + + + + + + + + + + + + + + + + + +

Field constraint

Overview

Field constraints are used for attaching constraints to field values. Unlike access policies, field constraints only apply on individual fields, and are only checked for 'create' and 'update' operations.

Internally ZenStack uses zod for validation. The checks are run in both the server-side CURD services and the clent-side React hooks. For the server side, upon validation error, HTTP 400 is returned with a body containing a message field for details. For the client side, a ValidationError is thrown.

Constraint attributes

The following attributes can be used to attach field constraints:

String

  • @length(_ min: Int?, _ max: Int?)

    Validates length of a string field.

  • @startsWith(_ text: String)

    Validates a string field value starts with the given text.

  • @endsWith(_ text: String)

    Validates a string field value ends with the given text.

  • @email()

    Validates a string field value is a valid email address.

  • @url()

    Validates a string field value is a valid url.

  • @datetime()

    Validates a string field value is a valid ISO datetime.

  • @regex(_ regex: String)

    Validates a string field value matches a regex.

Number

  • @gt(_ value: Int)

    Validates a number field is greater than the given value.

  • @gte(_ value: Int)

    Validates a number field is greater than or equal to the given value.

  • @lt(_ value: Int)

    Validates a number field is less than the given value.

  • @lte(_ value: Int)

    Validates a number field is less than or equal to the given value.

Example

model User {
+    id String @id
+    handle String @regex("^[0-9a-zA-Z]{4,16}$")
+    email String @email @endsWith("@myorg.com")
+    profileImage String? @url
+    age Int @gt(0)
+}
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/zmodel-field.html b/doc-serve/public/static/zmodel-field.html new file mode 100644 index 000000000..4e57e4649 --- /dev/null +++ b/doc-serve/public/static/zmodel-field.html @@ -0,0 +1,182 @@ + + + Field + + + + + + + + + + + + + + + + + + + + + + + + + +

Field

Fields are typed members of data models.

Syntax

A field declaration takes the following form:

model Model {
+    [FIELD_NAME] [FIELD_TYPE] (FIELD_ATTRIBUTES)?
+}
  • [FIELD_NAME]

    Name of the field. Needs to be unique in the containing data model. Needs to be a valid identifier matching regular expression [A-Za-z][a-za-z0-9_]\*.

  • [FIELD_TYPE]

    Type of the field. Can be a scalar type or a reference to another data model.

    The following scalar types are supported:

    • String

    • Boolean

    • Int

    • BigInt

    • Float

    • Decimal

    • Json

    • Bytes

      A field's type can be any of the scalar or reference type, a list of the aforementioned type (suffixed with []), or an optional of the aforementioned type (suffixed with ?).

  • [FIELD_ATTRIBUTES]

    Field attributes attach extra behaviors or constraints to the field. See Attribute for more information.

Example

model Post {
+    // "id" field is a mandatory unique identifier of this model
+    id String @id @default(uuid())
+
+    // fields can be DateTime
+    createdAt DateTime @default(now())
+    updatedAt DateTime @updatedAt
+
+    // or string
+    title String
+
+    // or integer
+    viewCount Int @default(0)
+
+    // and optional
+    content String?
+
+    // and a list too
+    tags String[]
+
+    // and can reference another data model too
+    comments Comment[]
+}
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/zmodel-overview.html b/doc-serve/public/static/zmodel-overview.html new file mode 100644 index 000000000..e616910ef --- /dev/null +++ b/doc-serve/public/static/zmodel-overview.html @@ -0,0 +1,158 @@ + + + Overview + + + + + + + + + + + + + + + + + + + + + + + + + +

Overview

ZModel, the modeling DSL of ZenStack, is the main concept that you'll deal with when using this toolkit.

The ZModel syntax is extended from the schema language of Prisma ORM. We made that choice based on several reasons:

  • CRUD heavily relies on database operations, however creating a new ORM doesn't add much value to the community, since there're already nice and mature solutions out there; so instead, we decided to extend Prisma - the overall best ORM toolkit for Typescript.

  • Prisma's schema language is simple and intuitive.

  • Extending a popular existing language lowers the learning curve, compared to inventing a new one.

Even so, this section provides detailed descriptions about all aspects of the ZModel language, so you don't need to jump over to Prisma's documentation for extra learnings.

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/zmodel-referential-action.html b/doc-serve/public/static/zmodel-referential-action.html new file mode 100644 index 000000000..56cdf1af8 --- /dev/null +++ b/doc-serve/public/static/zmodel-referential-action.html @@ -0,0 +1,179 @@ + + + Referential action + + + + + + + + + + + + + + + + + + + + + + + + + +

Referential action

Overview

When defining a relation, you can use referential action to control what happens when one side of a relation is updated or deleted, by setting the onDelete and onUpdate parameters in the @relation attribute.

    attribute @relation(
+        _ name: String?,
+        fields: FieldReference[]?,
+        references: FieldReference[]?,
+        onDelete: ReferentialAction?,
+        onUpdate: ReferentialAction?,
+        map: String?)

The ReferentialAction enum is defined as:

enum ReferentialAction {
+    Cascade
+    Restrict
+    NoAction
+    SetNull
+    SetDefault
+}
  • Cascade

    • onDelete: deleting a referenced record will trigger the deletion of referencing record.

    • onUpdate: updates the relation scalar fields if the referenced scalar fields of the dependent record are updated.

  • Restrict

    • onDelete: prevents the deletion if any referencing records exist.
    • onUpdate: prevents the identifier of a referenced record from being changed.
  • NoAction

    Similar to 'Restrict', the difference between the two is dependent on the database being used.

    See details here

  • SetNull

    • onDelete: the scalar field of the referencing object will be set to NULL.
    • onUpdate: when updating the identifier of a referenced object, the scalar fields of the referencing objects will be set to NULL.
  • SetDefault

    • onDelete: the scalar field of the referencing object will be set to the fields default value.
    • onUpdate: the scalar field of the referencing object will be set to the fields default value.

Example

model User {
+    id String @id
+    profile Profile?
+}
+
+model Profile {
+    id String @id
+    user @relation(fields: [userId], references: [id], onUpdate: Cascade, onDelete: Cascade)
+    userId String @unique
+}
+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/doc-serve/public/static/zmodel-relation.html b/doc-serve/public/static/zmodel-relation.html new file mode 100644 index 000000000..43054ee82 --- /dev/null +++ b/doc-serve/public/static/zmodel-relation.html @@ -0,0 +1,203 @@ + + + Relation + + + + + + + + + + + + + + + + + + + + + + + + + +

Relation

Relations are connections among data models. There're three types of relations:

  • One-to-one
  • One-to-many
  • Many-to-many

Relations are expressed with a pair of fields and together with the special @relation field attribute. One side of the relation field carries the @relation attribute to indicate how the connection is established.

One-to-one relation

The owner side of the relation declares an optional field typed as the data model of the owned side of the relation.

On the owned side, a reference field is declared with @relation attribute, together with an foreign key field storing the id of the owner entity.

model User {
+    id String @id
+    profile Profile?
+}
+
+model Profile {
+    id String @id
+    user @relation(fields: [userId], references: [id])
+    userId String @unique
+}

One-to-many relation

The owner side of the relation declares a list field typed as the data model of the owned side of the relation.

On the owned side, a reference field is declared with @relation attribute, together with an foreign key field storing the id of the owner entity.

model User {
+    id String @id
+    posts Post[]
+}
+
+model Post {
+    id String @id
+    author User? @relation(fields: [authorId], references: [id])
+    authorId String?
+}

Many-to-one relation

A join model is declared to connect the two sides of the relation, using two one-to-one relations.

Each side of the relation then establishes a one-to-many relation with the join model.

model Space {
+    id String @id
+    // one-to-many with the "join-model"
+    members Membership[]
+}
+
+// Membership is the "join-model" between User and Space
+model Membership {
+    id String @id()
+
+    // one-to-many from Space
+    space Space @relation(fields: [spaceId], references: [id])
+    spaceId String
+
+    // one-to-many from User
+    user User @relation(fields: [userId], references: [id])
+    userId String
+
+    // a user can be member of a space for only once
+    @@unique([userId, spaceId])
+}
+
+model User {
+    id String @id
+    // one-to-many with the "join-model"
+    membership Membership[]
+}
+

Referential action

When defining a relation, you can specify what happens when one side of a relation is updated or deleted. See Referential action for details.

+ + + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/ref/telemetry.md b/doc-serve/public/telemetry.md similarity index 79% rename from docs/ref/telemetry.md rename to doc-serve/public/telemetry.md index bda22e2c2..42540dac0 100644 --- a/docs/ref/telemetry.md +++ b/doc-serve/public/telemetry.md @@ -14,7 +14,7 @@ The information collected includes: We don't collect any telemetry at the runtime of apps using ZenStack. -We appreciate that you keep the telemetry ON so we can keep improving the toolkit. We follow the [Console Do Not Track](https://consoledonottrack.com/) convention, and you can turn off the telemetry by setting environment variable `DO_NOT_TRACK` to `1`: +We appreciate that you keep the telemetry ON so we can keep improving the toolkit. We follow the [Console Do Not Track](https://consoledonottrack.com/ ':target=blank') convention, and you can turn off the telemetry by setting environment variable `DO_NOT_TRACK` to `1`: ```bash DO_NOT_TRACK=1 npx zenstack ... diff --git a/doc-serve/public/vscode-extension.md b/doc-serve/public/vscode-extension.md new file mode 100644 index 000000000..c48150116 --- /dev/null +++ b/doc-serve/public/vscode-extension.md @@ -0,0 +1,5 @@ +# VSCode extension + +ZenStack VSCode extension provides syntax highlighting and error checking to improve the efficiency of your modeling work. + +You can install by searching "ZenStack Language Tools" inside of VSCode, or from [here](https://marketplace.visualstudio.com/items?itemName=zenstack.zenstack) directly. diff --git a/doc-serve/public/zmodel-access-policy.md b/doc-serve/public/zmodel-access-policy.md new file mode 100644 index 000000000..9ecdcd83f --- /dev/null +++ b/doc-serve/public/zmodel-access-policy.md @@ -0,0 +1,203 @@ +# Access policy + +Access policies use `@@allow` and `@@deny` rules to specify the eligibility of an operation over a model entity. The signatures of the attributes are: + +- `@@allow` + + ```zmodel + attribute @@allow(_ operation: String, _ condition: Boolean) + ``` + + _Params_: + + | Name | Description | + | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | + | operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbriviation for including all operations. | + | condition | Boolean expression indicating if the operations should be allowed | + +- `@@deny` + + ```zmodel + attribute @@deny(_ operation: String, _ condition: Boolean) + ``` + + _Params_: + + | Name | Description | + | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | + | operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbriviation for including all operations. | + | condition | Boolean expression indicating if the operations should be denied | + +## Using authentication in policy rules + +It's very common to use the current login user to verdict if an operation should be permitted. Therefore, ZenStack provides a built-in `auth()` attribute function that evaluates to the `User` entity corresponding to the current user. To use the function, your ZModel file must define a `User` data model. + +You can use `auth()` to: + +- Check if a user is logged in + + ```zmodel + @@deny('all', auth() == null) + ``` + +- Access user's fields + + ```zmodel + @@allow('update', auth().role == 'ADMIN') + ``` + +- Compare user identity + + ```zmodel + // owner is a relation field to User model + @@allow('update', auth() == owner) + ``` + +## Accessing relation fields in policy + +As you've seen in the examples above, you can access fields from relations in policy expressions. For example, to express "a user can be read by any user sharing a space" in the `User` model, you can directly read into its `membership` field. + +```zmodel + @@allow('read', membership?[space.members?[user == auth()]]) +``` + +In most cases, when you use a "to-many" relation in a policy rule, you'll use "Collection Predicate" to express a condition. See [next section](#collection-predicate-expressions) for details. + +## Collection predicate expressions + +Collection predicate expressions are boolean expressions used to express conditions over a list. It's mainly designed for building policy rules for "to-many" relations. It has three forms of syntaxes: + +- Any + + ``` + ?[condition] + ``` + + Any element in `collection` matches `condition` + +- All + + ``` + ![condition] + ``` + + All elements in `collection` match `condition` + +- None + + ``` + ^[condition] + ``` + + None element in `collection` matches `condition` + +The `condition` expression has direct access to fields defined in the model of `collection`. E.g.: + +```zmodel + @@allow('read', members?[user == auth()]) +``` + +, in condition `user == auth()`, `user` refers to the `user` field in model `Membership`, because the collection `members` is resolved to `Membership` model. + +Also, collection predicates can be nested to express complex conditions involving multi-level relation lookup. E.g.: + +```zmodel + @@allow('read', membership?[space.members?[user == auth()]]) +``` + +In this example, `user` refers to `user` field of `Membership` model because `space.members` is resolved to `Membership` model. + +## Combining multiple rules + +A data model can contain arbitrary number of policy rules. The logic of combining them is as follows: + +- The operation is rejected if any of the conditions in `@@deny` rules evaluate to `true` +- Otherwise, the operation is permitted if any of the conditions in `@@allow` rules evaluate to `true` +- Otherwise, the operation is rejected + +## Example + +### A simple example with Post model + +```zmodel +model Post { + // reject all operations if user's not logged in + @@deny('all', auth() == null) + + // allow all operations if the entity's owner matches the current user + @@allow('all', auth() == owner) + + // posts are readable to anyone + @allow('read', true) +} +``` + +### A more complex example with multi-user spaces + +```zmodel +model Space { + id String @id + members Membership[] + owner User @relation(fields: [ownerId], references: [id]) + ownerId String + + // require login + @@deny('all', auth() == null) + + // everyone can create a space + @@allow('create', true) + + // owner can do everything + @@allow('all', auth() == owner) + + // any user in the space can read the space + // + // Here the ?[condition] syntax is called + // "Collection Predicate", used to check if any element + // in the "collection" matches the "condition" + @@allow('read', members?[user == auth()]) +} + +// Membership is the "join-model" between User and Space +model Membership { + id String @id() + + // one-to-many from Space + space Space @relation(fields: [spaceId], references: [id]) + spaceId String + + // one-to-many from User + user User @relation(fields: [userId], references: [id]) + userId String + + // a user can be member of a space for only once + @@unique([userId, spaceId]) + + // require login + @@deny('all', auth() == null) + + // space owner can create/update/delete + @@allow('create,update,delete', space.owner == auth()) + + // user can read entries for spaces which he's a member of + @@allow('read', space.members?[user == auth()]) +} + +model User { + id String @id + email String @unique + membership Membership[] + ownedSpaces Space[] + + // allow signup + @@allow('create', true) + + // user can do everything to herself; note that "this" represents + // the current entity + @@allow('all', auth() == this) + + // can be read by users sharing a space + @@allow('read', membership?[space.members?[user == auth()]]) +} + +``` diff --git a/doc-serve/public/zmodel-attribute.md b/doc-serve/public/zmodel-attribute.md new file mode 100644 index 000000000..3a9c26be8 --- /dev/null +++ b/doc-serve/public/zmodel-attribute.md @@ -0,0 +1,480 @@ +# Attribute + +Attributes decorate fields and data models and attach extra behaviors or constraints to them. + +## Syntax + +### Field attribute + +Field attribute name is prefixed by a single `@`. Its application takes the following form: + +```zmodel +id String @[ATTR_NAME](ARGS)? +``` + +- **[ATTR_NAME]** + +Attribute name. See [below](#built-in-attributes) for a full list of attributes. + +- **[ARGS]** + +See [attribute arguments](#attribute-arguments). + +### Data model attribute + +Field attribute name is prefixed double `@@`. Its application takes the following form: + +```zmodel +model Model { + @@[ATTR_NAME](ARGS)? +} +``` + +- **[ATTR_NAME]** + +Attribute name. See [below](#built-in-attributes) for a full list of attributes. + +- **[ARGS]** + +See [attribute arguments](#attribute-arguments). + +### Arguments + +Attribute can be declared with a list of parameters, and applied with an optional comma-separated list of arguments. + +Arguments are mapped to parameters by position or by name. For example, for the `@default` attribute declared as: + +```zmodel +attribute @default(_ value: ContextType) +``` + +, the following two ways of applying it are equivalent: + +```zmodel +published Boolean @default(value: false) +``` + +```zmodel +published Boolean @default(false) +``` + +## Parameter types + +Attribute parameters are typed. The following types are supported: + +- Int + + Integer literal can be passed as argument. + + E.g., declaration: + + ```zmodel + attribute @password(saltLength: Int?, salt: String?) + + ``` + + application: + + ```zmodel + password String @password(saltLength: 10) + ``` + +- String + + String literal can be passed as argument. + + E.g., declaration: + + ```zmodel + attribute @id(map: String?) + ``` + + application: + + ```zmodel + id String @id(map: "_id") + ``` + +- Boolean + + Boolean literal or expression can be passed as argument. + + E.g., declaration: + + ```zmodel + attribute @@allow(_ operation: String, _ condition: Boolean) + ``` + + application: + + ```zmodel + @@allow("read", true) + @@allow("update", auth() != null) + ``` + +- ContextType + + A special type that represents the type of the field onto which the attribute is attached. + + E.g., declaration: + + ```zmodel + attribute @default(_ value: ContextType) + ``` + + application: + + ```zmodel + f1 String @default("hello") + f2 Int @default(1) + ``` + +- FieldReference + + References to fields defined in the current model. + + E.g., declaration: + + ```zmodel + attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) + ``` + + application: + + ```zmodel + model Model { + ... + // [ownerId] is a list of FieldReference + owner Owner @relation(fields: [ownerId], references: [id]) + ownerId + } + ``` + +- Enum + + Attribute parameter can also be typed as predefined enum. + + E.g., declaration: + + ```zmodel + attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + // ReferentialAction is a predefined enum + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) + ``` + + application: + + ```zmodel + model Model { + // 'Cascade' is a predefined enum value + owner Owner @relation(..., onDelete: Cascade) + } + ``` + +An attribute parameter can be typed as any of the above type, a list of the above type, or an optional of the above type. + +```zmodel + model Model { + ... + f1 String + f2 String + // a list of FieldReference + @@unique([f1, f2]) + } +``` + +## Attribute functions + +Attribute functions are used for providing values for attribute arguments, e.g., current `DateTime`, an autoincrement `Int`, etc. They can be used in place of attribute argument, like: + +```zmodel +model Model { + ... + serial Int @default(autoincrement()) + createdAt DateTime @default(now()) +} +``` + +You can find a list of predefined attribute functions [here](#predefined-attribute-functions). + +## Predefined attributes + +### Field attributes + +- `@id` + + ```zmodel + attribute @id(map: String?) + ``` + + Defines an ID on the model. + + _Params_: + + | Name | Description | + | ---- | ----------------------------------------------------------------- | + | map | The name of the underlying primary key constraint in the database | + +- `@default` + + ```zmodel + attribute @default(_ value: ContextType) + ``` + + Defines a default value for a field. + + _Params_: + + | Name | Description | + | ----- | ---------------------------- | + | value | The default value expression | + +- `@unique` + + ```zmodel + attribute @unique(map: String?) + ``` + + Defines a unique constraint for this field. + + _Params_: + + | Name | Description | + | ---- | ----------------------------------------------------------------- | + | map | The name of the underlying primary key constraint in the database | + +- `@relation` + + ```zmodel + attribute @relation(_ name: String?, fields: FieldReference[]?, references: FieldReference[]?, onDelete: ReferentialAction?, onUpdate: ReferentialAction?, map: String?) + ``` + + Defines meta information about a relation. + + _Params_: + + | Name | Description | + | ---------- | --------------------------------------------------------------------------------------- | + | name | The name of the relationship | + | fields | A list of fields defined in the current model | + | references | A list of fields of the model on the other side of the relation | + | onDelete | Referential action to take on delete. See details [here](zmodel-referential-action.md). | + | onUpdate | Referential action to take on update. See details [here](zmodel-referential-action.md). | + +- `@map` + + ```zmodel + attribute @map(_ name: String) + ``` + + Maps a field name or enum value from the schema to a column with a different name in the database. + + _Params_: + + | Name | Description | + | ---- | ------------------------------------------------- | + | map | The name of the underlying column in the database | + +- `@updatedAt` + + ```zmodel + attribute @updatedAt() + ``` + + Automatically stores the time when a record was last updated. + +- `@password` + + ```zmodel + attribute @password(saltLength: Int?, salt: String?) + ``` + + Indicates that the field is a password field and needs to be hashed before persistence. + + _NOTE_: ZenStack uses `bcryptjs` library to hash password. You can use the `saltLength` parameter to configure the cost of hashing, or use `salt` parameter to provide an explicit salt. By default, salt length of 12 is used. See [bcryptjs](https://www.npmjs.com/package/bcryptjs ':target=blank') for more details. + + _Params_: + + | Name | Description | + | ---------- | ------------------------------------------------------------- | + | saltLength | The length of salt to use (cost factor for the hash function) | + | salt | The salt to use (a pregenerated valid salt) | + +- `@omit` + + ```zmodel + attribute @omit() + ``` + + Indicates that the field should be omitted when read from the generated services. Commonly used together with `@password` attribute. + +### Model attributes + +- `@@unique` + + ```zmodel + attribute @@unique(_ fields: FieldReference[], name: String?, map: String?) + ``` + + Defines a compound unique constraint for the specified fields. + + _Params_: + + | Name | Description | + | ------ | ------------------------------------------------------------ | + | fields | A list of fields defined in the current model | + | name | The name of the unique combination of fields | + | map | The name of the underlying unique constraint in the database | + +- `@@index` + + ```zmodel + attribute @@index(_ fields: FieldReference[], map: String?) + ``` + + Defines an index in the database. + + _Params_: + + | Name | Description | + | ------ | ------------------------------------------------ | + | fields | A list of fields defined in the current model | + | map | The name of the underlying index in the database | + +- `@@map` + + ```zmodel + attribute @@map(_ name: String) + ``` + + Maps the schema model name to a table with a different name, or an enum name to a different underlying enum in the database. + + _Params_: + + | Name | Description | + | ---- | -------------------------------------------------------- | + | name | The name of the underlying table or enum in the database | + +- `@@allow` + + ```zmodel + attribute @@allow(_ operation: String, _ condition: Boolean) + ``` + + Defines an access policy that allows a set of operations when the given condition is true. + + _Params_: + + | Name | Description | + | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | + | operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbriviation for including all operations. | + | condition | Boolean expression indicating if the operations should be allowed | + +- `@@deny` + + ```zmodel + attribute @@deny(_ operation: String, _ condition: Boolean) + ``` + + Defines an access policy that denies a set of operations when the given condition is true. + + _Params_: + + | Name | Description | + | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | + | operation | Comma separated list of operations to control, including `"create"`, `"read"`, `"update"`, and `"delete"`. Pass` "all"` as an abbriviation for including all operations. | + | condition | Boolean expression indicating if the operations should be denied | + +## Predefined attribute functions + +- `uuid` + + ```zmodel + function uuid(): String {} + ``` + + Generates a globally unique identifier based on the UUID spec. + +- `cuid` + + ```zmodel + function cuid(): String {} + ``` + + Generates a globally unique identifier based on the [CUID](https://github.com/ericelliott/cuid) spec. + +- `now` + + ```zmodel + function now(): DateTime {} + ``` + + Gets current date-time. + +- `autoincrement` + + ```zmodel + function autoincrement(): Int {} + ``` + + Creates a sequence of integers in the underlying database and assign the incremented + values to the ID values of the created records based on the sequence. + +- `dbgenerated` + + ```zmodel + function dbgenerated(expr: String): Any {} + ``` + + Represents default values that cannot be expressed in the Prisma schema (such as random()). + +- `auth` + + ```zmodel + function auth(): User {} + ``` + + Gets the current login user. The return type of the function is the `User` data model defined in the current ZModel. + +## Examples + +Here're some examples on using field and model attributes: + +```zmodel +model User { + // unique id field with a default UUID value + id String @id @default(uuid()) + + // require email field to be unique + email String @unique + + // password is hashed with bcrypt with length of 16, omitted when returned from the CRUD services + password String @password(saltLength: 16) @omit + + // default to current date-time + createdAt DateTime @default(now()) + + // auto-updated when the entity is modified + updatedAt DateTime @updatedAt + + // mapping to a different column name in database + description String @map("desc") + + // mapping to a different table name in database + @@map("users") + + // use @@index to specify fields to create database index for + @@index([email]) +} +``` diff --git a/doc-serve/public/zmodel-data-model.md b/doc-serve/public/zmodel-data-model.md new file mode 100644 index 000000000..b93d3aa62 --- /dev/null +++ b/doc-serve/public/zmodel-data-model.md @@ -0,0 +1,35 @@ +# Data model + +Data models represent business entities of your application. + +## Syntax + +A data model declaration takes the following form: + +```zmodel +model [NAME] { + [FIELD]* +} +``` + +- **[NAME]**: + + Name of the data model. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **[FIELD]**: + + Arbitrary number of fields. See [next section](zmodel-field.md) for details. + +## Note + +A data model must include a `String` typed field named `id`, marked with `@id` attribute. The `id` field serves as a unique identifier for a model entity, and is mapped to the database table's primary key. + +See [here](zmodel-attribute.md) for more details about attributes. + +## Example + +```zmodel +model User { + id String @id +} +``` diff --git a/doc-serve/public/zmodel-data-source.md b/doc-serve/public/zmodel-data-source.md new file mode 100644 index 000000000..1b93c84d9 --- /dev/null +++ b/doc-serve/public/zmodel-data-source.md @@ -0,0 +1,80 @@ +# Data source + +Every model needs to include exactly one `datasource` declaration, providing information on how to connect to the underlying database. + +## Syntax + +A data source declaration takes the following form: + +```zmodel +datasource [NAME] { + provider = [PROVIDER] + url = [DB_URL] +} +``` + +- **[NAME]**: + + Name of the data source. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. Name is only informational and serves no other purposes. + +- **[PROVIDER]**: + + Name of database connector. Valid values: + + - sqlite + - postgresql + - mysql + - sqlserver + - cockroachdb + +- **[DB_URL]**: + + Database connection string. Either a plain string or an invocation of `env` function to fetch from an environment variable. + +## Examples + +```zmodel +datasource db { + provider = "postgresql" + url = "postgresql://postgres:abc123@localhost:5432/todo?schema=public" +} +``` + +It's highly recommended that you don't commit sensitive database connection string into source control. Alternatively, you can load it from an environment variable: + +```zmodel +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} +``` + +## Supported databases + +ZenStack uses [Prisma](https://prisma.io ':target=_blank') to talk to databases, so all relational databases supported by Prisma is supported by ZenStack as well. + +Here's a list for your reference: + +| Database | Version | +| --------------------- | ------- | +| PostgreSQL | 9.6 | +| PostgreSQL | 10 | +| PostgreSQL | 11 | +| PostgreSQL | 12 | +| PostgreSQL | 13 | +| PostgreSQL | 14 | +| PostgreSQL | 15 | +| MySQL | 5.6 | +| MySQL | 5.7 | +| MySQL | 8 | +| MariaDB | 10 | +| SQLite | \* | +| AWS Aurora | \* | +| AWS Aurora Serverless | \* | +| Microsoft SQL Server | 2022 | +| Microsoft SQL Server | 2019 | +| Microsoft SQL Server | 2017 | +| Azure SQL | \* | +| CockroachDB | 21.2.4+ | + +You can find the orignal list [here](https://www.prisma.io/docs/reference/database-reference/supported-databases ':target=_blank'). diff --git a/doc-serve/public/zmodel-enum.md b/doc-serve/public/zmodel-enum.md new file mode 100644 index 000000000..56a2428c9 --- /dev/null +++ b/doc-serve/public/zmodel-enum.md @@ -0,0 +1,30 @@ +# Enum + +Enums are container declarations for grouping constant identifiers. You can use them to express concepts like user roles, product categories, etc. + +## Syntax + +Enum declarations take the following form: + +```prsima +enum [ENUM_NAME] { + [FIELD]* +} +``` + +- **[ENUM_NAME]** + + Name of the enum. Needs to be unique in the entire model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **[FIELD]** + + Field identifier. Needs to be unique in the data model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +## Example + +```zmodel +enum UserRole { + USER + ADMIN +} +``` diff --git a/doc-serve/public/zmodel-field-constraint.md b/doc-serve/public/zmodel-field-constraint.md new file mode 100644 index 000000000..bcc416a73 --- /dev/null +++ b/doc-serve/public/zmodel-field-constraint.md @@ -0,0 +1,71 @@ +# Field constraint + +## Overview + +Field constraints are used for attaching constraints to field values. Unlike access policies, field constraints only apply on individual fields, and are only checked for 'create' and 'update' operations. + +Internally ZenStack uses [zod](https://github.com/colinhacks/zod ':target=blank') for validation. The checks are run in both the server-side CURD services and the clent-side React hooks. For the server side, upon validation error, HTTP 400 is returned with a body containing a `message` field for details. For the client side, a `ValidationError` is thrown. + +## Constraint attributes + +The following attributes can be used to attach field constraints: + +### String + +- `@length(_ min: Int?, _ max: Int?)` + + Validates length of a string field. + +- `@startsWith(_ text: String)` + + Validates a string field value starts with the given text. + +- `@endsWith(_ text: String)` + + Validates a string field value ends with the given text. + +- `@email()` + + Validates a string field value is a valid email address. + +- `@url()` + + Validates a string field value is a valid url. + +- `@datetime()` + + Validates a string field value is a valid ISO datetime. + +- `@regex(_ regex: String)` + + Validates a string field value matches a regex. + +### Number + +- `@gt(_ value: Int)` + + Validates a number field is greater than the given value. + +- `@gte(_ value: Int)` + + Validates a number field is greater than or equal to the given value. + +- `@lt(_ value: Int)` + + Validates a number field is less than the given value. + +- `@lte(_ value: Int)` + + Validates a number field is less than or equal to the given value. + +## Example + +```zmodel +model User { + id String @id + handle String @regex("^[0-9a-zA-Z]{4,16}$") + email String @email @endsWith("@myorg.com") + profileImage String? @url + age Int @gt(0) +} +``` diff --git a/doc-serve/public/zmodel-field.md b/doc-serve/public/zmodel-field.md new file mode 100644 index 000000000..a989228b5 --- /dev/null +++ b/doc-serve/public/zmodel-field.md @@ -0,0 +1,66 @@ +# Field + +Fields are typed members of data models. + +## Syntax + +A field declaration takes the following form: + +```zmodel +model Model { + [FIELD_NAME] [FIELD_TYPE] (FIELD_ATTRIBUTES)? +} +``` + +- **[FIELD_NAME]** + + Name of the field. Needs to be unique in the containing data model. Needs to be a valid identifier matching regular expression `[A-Za-z][a-za-z0-9_]\*`. + +- **[FIELD_TYPE]** + + Type of the field. Can be a scalar type or a reference to another data model. + + The following scalar types are supported: + + - String + - Boolean + - Int + - BigInt + - Float + - Decimal + - Json + - Bytes + + A field's type can be any of the scalar or reference type, a list of the aforementioned type (suffixed with `[]`), or an optional of the aforementioned type (suffixed with `?`). + +- **[FIELD_ATTRIBUTES]** + + Field attributes attach extra behaviors or constraints to the field. See [Attribute](zmodel-attribute.md) for more information. + +## Example + +```zmodel +model Post { + // "id" field is a mandatory unique identifier of this model + id String @id @default(uuid()) + + // fields can be DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // or string + title String + + // or integer + viewCount Int @default(0) + + // and optional + content String? + + // and a list too + tags String[] + + // and can reference another data model too + comments Comment[] +} +``` diff --git a/doc-serve/public/zmodel-overview.md b/doc-serve/public/zmodel-overview.md new file mode 100644 index 000000000..a3fcfc02f --- /dev/null +++ b/doc-serve/public/zmodel-overview.md @@ -0,0 +1,13 @@ +# Overview + +**ZModel**, the modeling DSL of ZenStack, is the main concept that you'll deal with when using this toolkit. + +The **ZModel** syntax is extended from the schema language of [Prisma ORM](https://prisma.io). We made that choice based on several reasons: + +- CRUD heavily relies on database operations, however creating a new ORM doesn't add much value to the community, since there're already nice and mature solutions out there; so instead, we decided to extend Prisma - the overall best ORM toolkit for Typescript. + +- Prisma's schema language is simple and intuitive. + +- Extending a popular existing language lowers the learning curve, compared to inventing a new one. + +Even so, this section provides detailed descriptions about all aspects of the ZModel language, so you don't need to jump over to Prisma's documentation for extra learnings. diff --git a/doc-serve/public/zmodel-referential-action.md b/doc-serve/public/zmodel-referential-action.md new file mode 100644 index 000000000..30cec3ada --- /dev/null +++ b/doc-serve/public/zmodel-referential-action.md @@ -0,0 +1,68 @@ +# Referential action + +## Overview + +When defining a relation, you can use referential action to control what happens when one side of a relation is updated or deleted, by setting the `onDelete` and `onUpdate` parameters in the `@relation` attribute. + +```zmodel + attribute @relation( + _ name: String?, + fields: FieldReference[]?, + references: FieldReference[]?, + onDelete: ReferentialAction?, + onUpdate: ReferentialAction?, + map: String?) +``` + +The `ReferentialAction` enum is defined as: + +```zmodel +enum ReferentialAction { + Cascade + Restrict + NoAction + SetNull + SetDefault +} +``` + +- `Cascade` + + - **onDelete**: deleting a referenced record will trigger the deletion of referencing record. + + - **onUpdate**: updates the relation scalar fields if the referenced scalar fields of the dependent record are updated. + +- `Restrict` + + - **onDelete**: prevents the deletion if any referencing records exist. + - **onUpdate**: prevents the identifier of a referenced record from being changed. + +- `NoAction` + + Similar to 'Restrict', the difference between the two is dependent on the database being used. + + See details [here](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/referential-actions#noaction ':target=blank') + +- `SetNull` + + - **onDelete**: the scalar field of the referencing object will be set to NULL. + - **onUpdate**: when updating the identifier of a referenced object, the scalar fields of the referencing objects will be set to NULL. + +- `SetDefault` + - **onDelete**: the scalar field of the referencing object will be set to the fields default value. + - **onUpdate**: the scalar field of the referencing object will be set to the fields default value. + +## Example + +```zmodel +model User { + id String @id + profile Profile? +} + +model Profile { + id String @id + user @relation(fields: [userId], references: [id], onUpdate: Cascade, onDelete: Cascade) + userId String @unique +} +``` diff --git a/doc-serve/public/zmodel-relation.md b/doc-serve/public/zmodel-relation.md new file mode 100644 index 000000000..02ca4e274 --- /dev/null +++ b/doc-serve/public/zmodel-relation.md @@ -0,0 +1,88 @@ +# Relation + +Relations are connections among data models. There're three types of relations: + +- One-to-one +- One-to-many +- Many-to-many + +Relations are expressed with a pair of fields and together with the special `@relation` field attribute. One side of the relation field carries the `@relation` attribute to indicate how the connection is established. + +## One-to-one relation + +The _owner_ side of the relation declares an optional field typed as the data model of the _owned_ side of the relation. + +On the _owned_ side, a reference field is declared with `@relation` attribute, together with an **foreign key** field storing the id of the owner entity. + +```zmodel +model User { + id String @id + profile Profile? +} + +model Profile { + id String @id + user @relation(fields: [userId], references: [id]) + userId String @unique +} +``` + +## One-to-many relation + +The _owner_ side of the relation declares a list field typed as the data model of the _owned_ side of the relation. + +On the _owned_ side, a reference field is declared with `@relation` attribute, together with an **foreign key** field storing the id of the owner entity. + +```zmodel +model User { + id String @id + posts Post[] +} + +model Post { + id String @id + author User? @relation(fields: [authorId], references: [id]) + authorId String? +} +``` + +## Many-to-one relation + +A _join model_ is declared to connect the two sides of the relation, using two one-to-one relations. + +Each side of the relation then establishes a one-to-many relation with the _join model_. + +```zmodel +model Space { + id String @id + // one-to-many with the "join-model" + members Membership[] +} + +// Membership is the "join-model" between User and Space +model Membership { + id String @id() + + // one-to-many from Space + space Space @relation(fields: [spaceId], references: [id]) + spaceId String + + // one-to-many from User + user User @relation(fields: [userId], references: [id]) + userId String + + // a user can be member of a space for only once + @@unique([userId, spaceId]) +} + +model User { + id String @id + // one-to-many with the "join-model" + membership Membership[] +} + +``` + +## Referential action + +When defining a relation, you can specify what happens when one side of a relation is updated or deleted. See [Referential action](zmodel-referential-action.md) for details. diff --git a/doc-serve/tsconfig.json b/doc-serve/tsconfig.json new file mode 100644 index 000000000..99710e857 --- /dev/null +++ b/doc-serve/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/doc-serve/vercel.json b/doc-serve/vercel.json new file mode 100644 index 000000000..c384e2204 --- /dev/null +++ b/doc-serve/vercel.json @@ -0,0 +1,3 @@ +{ + "trailingSlash": false +} diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..1d3de1ab4 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +sitemap.xml diff --git a/docs/8cd31ff7afe74424abbec00b65f04ae8.txt b/docs/8cd31ff7afe74424abbec00b65f04ae8.txt new file mode 100644 index 000000000..4c8237722 --- /dev/null +++ b/docs/8cd31ff7afe74424abbec00b65f04ae8.txt @@ -0,0 +1 @@ +8cd31ff7afe74424abbec00b65f04ae8 diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index d031bf46c..000000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -zenstack.dev \ No newline at end of file diff --git a/docs/_media/banner.png b/docs/_media/banner.png new file mode 100644 index 000000000..b2074d34e Binary files /dev/null and b/docs/_media/banner.png differ diff --git a/docs/_media/og-image.png b/docs/_media/og-image.png deleted file mode 100644 index 5c541ce85..000000000 Binary files a/docs/_media/og-image.png and /dev/null differ diff --git a/docs/_navbar.md b/docs/_navbar.md index d45aaa47f..1c416471c 100644 --- a/docs/_navbar.md +++ b/docs/_navbar.md @@ -1,3 +1 @@ -- [EN](/) -- [中文](/zh-cn/) - [Live Chat](https://go.zenstack.dev/chat ':target=_blank') diff --git a/docs/building-your-app.md b/docs/building-your-app.md index ab3cf4950..e25d70ac6 100644 --- a/docs/building-your-app.md +++ b/docs/building-your-app.md @@ -38,16 +38,13 @@ Make sure the services are mounted at route `/api/zenstack/` with a catch all pa ## _optional_ Integrating with NextAuth -If you use NextAuth for authentication, ZenStack also generates an adapter which you can use to configure NextAuth for persistence of user, session, etc. +If you use NextAuth for authentication, you can install the `@zenstackhq/next-auth` package for easier integration. This package provides an adapter and authorization helper that you can use to configure NextAuth. ```ts // pages/api/auth/[...nextauth].ts import service from '@zenstackhq/runtime'; -import { - authorize, - NextAuthAdapter as Adapter, -} from '@zenstackhq/runtime/auth'; +import { authorize, Adapter } from '@zenstackhq/next-auth'; import NextAuth, { type NextAuthOptions } from 'next-auth'; export const authOptions: NextAuthOptions = { @@ -68,6 +65,8 @@ export const authOptions: NextAuthOptions = { export default NextAuth(authOptions); ``` +Find more details [here](integrating-authentication.md) about integrating with different authentication schemes. + ## Using React hooks React hooks are generated for CRUD'ing each data model you defined. They save your time writing explicit HTTP requests to call the generated services. Internally the hooks use [SWR](https://swr.vercel.app/) for data fetching, so you'll also enjoy its built-in features, like caching, revalidation on interval, etc. diff --git a/docs/get-started/learning-the-zmodel-language.md b/docs/get-started/learning-the-zmodel-language.md deleted file mode 100644 index 27b01032e..000000000 --- a/docs/get-started/learning-the-zmodel-language.md +++ /dev/null @@ -1,445 +0,0 @@ -# Learning the ZModel Language - -ZModel is a declarative language for defining data models, relations and access policies. -ZModel is a superset of [Prisma's Schema Language](https://www.prisma.io/docs/concepts/components/prisma-schema), so if you're already familiar with Prisma, feel free to jump directly to the [Access Policies](#access-policies) section. Otherwise, don't worry. The syntax is intuitive and easy to learn. - -## Data source - -Every model needs to include exactly one `datasource` declaration, providing information on how to connect to the underlying databases. - -The recommended way is to load the connection string from an environment variable, like: - -```zmodel -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -} -``` - -Do not commit the `DATABASE_URL` value in source code; instead configure it in your deployment as an environment variable. - -## Data models - -Data models define the shapes of entities in your application domain. They include fields and attributes for attaching additional metadata. Data models are mapped to your database schema and used to generate CRUD services and front-end library code. - -Here's an example of a blog post model: - -```zmodel -model Post { - // the mandatory primary key of this model with a default UUID value - id String @id @default(uuid()) - - // fields can be DateTime - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - // or string - title String - - // or integer - viewCount Int @default(0) - - // and optional - content String? - - // and a list too - tags String[] -} -``` - -As you can see, fields are typed and can be a list or optional. Default values can be attached with the `@default` attribute. You can find all built-in types [here](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#model-field-scalar-types). - -Model fields can also be typed as other Models. We'll cover this in the [Relations](#relations) section. - -## Attributes - -Attributes attach additional metadata to models and fields. Some attributes take input parameters, and you can provide values by using literal expressions or calling attribute functions. - -Attributes attached to fields are prefixed with '@', and those to models are prefixed with '@@'. - -Here're some examples of commonly used attributes: - -```zmodel -model Post { - // @id is a field attribute, marking the field as a primary key - // @default is another field attribute for specifying a default value for the field if it's not given at creation time - // uuid() is a function for generating a UUID - id String @id @default(uuid()) - - // now() is a function that returns current time - createdAt DateTime @default(now()) - - // @updatedAt is a field attribute indicating its value should be updated to the current time whenever the model entity is updated - updatedAt DateTime @updatedAt - - // @unique adds uniqueness constraint to field - slug String @unique - - // @map can be used to give a different column name in database - title String @map("my_title") - - // @@map can be used to give a different table name in database - @@map("posts") - - // uniqueness constraint can also be expressed via @@unique model attribute, and you can combine multiple fields here - @@unique([slug]) - - // use @@index to specify fields to create database index for - @@index([slug]) -} -``` - -ZenStack inherits most attributes and functions from Prisma, and added a number of new ones: - -- `@password` - - A field attribute that marks a field as a password. Before storing such a field, ZenStack hashes its value with [bcryptjs](https://github.com/dcodeIO/bcrypt.js), with a default salt length of 12. - - You can override the default setting with the `saltLength` or `salt` named parameters, like: - -```zmodel -model User { - password String @password(saltLength: 16) -} - -model User { - password String @password(salt: "mysalt") -} -``` - -If both `saltLength` and `salt` parameters are provided, `salt` is used. - -- `@omit` - - A field attribute that marks a field to be excluded when model entities are read from the generated service. This is often used to prevent sensitive information from being returned to the front-end code (e.g., password, even hashed). - - E.g.: - -```zmodel -model User { - password String @password @omit -} -``` - -For attributes and functions inherited from Prisma, please refer to [Prisma's documentation](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#attributes) for details. - -## Relations - -The special `@relation` attribute expresses relations between data models. Here're some examples. - -- One-to-one - -```zmodel -model User { - id String @id - profile Profile? -} - -model Profile { - id String @id - user @relation(fields: [userId], references: [id]) - userId String @unique -} -``` - -- One-to-many - -```zmodel -model User { - id String @id - posts Post[] -} - -model Post { - id String @id - author User? @relation(fields: [authorId], references: [id]) - authorId String? -} -``` - -- Many-to-many - -```zmodel -model Space { - id String @id - members Membership[] -} - -// Membership is the "join-model" between User and Space -model Membership { - id String @id() - - // one-to-many from Space - space Space @relation(fields: [spaceId], references: [id]) - spaceId String - - // one-to-many from User - user User @relation(fields: [userId], references: [id]) - userId String - - // a user can be member of a space for only once - @@unique([userId, spaceId]) -} - -model User { - id String @id - membership Membership[] -} - -``` - -This document serves as a quick overview for starting with the ZModel language. For more thorough explanations about data modeling, please check out [Prisma's schema references](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference). - -## Access policies - -Access policies express authorization logic in a declarative way. They use `@@allow` and `@@deny` rules to specify the eligibility of an operation over a model entity. The signatures of the attributes are: - -```zmodel -@@allow(operation, condition) -@@deny(operation, condition) -``` - -, where `operation` can be of: "all", "read", "create", "update" and "delete" (or a comma-separated string of multiple values, like "create,update"), and `condition` must be a boolean expression. - -The logic of permitting/rejecting an operation is as follows: - -- By default, all operations are rejected if there isn't any @@allow rule in a model -- The operation is rejected if any of the conditions in @@deny rules evaluate to `true` -- Otherwise, the operation is permitted if any of the conditions in @@allow rules evaluate to `true` -- Otherwise, the operation is rejected - -### Using authentication in policy rules - -It's very common to use the current login user to verdict if an operation should be permitted. Therefore, ZenStack provides a built-in `auth()` attribute function that evaluates to the `User` entity corresponding to the current user. To use the function, your ZModel file must define a `User` data model. - -You can use `auth()` to: - -- Check if a user is logged in - -```zmodel -@@deny('all', auth() == null) -``` - -- Access user's fields - -```zmodel -@@allow('update', auth().role == 'ADMIN') -``` - -- Compare user identity - -```zmodel -// owner is a relation field to User model -@@allow('update', auth() == owner) -``` - -### A simple example with Post model - -```zmodel -model Post { - // reject all operations if user's not logged in - @@deny('all', auth() == null) - - // allow all operations if the entity's owner matches the current user - @@allow('all', auth() == owner) - - // posts are readable to anyone - @allow('read', true) -} -``` - -### A more complex example with multi-user spaces - -```zmodel -model Space { - id String @id - members Membership[] - owner User @relation(fields: [ownerId], references: [id]) - ownerId String - - // require login - @@deny('all', auth() == null) - - // everyone can create a space - @@allow('create', true) - - // owner can do everything - @@allow('all', auth() == owner) - - // any user in the space can read the space - // - // Here the ?[condition] syntax is called - // "Collection Predicate", used to check if any element - // in the "collection" matches the "condition" - @@allow('read', members?[user == auth()]) -} - -// Membership is the "join-model" between User and Space -model Membership { - id String @id() - - // one-to-many from Space - space Space @relation(fields: [spaceId], references: [id]) - spaceId String - - // one-to-many from User - user User @relation(fields: [userId], references: [id]) - userId String - - // a user can be member of a space for only once - @@unique([userId, spaceId]) - - // require login - @@deny('all', auth() == null) - - // space owner can create/update/delete - @@allow('create,update,delete', space.owner == auth()) - - // user can read entries for spaces which he's a member of - @@allow('read', space.members?[user == auth()]) -} - -model User { - id String @id - email String @unique - membership Membership[] - ownedSpaces Space[] - - // allow signup - @@allow('create', true) - - // user can do everything to herself; note that "this" represents - // the current entity - @@allow('all', auth() == this) - - // can be read by users sharing a space - @@allow('read', membership?[space.members?[user == auth()]]) -} - -``` - -### Accessing relation fields in policy - -As you've seen in the examples above, you can access fields from relations in policy expressions. For example, to express "a user can be read by any user sharing a space" in the `User` model, you can directly read into its `membership` field. - -```zmodel - @@allow('read', membership?[space.members?[user == auth()]]) -``` - -In most cases, when you use a "to-many" relation in a policy rule, you'll use "Collection Predicate" to express a condition. See [next section](#collection-predicate-expressions) for details. - -### Collection predicate expressions - -Collection predicate expressions are boolean expressions used to express conditions over a list. It's mainly designed for building policy rules for "to-many" relations. It has three forms of syntaxes: - -1. Any - - ``` - ?[condition] - ``` - - Any element in `collection` matches `condition` - -2. All - - ``` - ![condition] - ``` - - All elements in `collection` match `condition` - -3. None - - ``` - ^[condition] - ``` - - None element in `collection` matches `condition` - -The `condition` expression has direct access to fields defined in the model of `collection`. E.g.: - -```zmodel - @@allow('read', members?[user == auth()]) -``` - -, in condition `user == auth()`, `user` refers to the `user` field in model `Membership`, because the collection `members` is resolved to `Membership` model. - -Also, collection predicates can be nested to express complex conditions involving multi-level relation lookup. E.g.: - -```zmodel - @@allow('read', membership?[space.members?[user == auth()]]) -``` - -In this example, `user` refers to `user` field of `Membership` model because `space.members` is resolved to `Membership` model. - -### A complete example - -Please check out the [Collaborative Todo](../../samples/todo) for a complete example on using access policies. - -## Field constraints - -Field constraints are used for attaching constraints to field values. Unlike access policies, field constraints only apply on individual fields, and are only checked for 'create' and 'update' operations. - -Internally ZenStack uses [zod](https://github.com/colinhacks/zod) for validation. The checks are run in both the server-side CURD services and the clent-side React hooks. For the server side, upon validation error, HTTP 400 is returned with a body containing a `message` field for details. For the client side, a `ValidationError` is thrown. - -The following attributes can be used to attach field constraints: - -### String: - -- `@length(_ min: Int?, _ max: Int?)` - - Validates length of a string field. - -- `@startsWith(_ text: String)` - - Validates a string field value starts with the given text. - -- `@endsWith(_ text: String)` - - Validates a string field value ends with the given text. - -- `@email()` - - Validates a string field value is a valid email address. - -- `@url()` - - Validates a string field value is a valid url. - -- `@datetime()` - - Validates a string field value is a valid ISO datetime. - -- `@regex(_ regex: String)` - - Validates a string field value matches a regex. - -### Number: - -- `@gt(_ value: Int)` - - Validates a number field is greater than the given value. - -- `@gte(_ value: Int)` - - Validates a number field is greater than or equal to the given value. - -- `@lt(_ value: Int)` - - Validates a number field is less than the given value. - -- `@lte(_ value: Int)` - - Validates a number field is less than or equal to the given value. - -### Sample usage - -```zmodel -model User { - id String @id - handle String @regex("^[0-9a-zA-Z]{4,16}$") - email String @email @endsWith("@myorg.com") - profileImage String? @url - age Int @gt(0) -} -``` diff --git a/docs/get-started/next-js.md b/docs/get-started/next-js.md deleted file mode 100644 index 1387e9f5d..000000000 --- a/docs/get-started/next-js.md +++ /dev/null @@ -1,128 +0,0 @@ -# Getting started for Next.js - -## Create a new project from a starter - -The easiest way to start using ZenStack is by creating a new Next.js project from a preconfigured starter template. - -Here we demonstrate the process with a simple Blog starter using [Next-Auth](https://next-auth.js.org/) for user authentication. - -1. Make sure you have Node.js 16 or above and NPM 8 or above installed - -2. Create a new Next.js project from the ZenStack starter - -```bash -npx create-next-app --use-npm -e https://github.com/zenstackhq/nextjs-auth-starter [project name] - -cd [project name] -``` - -3. Run ZenStack generator to generate data services, auth adapter, and the client library - -```bash -npm run generate -``` - -4. Initialize your local DB and create the first migration - The starter is preconfigured with a local sqlite database. Run the following command to populate its schema and generates a migration history: - -```bash -npm run db:migrate -- -n init -``` - -5. Start the app - -```bash -npm run dev -``` - -If everything worked correctly, you should have a blog site where you can signup, author drafts, and publish them. Congratulations! In case anything broke, [reach out to us](#reach-out-to-us-for-issues-feedback-and-ideas), and we'll help. - -You can also try signing up multiple accounts and verify that drafts created by different users are isolated. - -Checkout [the starter's documentation](https://github.com/zenstackhq/nextjs-auth-starter#readme) for more details. - -## Add to an existing project - -1. Install the CLI and runtime - -```bash -npm i -D zenstack - -npm i @zenstackhq/runtime -``` - -2. Install [VSCode extension](https://marketplace.visualstudio.com/items?itemName=zenstack.zenstack) for authoring the model file - -3. Create a "zenstack" folder under your project root, and add a "schema.zmodel" file in it - -4. Configure database connection in "schema.model" - - Here's an example of using a Postgres database with connection string specified in `DATABASE_URL` environment variable: - -```zmodel -datasource db { - provider = 'postgresql' - url = env('DATABASE_URL') -} -``` - -5. Add models and define access policies as needed - -You can use the [sample model](https://github.com/zenstackhq/nextjs-auth-starter/blob/main/zenstack/schema.zmodel) in the start project as a reference. - -6. Generate server and client code from your model - -```bash -npx zenstack generate -``` - -7. Mount data-access API to endpoint - - Create file `pages/api/zenstack/[...path].ts`, with content: - -```ts -import { NextApiRequest, NextApiResponse } from 'next'; -import { - type RequestHandlerOptions, - requestHandler, -} from '@zenstackhq/runtime/server'; -import service from '@zenstackhq/runtime'; - -const options: RequestHandlerOptions = { - async getServerUser(req: NextApiRequest, res: NextApiResponse) { - // If you're using next-auth, current user can be fetched like: - // import { authOptions } from '@api/auth/[...nextauth]'; - // const session = await unstable_getServerSession(req, res, authOptions); - // return session?.user; - // - // Otherwise implement logic to return the user object for the current - // session. Database can be accessed with: "service.db". - }, -}; -export default requestHandler(service, options); -``` - -7. Initialize your local db and creates the first migration - -```bash -npm run db:migrate -- -n init -``` - -8. Start building your app by using the generated React hooks - E.g.: - -```jsx -import { usePost } from '@zenstackhq/runtime/hooks'; - -... - -const { get } = usePost(); -const posts = get({ where: { public: true } }); -return ( - <> - {posts?.map((post) => ( - - ))} - -); -``` diff --git a/docs/index.html b/docs/index.html index ede4b4cc5..65b47cac0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -2,7 +2,9 @@ - Welcome to ZenStack + + ZenStack - toolkit for building CRUD apps with Next.js + Typescript + - + - + - + diff --git a/docs/integrating-authentication.md b/docs/integrating-authentication.md index 035d153c2..bff6a3154 100644 --- a/docs/integrating-authentication.md +++ b/docs/integrating-authentication.md @@ -6,15 +6,17 @@ This documentation explains how to integrate ZenStack with popular authenticatio [NextAuth](https://next-auth.js.org/) is a comprehensive framework for implementating authentication. It offers a pluggable mechanism for configuring how user data is persisted. You can find a full example using ZenStack with NextAuth [here](https://github.com/zenstackhq/zenstack/tree/main/samples/todo ':target=blank'). -### Using generated adapter +ZenStack provides an extension package `@zenstackhq/next-auth` for integrating with NextAuth, which includes: -When `zenstack generate` runs, it generates an adapter for NextAuth if it finds the `next-auth` npm package is installed. The generated adapter can be configured to NextAuth as follows: +### Adapter + +Adapter is a NextAuth mechanism for hooking in custom persistence of auth related entities, like User, Account, etc. The ZenStack adapter can be configured to NextAuth as follows: ```ts // pages/api/auth/[...nextauth].ts import service from '@zenstackhq/runtime/server'; -import { NextAuthAdapter as Adapter } from '@zenstackhq/runtime/server/auth'; +import { Adapter } from '@zenstackhq/next-auth'; import NextAuth, { type NextAuthOptions } from 'next-auth'; export const authOptions: NextAuthOptions = { @@ -26,15 +28,15 @@ export const authOptions: NextAuthOptions = { export default NextAuth(authOptions); ``` -### Using generated `authorize` +### `authorize` helper -If you use [`CredentialsProvider`](https://next-auth.js.org/providers/credentials ':target=blank'), i.e. username/password based auth, you can also use the generated `authorize` function to implement how username/password is verified against the database: +If you use [`CredentialsProvider`](https://next-auth.js.org/providers/credentials ':target=blank'), i.e. email/password based auth, you can also use the `authorize` helper to implement how credentials are verified against the database: ```ts // pages/api/auth/[...nextauth].ts import service from '@zenstackhq/runtime/server'; -import { authorize } from '@zenstackhq/runtime/server/auth'; +import { authorize } from '@zenstackhq/next-auth'; import NextAuth, { type NextAuthOptions } from 'next-auth'; export const authOptions: NextAuthOptions = { diff --git a/docs/package-lock.json b/docs/package-lock.json new file mode 100644 index 000000000..02616276b --- /dev/null +++ b/docs/package-lock.json @@ -0,0 +1,3029 @@ +{ + "name": "zenstack-docs", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "zenstack-docs", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "ora": "^6.1.2" + }, + "devDependencies": { + "copyfiles": "^2.4.1", + "globby": "^13.1.2", + "puppeteer": "^19.4.0", + "rimraf": "^3.0.2", + "sitemap": "^7.1.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "dev": true + }, + "node_modules/@types/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", + "dev": true, + "dependencies": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + }, + "bin": { + "copyfiles": "copyfiles", + "copyup": "copyfiles" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", + "integrity": "sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==", + "dev": true, + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dev": true, + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1068969", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1068969.tgz", + "integrity": "sha512-ATFTrPbY1dKYhPPvpjtwWKSK2mIwGmRwX54UASn9THEuIZCe2n9k3vVuMmt6jWeL+e5QaaguEv/pMyR+JQB7VQ==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "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" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", + "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", + "dev": true, + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "dependencies": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + } + }, + "node_modules/noms/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/noms/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/ora/-/ora-6.1.2.tgz", + "integrity": "sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==", + "dependencies": { + "bl": "^5.0.0", + "chalk": "^5.0.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.6.1", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.1.0", + "log-symbols": "^5.1.0", + "strip-ansi": "^7.0.1", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/ora/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/puppeteer": { + "version": "19.4.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-19.4.0.tgz", + "integrity": "sha512-sRzWEfFSZCCcFUJflGtYI2V7A6qK4Jht+2JiI2LZgn+Nv/LOZZsBDEaGl98ZrS8oEcUA5on4p2yJbE0nzHNzIg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "cosmiconfig": "8.0.0", + "devtools-protocol": "0.0.1068969", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "puppeteer-core": "19.4.0" + }, + "engines": { + "node": ">=14.1.0" + } + }, + "node_modules/puppeteer-core": { + "version": "19.4.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.4.0.tgz", + "integrity": "sha512-gG/jxseleZStinBn86x8r7trjcE4jcjx1hIQWOpACQhquHYMuKnrWxkzg+EDn8sN3wUtF/Ry9mtJgjM49oUOFQ==", + "dev": true, + "dependencies": { + "cross-fetch": "3.1.5", + "debug": "4.3.4", + "devtools-protocol": "0.0.1068969", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.10.0" + }, + "engines": { + "node": ">=14.1.0" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/sitemap": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", + "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", + "dev": true, + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=12.0.0", + "npm": ">=5.6.0" + } + }, + "node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz", + "integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "dev": true + }, + "@types/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "requires": { + "restore-cursor": "^4.0.0" + } + }, + "cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==" + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", + "dev": true, + "requires": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cosmiconfig": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", + "integrity": "sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ==", + "dev": true, + "requires": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + } + }, + "cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dev": true, + "requires": { + "node-fetch": "2.6.7" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "requires": { + "clone": "^1.0.2" + } + }, + "devtools-protocol": { + "version": "0.0.1068969", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1068969.tgz", + "integrity": "sha512-ATFTrPbY1dKYhPPvpjtwWKSK2mIwGmRwX54UASn9THEuIZCe2n9k3vVuMmt6jWeL+e5QaaguEv/pMyR+JQB7VQ==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@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" + } + }, + "fastq": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globby": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.2.tgz", + "integrity": "sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==", + "dev": true, + "requires": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.11", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^4.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "requires": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "dependencies": { + "chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==" + } + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true + } + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "ora": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/ora/-/ora-6.1.2.tgz", + "integrity": "sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==", + "requires": { + "bl": "^5.0.0", + "chalk": "^5.0.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.6.1", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.1.0", + "log-symbols": "^5.1.0", + "strip-ansi": "^7.0.1", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "requires": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==" + } + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "puppeteer": { + "version": "19.4.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-19.4.0.tgz", + "integrity": "sha512-sRzWEfFSZCCcFUJflGtYI2V7A6qK4Jht+2JiI2LZgn+Nv/LOZZsBDEaGl98ZrS8oEcUA5on4p2yJbE0nzHNzIg==", + "dev": true, + "requires": { + "cosmiconfig": "8.0.0", + "devtools-protocol": "0.0.1068969", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "puppeteer-core": "19.4.0" + } + }, + "puppeteer-core": { + "version": "19.4.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.4.0.tgz", + "integrity": "sha512-gG/jxseleZStinBn86x8r7trjcE4jcjx1hIQWOpACQhquHYMuKnrWxkzg+EDn8sN3wUtF/Ry9mtJgjM49oUOFQ==", + "dev": true, + "requires": { + "cross-fetch": "3.1.5", + "debug": "4.3.4", + "devtools-protocol": "0.0.1068969", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.10.0" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "sitemap": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", + "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", + "dev": true, + "requires": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.2.4" + } + }, + "slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "requires": { + "defaults": "^1.0.3" + } + }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "ws": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.10.0.tgz", + "integrity": "sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==", + "dev": true, + "requires": {} + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 000000000..16ae28b32 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,30 @@ +{ + "name": "zenstack-docs", + "version": "1.0.0", + "description": "ZenStack documentation site", + "type": "module", + "scripts": { + "serve": "docsify serve -p 8765", + "copy-static": "mkdir -p ../doc-serve/public/static && copyfiles -e node_modules ./* ./**/* ../doc-serve/public", + "build": "rimraf ../doc-serve/public && npm run copy-static && node script/ssg.js && node script/sitemap.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/zenstackhq/zenstack.git" + }, + "author": "ZenStack Team", + "license": "MIT", + "bugs": { + "url": "https://github.com/zenstackhq/zenstack/issues" + }, + "homepage": "https://zenstack.dev", + "devDependencies": { + "globby": "^13.1.2", + "puppeteer": "^19.4.0", + "rimraf": "^3.0.2", + "sitemap": "^7.1.1" + }, + "dependencies": { + "ora": "^6.1.2" + } +} diff --git a/docs/robots.txt b/docs/robots.txt new file mode 100644 index 000000000..c2a49f4fb --- /dev/null +++ b/docs/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Allow: / diff --git a/docs/runtime-api.md b/docs/runtime-api.md index 42282bf84..07d7b4833 100644 --- a/docs/runtime-api.md +++ b/docs/runtime-api.md @@ -157,7 +157,7 @@ The server-side CRUD APIs have similar signature with client-side hooks, except - create ```ts - async find( + async create( context: QueryContext, args?: UserCreateArgs ): Promise; @@ -166,7 +166,7 @@ The server-side CRUD APIs have similar signature with client-side hooks, except - update ```ts - async get( + async update( context: QueryContext, id: string, args?: UserUpdateArgs @@ -175,7 +175,7 @@ The server-side CRUD APIs have similar signature with client-side hooks, except - del ```ts - async get( + async del( context: QueryContext, id: string, args?: UserDeleteArgs diff --git a/docs/script/sitemap.js b/docs/script/sitemap.js new file mode 100644 index 000000000..cd9ee52cd --- /dev/null +++ b/docs/script/sitemap.js @@ -0,0 +1,25 @@ +import { globbySync } from 'globby'; +import { SitemapStream, streamToPromise } from 'sitemap'; +import { Readable } from 'stream'; +import fs from 'fs'; + +const links = [ + { url: '/', changefreq: 'daily' }, + { url: '/changelog', changefreq: 'daily' }, + ...globbySync(['./**/[!_]?*.md', '!node_modules', '!README.md']).map( + (path) => ({ + url: `/${path.replace('.md', '')}`, + changefreq: 'daily', + }) + ), +]; + +console.log('Sitemap entries:'); +console.log(links); + +const stream = new SitemapStream({ hostname: 'https://zenstack.dev' }); +const content = ( + await streamToPromise(Readable.from(links).pipe(stream)) +).toString('utf-8'); + +fs.writeFileSync('../doc-serve/public/sitemap.xml', content); diff --git a/docs/script/ssg.js b/docs/script/ssg.js new file mode 100644 index 000000000..70b1ea7aa --- /dev/null +++ b/docs/script/ssg.js @@ -0,0 +1,38 @@ +import puppeteer from 'puppeteer'; +import { globbySync } from 'globby'; +import fs from 'fs'; +import ora from 'ora'; + +const siteUrl = 'http://localhost:8765'; + +const urls = [ + { route: 'index', url: `${siteUrl}/` }, + { route: 'changelog', url: `${siteUrl}/changelog` }, + ...globbySync(['./**/[!_]?*.md', '!node_modules', '!README.md']).map( + (path) => ({ + route: path.replace('.md', ''), + url: `${siteUrl}/${path.replace('.md', '')}`, + }) + ), +]; + +console.log('Generating static content for', urls.length, 'urls'); +const browser = await puppeteer.launch(); + +for (let i = 0; i < urls.length; i++) { + const { url, route } = urls[i]; + const spinner = ora(`${i + 1}/${urls.length}\tGenerating ${url}`).start(); + const page = await browser.newPage(); + + await page.goto(url); + await page.waitForNetworkIdle({ idleTime: 2000, timeout: 5000 }); + await page.evaluate( + "document.querySelectorAll('script').forEach(e => e.remove())" + ); + const content = await page.content(); + fs.writeFileSync(`../doc-serve/public/static/${route}.html`, content); + spinner.succeed(); + await page.close(); +} + +await browser.close(); diff --git a/docs/zh-cn/README.md b/docs/zh-cn/README.md deleted file mode 100644 index 47fa08e73..000000000 --- a/docs/zh-cn/README.md +++ /dev/null @@ -1,3 +0,0 @@ -暂时还没顾上翻译。。。 - -如果你有兴趣帮忙的话,非常欢迎[联系我们](mailto:contact@zenstack.dev)! diff --git a/docs/zmodel-attribute.md b/docs/zmodel-attribute.md index d93ad17b8..3a9c26be8 100644 --- a/docs/zmodel-attribute.md +++ b/docs/zmodel-attribute.md @@ -445,7 +445,7 @@ You can find a list of predefined attribute functions [here](#predefined-attribu function auth(): User {} ``` - Gets thec current login user. The return type of the function is the `User` data model defined in the current ZModel. + Gets the current login user. The return type of the function is the `User` data model defined in the current ZModel. ## Examples diff --git a/package.json b/package.json index 72f5b396d..a247b9790 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-monorepo", - "version": "0.4.0", + "version": "0.5.0", "description": "", "scripts": { "build": "pnpm -r build", diff --git a/packages/next-auth/.eslintrc.json b/packages/next-auth/.eslintrc.json new file mode 100644 index 000000000..0a913e874 --- /dev/null +++ b/packages/next-auth/.eslintrc.json @@ -0,0 +1,14 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "plugins": ["@typescript-eslint"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ] +} diff --git a/packages/next-auth/README.md b/packages/next-auth/README.md new file mode 100644 index 000000000..b9ae1045b --- /dev/null +++ b/packages/next-auth/README.md @@ -0,0 +1,5 @@ +# ZenStack Runtime Library + +This package is for integrating [next-auth](https://next-auth.js.org/) with ZenStack. + +Visit [Homepage](https://zenstack.dev) for more details. diff --git a/packages/next-auth/package.json b/packages/next-auth/package.json new file mode 100644 index 000000000..684f0a78a --- /dev/null +++ b/packages/next-auth/package.json @@ -0,0 +1,46 @@ +{ + "name": "@zenstackhq/next-auth", + "displayName": "ZenStack next-auth integration library", + "version": "0.5.0", + "description": "ZenStack adapter for integrating with next-auth", + "repository": { + "type": "git", + "url": "https://github.com/zenstackhq/zenstack" + }, + "main": "index.js", + "scripts": { + "clean": "rimraf dist", + "build": "pnpm lint && pnpm clean && tsc && cp ./package.json ./README.md dist/", + "watch": "tsc --watch", + "lint": "eslint src --ext ts", + "prepublishOnly": "pnpm build", + "publish-dev": "pnpm publish --tag dev" + }, + "publishConfig": { + "directory": "dist", + "linkDirectory": true + }, + "author": { + "name": "ZenStack Team" + }, + "homepage": "https://zenstack.dev", + "license": "MIT", + "keywords": [ + "zenstack", + "next-auth" + ], + "dependencies": { + "@next-auth/prisma-adapter": "^1.0.5", + "@zenstackhq/runtime": "workspace:*", + "bcryptjs": "^2.4.3" + }, + "devDependencies": { + "@types/bcryptjs": "^2.4.2", + "next-auth": "^4.0.0", + "rimraf": "^3.0.2", + "typescript": "^4.9.3" + }, + "peerDependencies": { + "next-auth": "^4.0.0" + } +} diff --git a/packages/next-auth/src/adapter.ts b/packages/next-auth/src/adapter.ts new file mode 100644 index 000000000..9b347eeaa --- /dev/null +++ b/packages/next-auth/src/adapter.ts @@ -0,0 +1,11 @@ +import { Adapter } from 'next-auth/adapters'; +import type { Service } from '@zenstackhq/runtime/server'; +import { PrismaAdapter } from '@next-auth/prisma-adapter'; + +/** + * Next-auth adapter for reading and persisting auth entities + * @param service ZenStack service + */ +export function Adapter(service: Service): Adapter { + return PrismaAdapter(service.db); +} diff --git a/packages/next-auth/src/authorize.ts b/packages/next-auth/src/authorize.ts new file mode 100644 index 000000000..0f8e4ddc2 --- /dev/null +++ b/packages/next-auth/src/authorize.ts @@ -0,0 +1,59 @@ +import { Service } from '@zenstackhq/runtime/server'; +import { compare } from 'bcryptjs'; + +async function verifyPassword(password: string, hashedPassword: string) { + return compare(password, hashedPassword); +} + +export class AuthorizeError extends Error { + constructor(message: string) { + super(message); + } +} + +export function authorize(service: Service) { + return async ( + credentials: Record<'email' | 'password', string> | undefined + ) => { + if (!credentials) { + throw new AuthorizeError('Missing credentials'); + } + + if (!credentials.email) { + throw new AuthorizeError('"email" is required in credentials'); + } + + if (!credentials.password) { + throw new AuthorizeError('"password" is required in credentials'); + } + + const maybeUser = await service.db.user.findFirst({ + where: { + email: credentials.email, + }, + select: { + id: true, + email: true, + password: true, + }, + }); + + if (!maybeUser || !maybeUser.password) { + return null; + } + + const isValid = await verifyPassword( + credentials.password, + maybeUser.password + ); + + if (!isValid) { + return null; + } + + return { + id: maybeUser.id, + email: maybeUser.email, + }; + }; +} diff --git a/packages/next-auth/src/index.ts b/packages/next-auth/src/index.ts new file mode 100644 index 000000000..802ff07f9 --- /dev/null +++ b/packages/next-auth/src/index.ts @@ -0,0 +1,2 @@ +export * from './adapter'; +export * from './authorize'; diff --git a/packages/next-auth/tsconfig.json b/packages/next-auth/tsconfig.json new file mode 100644 index 000000000..36d8bdce1 --- /dev/null +++ b/packages/next-auth/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "CommonJS", + "lib": ["ESNext"], + "sourceMap": true, + "outDir": "dist", + "strict": true, + "noUnusedLocals": true, + "noImplicitReturns": true, + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "resolveJsonModule": true, + "strictPropertyInitialization": false, + "paths": {} + }, + "include": ["src/**/*.ts"], + "exclude": ["dist", "node_modules"] +} diff --git a/packages/runtime/README.md b/packages/runtime/README.md index 453a79769..a5cd746fa 100644 --- a/packages/runtime/README.md +++ b/packages/runtime/README.md @@ -2,4 +2,4 @@ This package is the runtime library supporting web apps built using ZenStack. -Visit [Homepage](https://github.com/zenstackhq/zenstack#readme) for more details. +Visit [Homepage](https://zenstack.dev) for more details. diff --git a/packages/runtime/package.json b/packages/runtime/package.json index e754cda8a..e731e21c5 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/runtime", "displayName": "ZenStack Runtime Library", - "version": "0.4.0", + "version": "0.5.0", "description": "Runtime of ZenStack for both client-side and server-side environments.", "repository": { "type": "git", @@ -9,7 +9,7 @@ }, "scripts": { "clean": "rimraf dist", - "build": "npm run clean && tsc && cp -r pre/* dist/ && cp ./package.json dist/", + "build": "pnpm lint && pnpm clean && tsc && cp -r pre/* dist/ && cp ./package.json ./README.md dist/", "watch": "tsc --watch", "lint": "eslint src --ext ts", "prepublishOnly": "pnpm build", @@ -20,14 +20,15 @@ "linkDirectory": true }, "dependencies": { + "@types/bcryptjs": "^2.4.2", + "bcryptjs": "^2.4.3", "colors": "1.4.0", "cuid": "^2.1.8", "decimal.js": "^10.4.2", "deepcopy": "^2.1.0", + "superjson": "^1.11.0", "swr": "^1.3.0", "tslib": "^2.4.1", - "@types/bcryptjs": "^2.4.2", - "bcryptjs": "^2.4.3", "zod": "^3.19.1", "zod-validation-error": "^0.2.1" }, @@ -39,6 +40,7 @@ "author": { "name": "ZenStack Team" }, + "homepage": "https://zenstack.dev", "license": "MIT", "devDependencies": { "@types/bcryptjs": "^2.4.2", diff --git a/packages/runtime/pre/server/index.d.ts b/packages/runtime/pre/server/index.d.ts index 13bc9471d..76946d7b4 100644 --- a/packages/runtime/pre/server/index.d.ts +++ b/packages/runtime/pre/server/index.d.ts @@ -6,6 +6,8 @@ export type { PolicyOperationKind, RuntimeAttribute, QueryContext, + Service, + DbClientContract, } from '../lib/types'; export { diff --git a/packages/runtime/src/handler/data/crud.ts b/packages/runtime/src/handler/data/crud.ts index 4d6a6a7d7..a2a999785 100644 --- a/packages/runtime/src/handler/data/crud.ts +++ b/packages/runtime/src/handler/data/crud.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import cuid from 'cuid'; +import superjson from 'superjson'; import { TRANSACTION_FIELD_NAME } from '../../constants'; import { DbClientContract, @@ -122,7 +123,9 @@ export class CRUD { // conduct the create this.service.verbose( - `Conducting create: ${model}:\n${JSON.stringify(args)}` + `Conducting create: ${model}:\n${superjson.stringify( + args + )}` ); const createResult = (await tx[model].create(args)) as { id: string; @@ -245,7 +248,9 @@ export class CRUD { // conduct the update this.service.verbose( - `Conducting update: ${model}:\n${JSON.stringify(args)}` + `Conducting update: ${model}:\n${superjson.stringify( + args + )}` ); await tx[model].update(args); @@ -356,7 +361,9 @@ export class CRUD { // conduct the deletion this.service.verbose( - `Conducting delete ${model}:\n${JSON.stringify(args)}` + `Conducting delete ${model}:\n${superjson.stringify( + args + )}` ); await tx[model].delete(args); diff --git a/packages/runtime/src/handler/data/handler.ts b/packages/runtime/src/handler/data/handler.ts index baab57bd5..7c8c8caf9 100644 --- a/packages/runtime/src/handler/data/handler.ts +++ b/packages/runtime/src/handler/data/handler.ts @@ -1,14 +1,18 @@ import { NextApiRequest, NextApiResponse } from 'next'; +import superjson from 'superjson'; import { RequestHandlerOptions } from '../../request-handler'; +import { registerSerializers } from '../../serialization-utils'; import { DbClientContract, QueryContext, ServerErrorCode, Service, } from '../../types'; -import { RequestHandler, CRUDError } from '../types'; +import { CRUDError, RequestHandler } from '../types'; import { CRUD } from './crud'; +registerSerializers(); + /** * Request handler for /data endpoint which processes data CRUD requests. */ @@ -36,7 +40,9 @@ export default class DataHandler this.service.verbose(`Data request: ${method} ${path}`); if (req.body) { - this.service.verbose(`Request body: ${JSON.stringify(req.body)}`); + this.service.verbose( + `Request body: ${superjson.stringify(req.body)}` + ); } try { @@ -100,6 +106,18 @@ export default class DataHandler } } + private marshal(value: unknown) { + return JSON.parse(superjson.stringify(value)); + } + + private unmarshal(value: unknown) { + if (typeof value === 'string') { + return superjson.parse(value); + } else { + return superjson.parse(JSON.stringify(value)); + } + } + private async get( req: NextApiRequest, res: NextApiResponse, @@ -108,7 +126,7 @@ export default class DataHandler context: QueryContext ) { // parse additional query args from "q" parameter - const args = req.query.q ? JSON.parse(req.query.q as string) : {}; + const args = req.query.q ? this.unmarshal(req.query.q as string) : {}; if (id) { // GET /:id, make sure "id" is injected @@ -116,11 +134,11 @@ export default class DataHandler if (!result) { throw new CRUDError(ServerErrorCode.ENTITY_NOT_FOUND); } - res.status(200).send(result); + res.status(200).send(this.marshal(result)); } else { // GET /, get list const result = await this.crud.find(model, args, context); - res.status(200).send(result); + res.status(200).send(this.marshal(result)); } } @@ -130,8 +148,12 @@ export default class DataHandler model: string, context: QueryContext ) { - const result = await this.crud.create(model, req.body, context); - res.status(201).send(result); + const result = await this.crud.create( + model, + this.unmarshal(req.body), + context + ); + res.status(201).send(this.marshal(result)); } private async put( @@ -148,8 +170,13 @@ export default class DataHandler ); } - const result = await this.crud.update(model, id, req.body, context); - res.status(200).send(result); + const result = await this.crud.update( + model, + id, + this.unmarshal(req.body), + context + ); + res.status(200).send(this.marshal(result)); } private async del( @@ -166,8 +193,8 @@ export default class DataHandler ); } - const args = req.query.q ? JSON.parse(req.query.q as string) : {}; + const args = req.query.q ? this.unmarshal(req.query.q as string) : {}; const result = await this.crud.del(model, id, args, context); - res.status(200).send(result); + res.status(200).send(this.marshal(result)); } } diff --git a/packages/runtime/src/handler/data/policy-utils.ts b/packages/runtime/src/handler/data/policy-utils.ts index 6cd6e120e..a982aeb2c 100644 --- a/packages/runtime/src/handler/data/policy-utils.ts +++ b/packages/runtime/src/handler/data/policy-utils.ts @@ -2,6 +2,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { hashSync } from 'bcryptjs'; import deepcopy from 'deepcopy'; +import superjson from 'superjson'; import { DEFAULT_PASSWORD_SALT_LENGTH, GUARD_FIELD_NAME, @@ -15,7 +16,7 @@ import { ServerErrorCode, Service, } from '../../types'; -import { PrismaWriteActionType, CRUDError } from '../types'; +import { CRUDError, PrismaWriteActionType } from '../types'; import { NestedWriteVisitor } from './nested-write-vistor'; //#region General helpers @@ -103,7 +104,7 @@ export async function readWithCheck( await injectNestedReadConditions(model, args, service, context); service.verbose( - `Reading with validation for ${model}: ${JSON.stringify(args)}` + `Reading with validation for ${model}: ${superjson.stringify(args)}` ); const result = await db[model].findMany(args); @@ -187,40 +188,6 @@ async function postProcessForRead( if (await shouldOmit(service, model, field)) { delete entityData[field]; } - - const fieldValue = entityData[field]; - - if (typeof fieldValue === 'bigint') { - // serialize BigInt with typing info - entityData[field] = { - type: 'BigInt', - data: fieldValue.toString(), - }; - } - - if (fieldValue instanceof Date) { - // serialize Date with typing info - entityData[field] = { - type: 'Date', - data: fieldValue.toISOString(), - }; - } - - if (typeof fieldValue === 'object') { - const fieldInfo = await service.resolveField(model, field); - if (fieldInfo?.type === 'Decimal') { - // serialize Decimal with typing info - entityData[field] = { - type: 'Decimal', - data: fieldValue.toString(), - }; - } else if (fieldInfo?.type === 'Bytes') { - entityData[field] = { - type: 'Bytes', - data: Array.from(fieldValue as Buffer), - }; - } - } } const injectTarget = args.select ?? args.include; @@ -462,15 +429,15 @@ async function checkPolicyForSelectionPath( const query = buildChainedSelectQuery(id, selectionPath); service.verbose( - `Query for selection path: model ${model}, path ${JSON.stringify( + `Query for selection path: model ${model}, path ${superjson.stringify( selectionPath - )}, query ${JSON.stringify(query)}` + )}, query ${superjson.stringify(query)}` ); const r = await db[model].findUnique(query); // collect ids at the end of the path const ids: string[] = collectTerminalEntityIds(selectionPath, r); - service.verbose(`Collected leaf ids: ${JSON.stringify(ids)}`); + service.verbose(`Collected leaf ids: ${superjson.stringify(ids)}`); if (ids.length === 0) { return; diff --git a/packages/runtime/src/request.ts b/packages/runtime/src/request.ts index b5984beb4..ec9d9c99d 100644 --- a/packages/runtime/src/request.ts +++ b/packages/runtime/src/request.ts @@ -1,71 +1,15 @@ -import Decimal from 'decimal.js'; +import superjson from 'superjson'; import useSWR, { useSWRConfig } from 'swr'; import type { MutatorCallback, MutatorOptions, SWRResponse, } from 'swr/dist/types'; +import { registerSerializers } from './serialization-utils'; import { RequestOptions } from './types'; -type BufferShape = { type: 'Buffer'; data: number[] }; -function isBuffer(value: unknown): value is BufferShape { - return ( - !!value && - (value as BufferShape).type === 'Buffer' && - Array.isArray((value as BufferShape).data) - ); -} - -type BigIntShape = { type: 'BigInt'; data: string }; -function isBigInt(value: unknown): value is BigIntShape { - return ( - !!value && - (value as BigIntShape).type === 'BigInt' && - typeof (value as BigIntShape).data === 'string' - ); -} - -type DateShape = { type: 'Date'; data: string }; -function isDate(value: unknown): value is BigIntShape { - return ( - !!value && - (value as DateShape).type === 'Date' && - typeof (value as DateShape).data === 'string' - ); -} - -type DecmalShape = { type: 'Decimal'; data: string }; -function isDecimal(value: unknown): value is DecmalShape { - return ( - !!value && - (value as DecmalShape).type === 'Decimal' && - typeof (value as DateShape).data === 'string' - ); -} - -const dataReviver = (key: string, value: unknown) => { - // Buffer - if (isBuffer(value)) { - return Buffer.from(value.data); - } - - // BigInt - if (isBigInt(value)) { - return BigInt(value.data); - } - - // Date - if (isDate(value)) { - return new Date(value.data); - } - - // Decimal - if (isDecimal(value)) { - return new Decimal(value.data); - } - - return value; -}; +// register superjson custom serializers +registerSerializers(); const fetcher = async (url: string, options?: RequestInit) => { const res = await fetch(url, options); @@ -79,24 +23,32 @@ const fetcher = async (url: string, options?: RequestInit) => { } const textResult = await res.text(); - console.log; try { - return JSON.parse(textResult, dataReviver); + return unmarshal(textResult); } catch (err) { console.error(`Unable to deserialize data:`, textResult); throw err; } }; +function marshal(value: unknown) { + return superjson.stringify(value); +} + +function unmarshal(value: string) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return superjson.parse(value); +} + function makeUrl(url: string, args: unknown) { - return args ? url + `?q=${encodeURIComponent(JSON.stringify(args))}` : url; + return args ? url + `?q=${encodeURIComponent(marshal(args))}` : url; } /** * Makes a GET request with SWR. * * @param url The request URL. - * @param args The request args object, which will be JSON-stringified and appended as "?q=" parameter + * @param args The request args object, which will be superjson-stringified and appended as "?q=" parameter * @returns SWR response */ // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -111,6 +63,13 @@ export function get( }); } +/** + * Makes a POST request. + * + * @param url The request URL. + * @param data The request data. + * @param mutate Mutator for invalidating cache. + */ export async function post( url: string, data: Data, @@ -121,12 +80,19 @@ export async function post( headers: { 'content-type': 'application/json', }, - body: JSON.stringify(data), + body: marshal(data), }); mutate(url, true); return r; } +/** + * Makes a PUT request. + * + * @param url The request URL. + * @param data The request data. + * @param mutate Mutator for invalidating cache. + */ export async function put( url: string, data: Data, @@ -137,12 +103,19 @@ export async function put( headers: { 'content-type': 'application/json', }, - body: JSON.stringify(data), + body: marshal(data), }); mutate(url, true); return r; } +/** + * Makes a DELETE request. + * + * @param url The request URL. + * @param args The request args object, which will be superjson-stringified and appended as "?q=" parameter + * @param mutate Mutator for invalidating cache. + */ export async function del( url: string, args: unknown, diff --git a/packages/runtime/src/serialization-utils.ts b/packages/runtime/src/serialization-utils.ts new file mode 100644 index 000000000..15442900b --- /dev/null +++ b/packages/runtime/src/serialization-utils.ts @@ -0,0 +1,21 @@ +import Decimal from 'decimal.js'; +import superjson from 'superjson'; + +export function registerSerializers() { + superjson.registerCustom( + { + isApplicable: (v): v is Buffer => Buffer.isBuffer(v), + serialize: (v) => JSON.stringify(v.toJSON().data), + deserialize: (v) => Buffer.from(JSON.parse(v)), + }, + 'Buffer' + ); + superjson.registerCustom( + { + isApplicable: (v): v is Decimal => Decimal.isDecimal(v), + serialize: (v) => v.toJSON(), + deserialize: (v) => new Decimal(v), + }, + 'decimal.js' + ); +} diff --git a/packages/schema/build/env-plugin.js b/packages/schema/build/env-plugin.js index 78b17385d..bb4e2c173 100644 --- a/packages/schema/build/env-plugin.js +++ b/packages/schema/build/env-plugin.js @@ -12,19 +12,27 @@ module.exports = { function _findEnvFile(dir) { if (!fs.existsSync(dir)) return undefined; - if (fs.existsSync(`${dir}/.env.${ENV}`)) { - return `${dir}/.env.${ENV}`; - } else if (fs.existsSync(`${dir}/.env`)) { - return `${dir}/.env`; - } else { - const next = path.resolve(dir, '../'); - if (next === dir) { - // at root now, exit - return undefined; - } else { - return _findEnvFile(next); + const candidates = [ + `${dir}/.env.${ENV}.local`, + `${dir}/.env.${ENV}`, + `${dir}/.env.local`, + `${dir}/.env`, + ]; + + for (const candidate of candidates) { + if (fs.existsSync(candidate)) { + console.log('Using env from:', candidate); + return candidate; } } + + const next = path.resolve(dir, '../'); + if (next === dir) { + // at root now, exit + return undefined; + } else { + return _findEnvFile(next); + } } build.onResolve({ filter: /^env$/ }, async (args) => { diff --git a/packages/schema/package.json b/packages/schema/package.json index a7418f642..d32890a51 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -2,11 +2,12 @@ "name": "zenstack", "publisher": "zenstack", "displayName": "ZenStack Language Tools", - "description": "A toolkit for modeling data and access policies in full-stack development with Next.js and Typescript", - "version": "0.4.0", + "description": "A toolkit for building secure CRUD apps with Next.js + Typescript", + "version": "0.5.0", "author": { "name": "ZenStack Team" }, + "homepage": "https://zenstack.dev", "license": "MIT", "keywords": [ "fullstack", @@ -93,6 +94,7 @@ "langium": "^0.5.0", "mixpanel": "^0.17.0", "node-machine-id": "^1.1.12", + "ora": "^6.1.2", "pluralize": "^8.0.0", "prisma": "~4.7.0", "promisify": "^0.0.3", diff --git a/packages/schema/src/generator/field-constraint/index.ts b/packages/schema/src/generator/field-constraint/index.ts index c3271d8d0..35d023722 100644 --- a/packages/schema/src/generator/field-constraint/index.ts +++ b/packages/schema/src/generator/field-constraint/index.ts @@ -1,7 +1,3 @@ -import { Context, Generator } from '../types'; -import { Project, SourceFile } from 'ts-morph'; -import * as path from 'path'; -import colors from 'colors'; import { DataModel, DataModelField, @@ -10,6 +6,9 @@ import { isLiteralExpr, LiteralExpr, } from '@lang/generated/ast'; +import * as path from 'path'; +import { Project, SourceFile } from 'ts-morph'; +import { Context, Generator } from '../types'; /** * Generates field constraint validators (run on both client and server side) @@ -19,7 +18,15 @@ export default class FieldConstraintGenerator implements Generator { return 'field-constraint'; } - async generate(context: Context): Promise { + get startMessage() { + return 'Generating field constraints...'; + } + + get successMessage() { + return 'Successfully generated field constraints'; + } + + async generate(context: Context) { const project = new Project(); const sf = project.createSourceFile( path.join( @@ -41,7 +48,7 @@ export default class FieldConstraintGenerator implements Generator { sf.formatText(); await project.save(); - console.log(colors.blue(` ✔️ Field constraint validators generated`)); + return []; } private generateConstraints(sf: SourceFile, model: DataModel) { diff --git a/packages/schema/src/generator/index.ts b/packages/schema/src/generator/index.ts index 23265586f..ff01c6ac8 100644 --- a/packages/schema/src/generator/index.ts +++ b/packages/schema/src/generator/index.ts @@ -1,14 +1,14 @@ /* eslint-disable @typescript-eslint/no-var-requires */ -import { Context } from './types'; +import { Context, Generator } from './types'; import * as fs from 'fs'; import colors from 'colors'; import PrismaGenerator from './prisma'; import ServiceGenerator from './service'; import ReactHooksGenerator from './react-hooks'; -import NextAuthGenerator from './next-auth'; import { TypescriptCompilation } from './tsc'; import FieldConstraintGenerator from './field-constraint'; import telemetry from '../telemetry'; +import ora from 'ora'; /** * ZenStack code generator @@ -38,19 +38,19 @@ export class ZenStackGenerator { fs.mkdirSync(context.generatedCodeDir); } - const version = require('../../package.json').version; - console.log(colors.bold(`⌛️ Running ZenStack generator v${version}`)); - // TODO: plugin mechanism - const generators = [ + const generators: Generator[] = [ new PrismaGenerator(), new ServiceGenerator(), new ReactHooksGenerator(), - new NextAuthGenerator(), new FieldConstraintGenerator(), new TypescriptCompilation(), ]; + const version = require('../../package.json').version; + console.log(colors.bold(`⌛️ Running ZenStack generator v${version}`)); + + const warnings: string[] = []; for (const generator of generators) { if ( includeGenerators && @@ -59,6 +59,7 @@ export class ZenStackGenerator { continue; } + const spinner = ora(generator.startMessage).start(); await telemetry.trackSpan( 'cli:generator:start', 'cli:generator:complete', @@ -66,8 +67,12 @@ export class ZenStackGenerator { { generator: generator.name, }, - () => generator.generate(context) + async () => { + const genWarnings = await generator.generate(context); + warnings.push(...genWarnings); + } ); + spinner.succeed(`${colors.cyan(generator.successMessage)}`); } console.log( @@ -75,5 +80,7 @@ export class ZenStackGenerator { colors.bold('👻 All generators completed successfully!') ) ); + + warnings.forEach((w) => console.warn(colors.yellow(w))); } } diff --git a/packages/schema/src/generator/next-auth/index.ts b/packages/schema/src/generator/next-auth/index.ts deleted file mode 100644 index fb81983a2..000000000 --- a/packages/schema/src/generator/next-auth/index.ts +++ /dev/null @@ -1,352 +0,0 @@ -import { Context, Generator } from '../types'; -import { Project } from 'ts-morph'; -import * as path from 'path'; -import colors from 'colors'; -import { DataModel, isDataModel, Model } from '@lang/generated/ast'; -import { execSync } from 'child_process'; - -/** - * Generates NextAuth adaptor code - */ -export default class NextAuthGenerator implements Generator { - get name() { - return 'next-auth'; - } - - private findModel(schema: Model, name: string) { - return schema.declarations.find( - (d) => isDataModel(d) && d.name === name - ) as DataModel; - } - - private modelHasField(model: DataModel, name: string) { - return !!model.fields.find((f) => f.name === name); - } - - async generate(context: Context): Promise { - try { - execSync('npm ls next-auth'); - } catch (err) { - return; - } - - if (!this.findModel(context.schema, 'User')) { - console.warn( - colors.yellow( - 'Skipping generating next-auth adapter: "User" model not found.' - ) - ); - return; - } - - const userModel = this.findModel(context.schema, 'User'); - if ( - !this.modelHasField(userModel, 'email') || - !this.modelHasField(userModel, 'emailVerified') - ) { - console.warn( - colors.yellow( - `Skipping generating next-auth adapter because "User" model doesn't meet requirements: "email" and "emailVerified" fields are required.` - ) - ); - return; - } - - const project = new Project(); - - this.generateIndex(project, context); - this.generateAdapter(project, context); - this.generateAuthorize(project, context); - - await project.save(); - - console.log(colors.blue(` ✔️ Next-auth adapter generated`)); - } - - private generateIndex(project: Project, context: Context) { - const sf = project.createSourceFile( - path.join(context.generatedCodeDir, 'src/auth/index.ts'), - undefined, - { overwrite: true } - ); - - sf.addStatements([ - `export * from './next-auth-adapter';`, - `export * from './authorize';`, - ]); - - sf.formatText(); - } - - private generateAdapter(project: Project, context: Context) { - const sf = project.createSourceFile( - path.join( - context.generatedCodeDir, - 'src/auth/next-auth-adapter.ts' - ), - undefined, - { overwrite: true } - ); - - sf.addImportDeclarations([ - { - namedImports: [ - { - name: 'ZenStackService', - }, - ], - moduleSpecifier: '..', - }, - { - namedImports: [ - { - name: 'Adapter', - }, - ], - moduleSpecifier: 'next-auth/adapters', - }, - { - namedImports: [ - { - name: 'Prisma', - }, - ], - moduleSpecifier: '../../.prisma', - isTypeOnly: true, - }, - ]); - - const adapter = sf.addFunction({ - name: 'NextAuthAdapter', - isExported: true, - returnType: 'Adapter', - }); - - adapter.addParameter({ - name: 'service', - type: 'ZenStackService', - }); - - const userModel = this.findModel(context.schema, 'User'); - - adapter.setBodyText((writer) => { - writer.writeLine('const db = service.db;'); - writer.write('return '); - writer.block(() => { - writer.writeLine( - ` - createUser: (data) => db.user.create({ data: data as Prisma.UserCreateInput }), - getUser: (id) => db.user.findUnique({ where: { id } }), - updateUser: (data) => db.user.update({ where: { id: data.id }, data: data as Prisma.UserUpdateInput }), - deleteUser: (id) => db.user.delete({ where: { id } }), - ` - ); - - if (this.modelHasField(userModel, 'email')) { - writer.writeLine( - 'getUserByEmail: (id) => db.user.findUnique({ where: { id } }),' - ); - } else { - writer.writeLine( - `getUserByEmail: (id) => { throw new Error('"User" model has no "email" field'); },` - ); - } - - if (this.findModel(context.schema, 'Account')) { - writer.writeLine( - ` - async getUserByAccount(provider_providerAccountId) { - const account = await db.account.findUnique({ - where: { provider_providerAccountId }, - select: { user: true }, - }); - return account?.user ?? null; - }, - linkAccount: (data) => db.account.create({ data }) as any, - unlinkAccount: (provider_providerAccountId) => - db.account.delete({ where: { provider_providerAccountId } }) as any, - ` - ); - } else { - writer.writeLine( - ` - async getUserByAccount(provider_providerAccountId) { throw new Error('Schema has no "Account" model declared'); }, - linkAccount: (data) => { throw new Error('Schema has no "Account" model declared'); }, - unlinkAccount: (provider_providerAccountId) => { throw new Error('Schema has no "Account" model declared'); }, - ` - ); - } - - if (this.findModel(context.schema, 'Session')) { - writer.writeLine( - ` - async getSessionAndUser(sessionToken) { - const userAndSession = await db.session.findUnique({ - where: { sessionToken }, - include: { user: true }, - }); - if (!userAndSession) return null; - const { user, ...session } = userAndSession; - return { user, session }; - }, - createSession: (data) => db.session.create({ data }), - updateSession: (data) => - db.session.update({ - data, - where: { sessionToken: data.sessionToken }, - }), - deleteSession: (sessionToken) => - db.session.delete({ where: { sessionToken } }), - ` - ); - } else { - writer.writeLine( - ` - async getSessionAndUser(sessionToken) { throw new Error('Schema has no "Session" model declared'); }, - createSession: (data) => { throw new Error('Schema has no "Session" model declared'); }, - updateSession: (data) => { throw new Error('Schema has no "Session" model declared'); }, - deleteSession: (sessionToken) => { throw new Error('Schema has no "Session" model declared'); }, ` - ); - } - - if (this.findModel(context.schema, 'VerificationToken')) { - writer.writeLine( - ` - createVerificationToken: (data) => db.verificationToken.create({ data }), - async useVerificationToken(identifier_token) { - try { - return await db.verificationToken.delete({ - where: { identifier_token }, - }); - } catch (error) { - // If token already used/deleted, just return null - // https://www.prisma.io/docs/reference/api-reference/error-reference#p2025 - if ( - (error as Prisma.PrismaClientKnownRequestError).code === - 'P2025' - ) - return null; - throw error; - } - }, - ` - ); - } else { - writer.writeLine( - ` - createVerificationToken: (data) => { throw new Error('Schema has no "VerificationToken" model declared'); }, - async useVerificationToken(identifier_token) { throw new Error('Schema has no "VerificationToken" model declared'); }, ` - ); - } - }); - }); - - sf.formatText(); - } - - private generateAuthorize(project: Project, context: Context) { - const userModel = this.findModel(context.schema, 'User'); - const hasEmail = userModel && this.modelHasField(userModel, 'email'); - const hasPassword = - userModel && this.modelHasField(userModel, 'password'); - - let content = ''; - if (!hasEmail || !hasPassword) { - content = ` - import { ZenStackService } from '..'; - - export function authorize(service: ZenStackService, implicitSignup = false) { - throw new Error('"User" model must have "email" and "password" field'); - } - `; - } else { - content = ` - import { ZenStackService } from '..'; - import { hash, compare } from 'bcryptjs'; - - async function hashPassword(password: string) { - const hashedPassword = await hash(password, 12); - return hashedPassword; - } - - async function verifyPassword(password: string, hashedPassword: string) { - const isValid = await compare(password, hashedPassword); - return isValid; - } - - export function authorize(service: ZenStackService, implicitSignup = false) { - return async ( - credentials: Record<'email' | 'password', string> | undefined - ) => { - if (!credentials) { - throw new Error('Missing credentials'); - } - - try { - let maybeUser = await service.db.user.findFirst({ - where: { - email: credentials!.email, - }, - select: { - id: true, - email: true, - password: true, - name: true, - }, - }); - - if (!maybeUser) { - if (!implicitSignup || !credentials.password || !credentials.email) { - return null; - } - - maybeUser = await service.db.user.create({ - data: { - email: credentials.email, - password: await hashPassword(credentials.password), - }, - select: { - id: true, - email: true, - password: true, - name: true, - }, - }); - } else { - if (!maybeUser.password) { - throw new Error('Invalid User Record'); - } - - const isValid = await verifyPassword( - credentials.password, - maybeUser.password - ); - - if (!isValid) { - return null; - } - } - - return { - id: maybeUser.id, - email: maybeUser.email, - name: maybeUser.name, - }; - } catch (error) { - console.log('Error occurred during authorization:', error); - throw error; - } - }; - } - `; - } - - const sf = project.createSourceFile( - path.join(context.generatedCodeDir, 'src/auth/authorize.ts'), - content, - { overwrite: true } - ); - - sf.formatText(); - } -} diff --git a/packages/schema/src/generator/prisma/index.ts b/packages/schema/src/generator/prisma/index.ts index 183c468ef..46ee852db 100644 --- a/packages/schema/src/generator/prisma/index.ts +++ b/packages/schema/src/generator/prisma/index.ts @@ -1,8 +1,7 @@ -import colors from 'colors'; -import { Context, Generator, GeneratorError } from '../types'; import { execSync } from '../../utils/exec-utils'; -import PrismaSchemaGenerator from './schema-generator'; +import { Context, Generator, GeneratorError } from '../types'; import QueryGuardGenerator from './query-guard-generator'; +import PrismaSchemaGenerator from './schema-generator'; /** * Generates Prisma schema and db client @@ -12,7 +11,15 @@ export default class PrismaGenerator implements Generator { return 'prisma'; } - async generate(context: Context): Promise { + get startMessage() { + return 'Generating Prisma client...'; + } + + get successMessage() { + return 'Successfully generated Prisma client'; + } + + async generate(context: Context) { // generate prisma schema const schemaFile = await new PrismaSchemaGenerator(context).generate(); @@ -22,9 +29,7 @@ export default class PrismaGenerator implements Generator { // generate prisma query guard await new QueryGuardGenerator(context).generate(); - console.log( - colors.blue(` ✔️ Prisma schema and query guard generated`) - ); + return []; } private async generatePrismaClient(schemaFile: string) { diff --git a/packages/schema/src/generator/react-hooks/index.ts b/packages/schema/src/generator/react-hooks/index.ts index 0c8e5e919..7a856bedd 100644 --- a/packages/schema/src/generator/react-hooks/index.ts +++ b/packages/schema/src/generator/react-hooks/index.ts @@ -1,10 +1,9 @@ -import { Context, Generator } from '../types'; -import { Project } from 'ts-morph'; -import * as path from 'path'; -import { paramCase } from 'change-case'; import { DataModel, isDataModel } from '@lang/generated/ast'; -import colors from 'colors'; +import { paramCase } from 'change-case'; +import * as path from 'path'; +import { Project } from 'ts-morph'; import { API_ROUTE_NAME, RUNTIME_PACKAGE } from '../constants'; +import { Context, Generator } from '../types'; /** * Generate react data query hooks code @@ -14,9 +13,18 @@ export default class ReactHooksGenerator implements Generator { return 'react-hooks'; } - async generate(context: Context): Promise { + get startMessage() { + return 'Generating React hooks...'; + } + + get successMessage(): string { + return 'Successfully generated React hooks'; + } + + async generate(context: Context) { const project = new Project(); const models: DataModel[] = []; + const warnings: string[] = []; for (const model of context.schema.declarations.filter( (d): d is DataModel => isDataModel(d) @@ -25,10 +33,8 @@ export default class ReactHooksGenerator implements Generator { (attr) => attr.decl.ref?.name === '@@allow' ); if (!hasAllowRule) { - console.warn( - colors.yellow( - `Not generating hooks for "${model.name}" because it doesn't have any @@allow rule` - ) + warnings.push( + `Not generating hooks for "${model.name}" because it doesn't have any @@allow rule` ); } else { models.push(model); @@ -40,8 +46,7 @@ export default class ReactHooksGenerator implements Generator { models.forEach((d) => this.generateModelHooks(project, context, d)); await project.save(); - - console.log(colors.blue(' ✔️ React hooks generated')); + return warnings; } private getValidator(model: DataModel, mode: 'create' | 'update') { diff --git a/packages/schema/src/generator/service/index.ts b/packages/schema/src/generator/service/index.ts index 3216832dd..efe67fcc0 100644 --- a/packages/schema/src/generator/service/index.ts +++ b/packages/schema/src/generator/service/index.ts @@ -1,6 +1,5 @@ import { DataModel, isDataModel } from '@lang/generated/ast'; import { camelCase } from 'change-case'; -import colors from 'colors'; import * as path from 'path'; import { Project } from 'ts-morph'; import { RUNTIME_PACKAGE } from '../constants'; @@ -14,7 +13,15 @@ export default class ServiceGenerator implements Generator { return 'service'; } - async generate(context: Context): Promise { + get startMessage() { + return 'Generating ZenStack service...'; + } + + get successMessage() { + return 'Successfully generated ZenStack service'; + } + + async generate(context: Context) { const project = new Project(); const sf = project.createSourceFile( path.join(context.generatedCodeDir, 'src/index.ts'), @@ -101,6 +108,6 @@ export default class ServiceGenerator implements Generator { sf.formatText(); await project.save(); - console.log(colors.blue(` ✔️ ZenStack service generated`)); + return []; } } diff --git a/packages/schema/src/generator/tsc/index.ts b/packages/schema/src/generator/tsc/index.ts index 50321f73d..713a5f7f2 100644 --- a/packages/schema/src/generator/tsc/index.ts +++ b/packages/schema/src/generator/tsc/index.ts @@ -1,5 +1,4 @@ /* eslint-disable @typescript-eslint/no-var-requires */ -import colors from 'colors'; import * as fs from 'fs'; import path from 'path'; import { execSync } from '../../utils/exec-utils'; @@ -10,6 +9,14 @@ export class TypescriptCompilation implements Generator { return 'tsc'; } + get startMessage() { + return 'Transpiling generated code...'; + } + + get successMessage() { + return 'Successfully transpiled all generated code'; + } + async generate(context: Context) { // generate package.json const packageJson = require(path.join( @@ -47,6 +54,6 @@ export class TypescriptCompilation implements Generator { ); } - console.log(colors.blue(' ✔️ Typescript source files transpiled')); + return []; } } diff --git a/packages/schema/src/generator/types.ts b/packages/schema/src/generator/types.ts index 49733e443..44f0f074b 100644 --- a/packages/schema/src/generator/types.ts +++ b/packages/schema/src/generator/types.ts @@ -8,7 +8,9 @@ export interface Context { export interface Generator { get name(): string; - generate(context: Context): Promise; + get startMessage(): string; + get successMessage(): string; + generate(context: Context): Promise; } export class GeneratorError extends Error { diff --git a/packages/schema/src/language-server/lsp/zmodel-definition-provider.ts b/packages/schema/src/language-server/lsp/zmodel-definition-provider.ts deleted file mode 100644 index 786ffcfed..000000000 --- a/packages/schema/src/language-server/lsp/zmodel-definition-provider.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { - CstNode, - DefinitionProvider, - findDeclarationNodeAtOffset, - getDocument, - GoToLink, - LangiumDocument, - LangiumServices, - MaybePromise, - NameProvider, -} from 'langium'; -import { GrammarConfig } from 'langium/lib/grammar/grammar-config'; -import { References } from 'langium/lib/references/references'; -import { DefinitionParams, LocationLink } from 'vscode-languageserver'; - -/** - * Custom Langium DefinitionProvider implementation - */ -export default class ZModelDefinitionProvider implements DefinitionProvider { - protected readonly nameProvider: NameProvider; - protected readonly references: References; - protected readonly grammarConfig: GrammarConfig; - - constructor(services: LangiumServices) { - this.nameProvider = services.references.NameProvider; - this.references = services.references.References; - this.grammarConfig = services.parser.GrammarConfig; - } - - getDefinition( - document: LangiumDocument, - params: DefinitionParams - ): MaybePromise { - const rootNode = document.parseResult.value; - if (rootNode.$cstNode) { - const cst = rootNode.$cstNode; - const sourceCstNode = findDeclarationNodeAtOffset( - cst, - document.textDocument.offsetAt(params.position), - this.grammarConfig.nameRegexp - ); - if (sourceCstNode) { - return this.collectLocationLinks(sourceCstNode, params); - } - } - return undefined; - } - - protected collectLocationLinks( - sourceCstNode: CstNode, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _params: DefinitionParams - ): MaybePromise { - const goToLink = this.findLink(sourceCstNode); - if (goToLink) { - if ( - // this condition is for working around a potential Langium bug - // https://github.com/langium/langium/discussions/732 - !goToLink.targetDocument.textDocument.uri.endsWith( - 'stdlib.zmodel' - ) - ) { - return [ - LocationLink.create( - goToLink.targetDocument.textDocument.uri, - (goToLink.target.element.$cstNode ?? goToLink.target) - .range, - goToLink.target.range, - goToLink.source.range - ), - ]; - } - } - return undefined; - } - - protected findLink(source: CstNode): GoToLink | undefined { - const target = this.references.findDeclarationNode(source); - if (target?.element) { - const targetDocument = getDocument(target.element); - if (target && targetDocument) { - return { source, target, targetDocument }; - } - } - return undefined; - } -} diff --git a/packages/schema/src/language-server/zmodel-linker.ts b/packages/schema/src/language-server/zmodel-linker.ts index 7730acf33..2dcaf6c81 100644 --- a/packages/schema/src/language-server/zmodel-linker.ts +++ b/packages/schema/src/language-server/zmodel-linker.ts @@ -129,10 +129,6 @@ export class ZModelLinker extends DefaultLinker { document: LangiumDocument, extraScopes: ScopeProvider[] = [] ) { - if (node.$resolvedType) { - return; - } - switch (node.$type) { case LiteralExpr: this.resolveLiteral(node as LiteralExpr); diff --git a/packages/schema/src/language-server/zmodel-module.ts b/packages/schema/src/language-server/zmodel-module.ts index f8a159263..0a4091750 100644 --- a/packages/schema/src/language-server/zmodel-module.ts +++ b/packages/schema/src/language-server/zmodel-module.ts @@ -30,7 +30,6 @@ import { import { TextDocuments } from 'vscode-languageserver'; import { TextDocument } from 'vscode-languageserver-textdocument'; import ZModelWorkspaceManager from './zmodel-workspace-manager'; -import ZModelDefinitionProvider from './lsp/zmodel-definition-provider'; /** * Declaration of custom services - add your own service classes here. @@ -65,10 +64,6 @@ export const ZModelModule: Module< new ZModelValidationRegistry(services), ZModelValidator: () => new ZModelValidator(), }, - lsp: { - DefinitionProvider: (services) => - new ZModelDefinitionProvider(services), - }, }; // this duplicates createDefaultSharedModule except that a custom WorkspaceManager is used diff --git a/packages/schema/src/res/stdlib.zmodel b/packages/schema/src/res/stdlib.zmodel index 9b436a05c..4a8078cb4 100644 --- a/packages/schema/src/res/stdlib.zmodel +++ b/packages/schema/src/res/stdlib.zmodel @@ -54,7 +54,7 @@ enum AttributeTargetField { function env(name: String): String {} /* - * Gets thec current login user. + * Gets the current login user. */ function auth(): Any {} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 75499068e..df222095e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,26 @@ importers: devDependencies: '@changesets/cli': 2.25.2 + packages/next-auth: + specifiers: + '@next-auth/prisma-adapter': ^1.0.5 + '@types/bcryptjs': ^2.4.2 + '@zenstackhq/runtime': workspace:* + bcryptjs: ^2.4.3 + next-auth: ^4.0.0 + rimraf: ^3.0.2 + typescript: ^4.9.3 + dependencies: + '@next-auth/prisma-adapter': 1.0.5_w3qkztkwfy6eylhe7n5itugygy + '@zenstackhq/runtime': link:../runtime/dist + bcryptjs: 2.4.3 + devDependencies: + '@types/bcryptjs': 2.4.2 + next-auth: 4.17.0_azq6kxkn3od7qdylwkyksrwopy + rimraf: 3.0.2 + typescript: 4.9.3 + publishDirectory: dist + packages/runtime: specifiers: '@types/bcryptjs': ^2.4.2 @@ -22,6 +42,7 @@ importers: react: ^17.0.2 || ^18 react-dom: ^17.0.2 || ^18 rimraf: ^3.0.2 + superjson: ^1.11.0 swr: ^1.3.0 tslib: ^2.4.1 typescript: ^4.9.3 @@ -37,6 +58,7 @@ importers: next: 12.3.1_biqbaboplfbrettd7655fr4n2y react: 18.2.0 react-dom: 18.2.0_react@18.2.0 + superjson: 1.11.0 swr: 1.3.0_react@18.2.0 tslib: 2.4.1 zod: 3.19.1 @@ -76,6 +98,7 @@ importers: langium-cli: ^0.5.0 mixpanel: ^0.17.0 node-machine-id: ^1.1.12 + ora: ^6.1.2 pluralize: ^8.0.0 prisma: ~4.7.0 promisify: ^0.0.3 @@ -106,6 +129,7 @@ importers: langium: 0.5.0 mixpanel: 0.17.0 node-machine-id: 1.1.12 + ora: 6.1.2 pluralize: 8.0.0 prisma: 4.7.0 promisify: 0.0.3 @@ -151,10 +175,12 @@ importers: '@types/supertest': ^2.0.12 '@types/tmp': ^0.2.3 bcryptjs: ^2.4.3 + decimal.js: ^10.4.2 jest: ^29.0.3 jest-fetch-mock: ^3.0.3 next: ^12.3.1 sleep-promise: ^9.1.0 + superjson: ^1.11.0 supertest: ^6.3.0 tmp: ^0.2.1 ts-jest: ^29.0.1 @@ -163,7 +189,9 @@ importers: dependencies: '@types/node': 14.18.29 bcryptjs: 2.4.3 + decimal.js: 10.4.2 sleep-promise: 9.1.0 + superjson: 1.11.0 devDependencies: '@types/bcryptjs': 2.4.2 '@types/jest': 29.0.3 @@ -689,7 +717,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.11 - dev: true /@babel/template/7.18.10: resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} @@ -1508,6 +1535,16 @@ packages: read-yaml-file: 1.1.0 dev: true + /@next-auth/prisma-adapter/1.0.5_w3qkztkwfy6eylhe7n5itugygy: + resolution: {integrity: sha512-VqMS11IxPXrPGXw6Oul6jcyS/n8GLOWzRMrPr3EMdtD6eOalM6zz05j08PcNiis8QzkfuYnCv49OvufTuaEwYQ==} + peerDependencies: + '@prisma/client': '>=2.26.0 || >=3' + next-auth: ^4 + dependencies: + '@prisma/client': 4.7.1 + next-auth: 4.17.0_azq6kxkn3od7qdylwkyksrwopy + dev: false + /@next/env/12.3.1: resolution: {integrity: sha512-9P9THmRFVKGKt9DYqeC2aKIxm8rlvkK38V1P1sRE7qyoPBIs8l9oo79QoSdPtOWfzkbDAVUqvbQGgTMsb8BtJg==} @@ -1676,6 +1713,22 @@ packages: engines: {node: '>=14'} dev: true + /@panva/hkdf/1.0.2: + resolution: {integrity: sha512-MSAs9t3Go7GUkMhpKC44T58DJ5KGk2vBo+h1cqQeqlMfdGkxaVB78ZWpv9gYi/g2fa4sopag9gJsNvS8XGgWJA==} + + /@prisma/client/4.7.1: + resolution: {integrity: sha512-/GbnOwIPtjiveZNUzGXOdp7RxTEkHL4DZP3vBaFNadfr6Sf0RshU5EULFzVaSi9i9PIK9PYd+1Rn7z2B2npb9w==} + engines: {node: '>=14.17'} + requiresBuild: true + peerDependencies: + prisma: '*' + peerDependenciesMeta: + prisma: + optional: true + dependencies: + '@prisma/engines-version': 4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c + dev: false + /@prisma/debug/4.7.0: resolution: {integrity: sha512-KdfL70X2OgYMrweEiXa9pZReAPbsYbCbFAyT8Ud/8+w+zI1xOWpFZ4watK95ambK0f6/2p1kP6WGHGKOor1imA==} dependencies: @@ -1707,6 +1760,10 @@ packages: - supports-color dev: true + /@prisma/engines-version/4.7.1-1.272861e07ab64f234d3ffc4094e32bd61775599c: + resolution: {integrity: sha512-Bd4LZ+WAnUHOq31e9X/ihi5zPlr4SzTRwUZZYxvWOxlerIZ7HJlVa9zXpuKTKLpI9O1l8Ec4OYCKsivWCs5a3Q==} + dev: false + /@prisma/engines/4.7.0: resolution: {integrity: sha512-afKrVFktaZ1pOK12/uFl2hRsBWIJZuC5FdDtacuKk5x/mR+rC5AbA+PlN3ZCZbmYTaeiBMHjcU5wbT5z2N3nSQ==} requiresBuild: true @@ -2252,6 +2309,11 @@ packages: engines: {node: '>=8'} dev: true + /ansi-regex/6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: false + /ansi-styles/3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -2516,7 +2578,6 @@ packages: /base64-js/1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true /bcryptjs/2.4.3: resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} @@ -2542,6 +2603,14 @@ packages: readable-stream: 3.6.0 dev: true + /bl/5.1.0: + resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + dependencies: + buffer: 6.0.3 + inherits: 2.0.4 + readable-stream: 3.6.0 + dev: false + /boolbase/1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} dev: true @@ -2608,6 +2677,13 @@ packages: ieee754: 1.2.1 dev: true + /buffer/6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + /busboy/1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -2681,6 +2757,11 @@ packages: supports-color: 7.2.0 dev: true + /chalk/5.1.2: + resolution: {integrity: sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: false + /change-case/4.1.2: resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} dependencies: @@ -2799,10 +2880,16 @@ packages: restore-cursor: 3.1.0 dev: true + /cli-cursor/4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + restore-cursor: 4.0.0 + dev: false + /cli-spinners/2.7.0: resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} engines: {node: '>=6'} - dev: true /cli-truncate/2.1.0: resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} @@ -2840,7 +2927,6 @@ packages: /clone/1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} - dev: true /co/4.6.0: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} @@ -2957,10 +3043,21 @@ packages: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} dev: true + /cookie/0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + /cookiejar/2.1.3: resolution: {integrity: sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==} dev: true + /copy-anything/3.0.3: + resolution: {integrity: sha512-fpW2W/BqEzqPp29QS+MwwfisHCQZtiduTe/m8idFo0xbti9fIZ2WVhAsCv4ggFVH3AgCkVdpoOCtQC6gBrdhjw==} + engines: {node: '>=12.13'} + dependencies: + is-what: 4.1.8 + dev: false + /core-util-is/1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true @@ -3122,7 +3219,6 @@ packages: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} dependencies: clone: 1.0.4 - dev: true /define-properties/1.1.4: resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} @@ -4198,7 +4294,6 @@ packages: /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: true /ignore/5.2.0: resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} @@ -4241,7 +4336,6 @@ packages: /inherits/2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true /ini/1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} @@ -4342,6 +4436,11 @@ packages: engines: {node: '>=8'} dev: true + /is-interactive/2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + dev: false + /is-negative-zero/2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -4418,12 +4517,22 @@ packages: engines: {node: '>=10'} dev: true + /is-unicode-supported/1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: false + /is-weakref/1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.2 dev: true + /is-what/4.1.8: + resolution: {integrity: sha512-yq8gMao5upkPoGEU9LsB2P+K3Kt8Q3fQFCGyNCWOAnJAMzEXVV9drYb0TXr42TTliLLhKIBvulgAXgtLLnwzGA==} + engines: {node: '>=12.13'} + dev: false + /is-windows/1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -5410,6 +5519,9 @@ packages: - ts-node dev: true + /jose/4.11.1: + resolution: {integrity: sha512-YRv4Tk/Wlug8qicwqFNFVEZSdbROCHRAC6qu/i0dyNKr5JQdoa2pIGoS04lLO/jXQX7Z9omoNewYIVIxqZBd9Q==} + /js-sdsl/4.1.5: resolution: {integrity: sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==} dev: true @@ -5617,6 +5729,14 @@ packages: is-unicode-supported: 0.1.0 dev: true + /log-symbols/5.1.0: + resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} + engines: {node: '>=12'} + dependencies: + chalk: 5.1.2 + is-unicode-supported: 1.3.0 + dev: false + /loose-envify/1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -5748,7 +5868,6 @@ packages: /mimic-fn/2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - dev: true /mimic-response/3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} @@ -5846,6 +5965,31 @@ packages: engines: {node: '>=10'} dev: true + /next-auth/4.17.0_azq6kxkn3od7qdylwkyksrwopy: + resolution: {integrity: sha512-aN2tdnjS0MDeUpB2tBDOaWnegkgeMWrsccujbXRGMJ607b+EwRcy63MFGSr0OAboDJEe0902piXQkt94GqF8Qw==} + engines: {node: ^12.19.0 || ^14.15.0 || ^16.13.0 || ^18.12.0} + peerDependencies: + next: ^12.2.5 || ^13 + nodemailer: ^6.6.5 + react: ^17.0.2 || ^18 + react-dom: ^17.0.2 || ^18 + peerDependenciesMeta: + nodemailer: + optional: true + dependencies: + '@babel/runtime': 7.20.1 + '@panva/hkdf': 1.0.2 + cookie: 0.5.0 + jose: 4.11.1 + next: 12.3.1_biqbaboplfbrettd7655fr4n2y + oauth: 0.9.15 + openid-client: 5.3.1 + preact: 10.11.3 + preact-render-to-string: 5.2.6_preact@10.11.3 + react: 18.2.0 + react-dom: 18.2.0_react@18.2.0 + uuid: 8.3.2 + /next/12.3.1_6tziyx3dehkoeijunclpkpolha: resolution: {integrity: sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw==} engines: {node: '>=12.22.0'} @@ -5934,7 +6078,6 @@ packages: transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - dev: false /no-case/3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -6005,6 +6148,13 @@ packages: boolbase: 1.0.0 dev: true + /oauth/0.9.15: + resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} + + /object-hash/2.2.0: + resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} + engines: {node: '>= 6'} + /object-inspect/1.12.2: resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} dev: true @@ -6024,6 +6174,10 @@ packages: object-keys: 1.1.1 dev: true + /oidc-token-hash/5.0.1: + resolution: {integrity: sha512-EvoOtz6FIEBzE+9q253HsLCVRiK/0doEJ2HCvvqMQb3dHZrP3WlJKYtJ55CRTw4jmYomzH4wkPuCj/I3ZvpKxQ==} + engines: {node: ^10.13.0 || >=12.0.0} + /once/1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -6035,7 +6189,6 @@ packages: engines: {node: '>=6'} dependencies: mimic-fn: 2.1.0 - dev: true /open/7.4.2: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} @@ -6045,6 +6198,14 @@ packages: is-wsl: 2.2.0 dev: true + /openid-client/5.3.1: + resolution: {integrity: sha512-RLfehQiHch9N6tRWNx68cicf3b1WR0x74bJWHRc25uYIbSRwjxYcTFaRnzbbpls5jroLAaB/bFIodTgA5LJMvw==} + dependencies: + jose: 4.11.1 + lru-cache: 6.0.0 + object-hash: 2.2.0 + oidc-token-hash: 5.0.1 + /optionator/0.9.1: resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} @@ -6072,6 +6233,21 @@ packages: wcwidth: 1.0.1 dev: true + /ora/6.1.2: + resolution: {integrity: sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + bl: 5.1.0 + chalk: 5.1.2 + cli-cursor: 4.0.0 + cli-spinners: 2.7.0 + is-interactive: 2.0.0 + is-unicode-supported: 1.3.0 + log-symbols: 5.1.0 + strip-ansi: 7.0.1 + wcwidth: 1.0.1 + dev: false + /os-tmpdir/1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -6273,6 +6449,17 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 + /preact-render-to-string/5.2.6_preact@10.11.3: + resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} + peerDependencies: + preact: '>=10' + dependencies: + preact: 10.11.3 + pretty-format: 3.8.0 + + /preact/10.11.3: + resolution: {integrity: sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==} + /prebuild-install/7.1.1: resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} engines: {node: '>=10'} @@ -6331,6 +6518,9 @@ packages: react-is: 18.2.0 dev: true + /pretty-format/3.8.0: + resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==} + /prisma/4.7.0: resolution: {integrity: sha512-VsecNo0Ca3+bDTzSpJqIpdupKVhhQ8aOYeWc09JlUM89knqvhSrlMrg0U8BiOD4tFrY1OPaCcraK8leDBxKMBg==} engines: {node: '>=14.17'} @@ -6491,7 +6681,6 @@ packages: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 - dev: true /readdir-glob/1.1.2: resolution: {integrity: sha512-6RLVvwJtVwEDfPdn6X6Ille4/lxGl0ATOY4FN/B9nxQcgOazvvI0nodiD19ScKq0PvA/29VpaOQML36o5IzZWA==} @@ -6516,7 +6705,6 @@ packages: /regenerator-runtime/0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - dev: true /regexp-to-ast/0.5.0: resolution: {integrity: sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==} @@ -6588,6 +6776,14 @@ packages: signal-exit: 3.0.7 dev: true + /restore-cursor/4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: false + /retry/0.13.1: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} @@ -6621,7 +6817,6 @@ packages: /safe-buffer/5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true /safe-regex-test/1.0.0: resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} @@ -6719,7 +6914,6 @@ packages: /signal-exit/3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true /simple-concat/1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} @@ -6889,7 +7083,6 @@ packages: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 - dev: true /strip-ansi/6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -6898,6 +7091,13 @@ packages: ansi-regex: 5.0.1 dev: true + /strip-ansi/7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: false + /strip-bom/3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -6961,7 +7161,6 @@ packages: optional: true dependencies: react: 18.2.0 - dev: false /superagent/8.0.2: resolution: {integrity: sha512-QtYZ9uaNAMexI7XWl2vAXAh0j4q9H7T0WVEI/y5qaUB3QLwxo+voUgCQ217AokJzUTIVOp0RTo7fhZrwhD7A2Q==} @@ -6982,6 +7181,13 @@ packages: - supports-color dev: true + /superjson/1.11.0: + resolution: {integrity: sha512-6PfAg1FKhqkwWvPb2uXhH4MkMttdc17eJ91+Aoz4s1XUEDZFmLfFx/xVA3wgkPxAGy5dpozgGdK6V/n20Wj9yg==} + engines: {node: '>=10'} + dependencies: + copy-anything: 3.0.3 + dev: false + /supertest/6.3.0: resolution: {integrity: sha512-QgWju1cNoacP81Rv88NKkQ4oXTzGg0eNZtOoxp1ROpbS4OHY/eK5b8meShuFtdni161o5X0VQvgo7ErVyKK+Ow==} engines: {node: '>=6.4.0'} @@ -7508,7 +7714,6 @@ packages: /util-deprecate/1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true /uuid/3.4.0: resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} @@ -7519,7 +7724,6 @@ packages: /uuid/8.3.2: resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} hasBin: true - dev: true /uuid/9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} @@ -7617,7 +7821,6 @@ packages: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: defaults: 1.0.4 - dev: true /webidl-conversions/3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} diff --git a/samples/todo/.babelrc b/samples/todo/.babelrc new file mode 100644 index 000000000..cfeaef173 --- /dev/null +++ b/samples/todo/.babelrc @@ -0,0 +1,6 @@ +{ + "presets": ["next/babel"], + // "superjson-next" plugin uses superjson for serialization between getServerSideProps and client, + // so that types like Date and BigInt are properly handled + "plugins": ["superjson-next"] +} diff --git a/samples/todo/package-lock.json b/samples/todo/package-lock.json index cb2563a39..5e79d9d8d 100644 --- a/samples/todo/package-lock.json +++ b/samples/todo/package-lock.json @@ -1,16 +1,18 @@ { "name": "todo", - "version": "0.3.23", + "version": "0.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "todo", - "version": "0.3.23", + "version": "0.5.0", "dependencies": { "@heroicons/react": "^2.0.12", "@prisma/client": "^4.7.0", - "@zenstackhq/runtime": "^0.3.23", + "@zenstackhq/next-auth": "^0.5.0", + "@zenstackhq/runtime": "^0.5.0", + "babel-plugin-superjson-next": "^0.4.5", "bcryptjs": "^2.4.3", "daisyui": "^2.31.0", "moment": "^2.29.4", @@ -33,7 +35,7 @@ "postcss": "^8.4.16", "tailwindcss": "^3.1.8", "typescript": "^4.6.2", - "zenstack": "^0.3.23" + "zenstack": "^0.5.0" } }, "../../packages/runtime": { @@ -75,11 +77,29 @@ "@babel/highlight": "^7.10.4" } }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -193,6 +213,19 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/types": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@chevrotain/types": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-9.1.0.tgz", @@ -253,6 +286,15 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@next-auth/prisma-adapter": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@next-auth/prisma-adapter/-/prisma-adapter-1.0.5.tgz", + "integrity": "sha512-VqMS11IxPXrPGXw6Oul6jcyS/n8GLOWzRMrPr3EMdtD6eOalM6zz05j08PcNiis8QzkfuYnCv49OvufTuaEwYQ==", + "peerDependencies": { + "@prisma/client": ">=2.26.0 || >=3", + "next-auth": "^4" + } + }, "node_modules/@next/env": { "version": "12.3.1", "resolved": "https://registry.npmjs.org/@next/env/-/env-12.3.1.tgz", @@ -749,10 +791,23 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@zenstackhq/next-auth": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@zenstackhq/next-auth/-/next-auth-0.5.0.tgz", + "integrity": "sha512-/6kMkoqea2WWz9oAz9gYBRfJdNKjCmrYQ79kTsLWSRPP2E89GsVTSCRZPU7qnGzBL9B3kVdYWA/yHBuTwpYqbA==", + "dependencies": { + "@next-auth/prisma-adapter": "^1.0.5", + "@zenstackhq/runtime": "0.5.0", + "bcryptjs": "^2.4.3" + }, + "peerDependencies": { + "next-auth": "^4.0.0" + } + }, "node_modules/@zenstackhq/runtime": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/@zenstackhq/runtime/-/runtime-0.3.23.tgz", - "integrity": "sha512-p6QDSjn2I5hDLhz0qK2//9XTno2YpP2C9x8ak9GzoV4XOJcUua7bNvSpRjJ25n15VYzTnelXndsruZjDTeoCaw==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@zenstackhq/runtime/-/runtime-0.5.0.tgz", + "integrity": "sha512-eneaJ1+xThyg9dnIvOvcm3buIVSX9XU8biGE13wBGAkgDWxuOWLNITNEF4MrV4WGwQjwKAR8o0WZaGTMOrMHfw==", "dependencies": { "@types/bcryptjs": "^2.4.2", "bcryptjs": "^2.4.3", @@ -760,6 +815,7 @@ "cuid": "^2.1.8", "decimal.js": "^10.4.2", "deepcopy": "^2.1.0", + "superjson": "^1.11.0", "swr": "^1.3.0", "tslib": "^2.4.1", "zod": "^3.19.1", @@ -1044,12 +1100,49 @@ "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", "dev": true }, + "node_modules/babel-plugin-superjson-next": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/babel-plugin-superjson-next/-/babel-plugin-superjson-next-0.4.5.tgz", + "integrity": "sha512-k7S99Qpsbi3OSdlCMXEiklzxepM6QbYEIUsrjgSkpx+ksT0iNfdY2r1kCzBK2UjG8fLN6NZEKpDA8XpG2pbDSA==", + "dependencies": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/types": "^7.13.17", + "hoist-non-react-statics": "^3.3.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "next": ">=9.0.0", + "superjson": "1.x" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", @@ -1063,6 +1156,17 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1111,6 +1215,30 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -1250,6 +1378,42 @@ "fsevents": "~2.3.2" } }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/clsx": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", @@ -1343,6 +1507,20 @@ "node": ">= 0.6" } }, + "node_modules/copy-anything": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.3.tgz", + "integrity": "sha512-fpW2W/BqEzqPp29QS+MwwfisHCQZtiduTe/m8idFo0xbti9fIZ2WVhAsCv4ggFVH3AgCkVdpoOCtQC6gBrdhjw==", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/core-js-pure": { "version": "3.25.5", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.5.tgz", @@ -1438,9 +1616,9 @@ } }, "node_modules/decimal.js": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", - "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==" + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, "node_modules/deep-is": { "version": "0.1.4", @@ -1456,6 +1634,18 @@ "type-detect": "^4.0.8" } }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", @@ -2456,6 +2646,14 @@ "tslib": "^2.0.3" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -2469,6 +2667,26 @@ "node": ">= 6" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -2643,6 +2861,18 @@ "node": ">=0.10.0" } }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -2736,6 +2966,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -2748,6 +2990,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-what": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.8.tgz", + "integrity": "sha512-yq8gMao5upkPoGEU9LsB2P+K3Kt8Q3fQFCGyNCWOAnJAMzEXVV9drYb0TXr42TTliLLhKIBvulgAXgtLLnwzGA==", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2880,6 +3133,34 @@ "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, + "node_modules/log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "dev": true, + "dependencies": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", + "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -2931,6 +3212,15 @@ "node": ">=8.6" } }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3295,6 +3585,21 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/openid-client": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.2.1.tgz", @@ -3326,6 +3631,68 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/ora/-/ora-6.1.2.tgz", + "integrity": "sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==", + "dev": true, + "dependencies": { + "bl": "^5.0.0", + "chalk": "^5.0.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.6.1", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.1.0", + "log-symbols": "^5.1.0", + "strip-ansi": "^7.0.1", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", + "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -3715,8 +4082,7 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-toastify": { "version": "9.0.8", @@ -3738,6 +4104,20 @@ "pify": "^2.3.0" } }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -3823,6 +4203,22 @@ "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -3869,6 +4265,26 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -3952,6 +4368,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -4016,6 +4438,15 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -4135,6 +4566,17 @@ } } }, + "node_modules/superjson": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-1.11.0.tgz", + "integrity": "sha512-6PfAg1FKhqkwWvPb2uXhH4MkMttdc17eJ91+Aoz4s1XUEDZFmLfFx/xVA3wgkPxAGy5dpozgGdK6V/n20Wj9yg==", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4268,6 +4710,14 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4529,6 +4979,15 @@ "integrity": "sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ==", "dev": true }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/when": { "version": "3.7.8", "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", @@ -4603,13 +5062,13 @@ } }, "node_modules/zenstack": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.3.23.tgz", - "integrity": "sha512-sJMIVxNpxWGozFbs2kndyLM9NPLucdHvjYASfGRi8tp9FrRg2d4Ji2qDC2W5C7sqIvWrUltxpuoynbdjNljhHA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.5.0.tgz", + "integrity": "sha512-nMYl5b9/9FuKBQP++xnJoeM/9bySavgfeRtT552BP7S8I9f8iRK/SxMJqaD8IS5mdFhXj3sdQULjd43euLs8wA==", "dev": true, "hasInstallScript": true, "dependencies": { - "@zenstackhq/runtime": "0.3.23", + "@zenstackhq/runtime": "0.5.0", "async-exit-hook": "^2.0.1", "change-case": "^4.1.2", "chevrotain": "^9.1.0", @@ -4619,6 +5078,7 @@ "langium": "^0.5.0", "mixpanel": "^0.17.0", "node-machine-id": "^1.1.12", + "ora": "^6.1.2", "pluralize": "^8.0.0", "prisma": "~4.7.0", "promisify": "^0.0.3", @@ -4680,11 +5140,23 @@ "@babel/highlight": "^7.10.4" } }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + }, "@babel/helper-validator-identifier": { "version": "7.19.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" }, "@babel/highlight": { "version": "7.18.6", @@ -4773,6 +5245,16 @@ "regenerator-runtime": "^0.13.4" } }, + "@babel/types": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, "@chevrotain/types": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-9.1.0.tgz", @@ -4825,6 +5307,12 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@next-auth/prisma-adapter": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@next-auth/prisma-adapter/-/prisma-adapter-1.0.5.tgz", + "integrity": "sha512-VqMS11IxPXrPGXw6Oul6jcyS/n8GLOWzRMrPr3EMdtD6eOalM6zz05j08PcNiis8QzkfuYnCv49OvufTuaEwYQ==", + "requires": {} + }, "@next/env": { "version": "12.3.1", "resolved": "https://registry.npmjs.org/@next/env/-/env-12.3.1.tgz", @@ -5127,10 +5615,20 @@ } } }, + "@zenstackhq/next-auth": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@zenstackhq/next-auth/-/next-auth-0.5.0.tgz", + "integrity": "sha512-/6kMkoqea2WWz9oAz9gYBRfJdNKjCmrYQ79kTsLWSRPP2E89GsVTSCRZPU7qnGzBL9B3kVdYWA/yHBuTwpYqbA==", + "requires": { + "@next-auth/prisma-adapter": "^1.0.5", + "@zenstackhq/runtime": "0.5.0", + "bcryptjs": "^2.4.3" + } + }, "@zenstackhq/runtime": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/@zenstackhq/runtime/-/runtime-0.3.23.tgz", - "integrity": "sha512-p6QDSjn2I5hDLhz0qK2//9XTno2YpP2C9x8ak9GzoV4XOJcUua7bNvSpRjJ25n15VYzTnelXndsruZjDTeoCaw==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@zenstackhq/runtime/-/runtime-0.5.0.tgz", + "integrity": "sha512-eneaJ1+xThyg9dnIvOvcm3buIVSX9XU8biGE13wBGAkgDWxuOWLNITNEF4MrV4WGwQjwKAR8o0WZaGTMOrMHfw==", "requires": { "@types/bcryptjs": "^2.4.2", "bcryptjs": "^2.4.3", @@ -5138,6 +5636,7 @@ "cuid": "^2.1.8", "decimal.js": "^10.4.2", "deepcopy": "^2.1.0", + "superjson": "^1.11.0", "swr": "^1.3.0", "tslib": "^2.4.1", "zod": "^3.19.1", @@ -5332,12 +5831,28 @@ "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", "dev": true }, + "babel-plugin-superjson-next": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/babel-plugin-superjson-next/-/babel-plugin-superjson-next-0.4.5.tgz", + "integrity": "sha512-k7S99Qpsbi3OSdlCMXEiklzxepM6QbYEIUsrjgSkpx+ksT0iNfdY2r1kCzBK2UjG8fLN6NZEKpDA8XpG2pbDSA==", + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/types": "^7.13.17", + "hoist-non-react-statics": "^3.3.2" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, "bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", @@ -5348,6 +5863,17 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, + "bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dev": true, + "requires": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -5377,6 +5903,16 @@ "update-browserslist-db": "^1.0.9" } }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -5480,6 +6016,27 @@ "readdirp": "~3.6.0" } }, + "cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "requires": { + "restore-cursor": "^4.0.0" + } + }, + "cli-spinners": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.7.0.tgz", + "integrity": "sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==", + "dev": true + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true + }, "clsx": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", @@ -5555,6 +6112,14 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, + "copy-anything": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.3.tgz", + "integrity": "sha512-fpW2W/BqEzqPp29QS+MwwfisHCQZtiduTe/m8idFo0xbti9fIZ2WVhAsCv4ggFVH3AgCkVdpoOCtQC6gBrdhjw==", + "requires": { + "is-what": "^4.1.8" + } + }, "core-js-pure": { "version": "3.25.5", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.5.tgz", @@ -5624,9 +6189,9 @@ } }, "decimal.js": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.2.tgz", - "integrity": "sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==" + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, "deep-is": { "version": "0.1.4", @@ -5642,6 +6207,15 @@ "type-detect": "^4.0.8" } }, + "defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, "define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", @@ -6402,6 +6976,14 @@ "tslib": "^2.0.3" } }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, "https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -6412,6 +6994,12 @@ "debug": "4" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -6535,6 +7123,12 @@ "is-extglob": "^2.1.1" } }, + "is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true + }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -6592,6 +7186,12 @@ "has-symbols": "^1.0.2" } }, + "is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true + }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -6601,6 +7201,11 @@ "call-bind": "^1.0.2" } }, + "is-what": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.8.tgz", + "integrity": "sha512-yq8gMao5upkPoGEU9LsB2P+K3Kt8Q3fQFCGyNCWOAnJAMzEXVV9drYb0TXr42TTliLLhKIBvulgAXgtLLnwzGA==" + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -6712,6 +7317,24 @@ "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, + "log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "dev": true, + "requires": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "dependencies": { + "chalk": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", + "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", + "dev": true + } + } + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6751,6 +7374,12 @@ "picomatch": "^2.3.1" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6989,6 +7618,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "openid-client": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.2.1.tgz", @@ -7014,6 +7652,46 @@ "word-wrap": "^1.2.3" } }, + "ora": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/ora/-/ora-6.1.2.tgz", + "integrity": "sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==", + "dev": true, + "requires": { + "bl": "^5.0.0", + "chalk": "^5.0.0", + "cli-cursor": "^4.0.0", + "cli-spinners": "^2.6.1", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^1.1.0", + "log-symbols": "^5.1.0", + "strip-ansi": "^7.0.1", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "chalk": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz", + "integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==", + "dev": true + }, + "strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + } + } + }, "param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -7264,8 +7942,7 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-toastify": { "version": "9.0.8", @@ -7283,6 +7960,17 @@ "pify": "^2.3.0" } }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -7341,6 +8029,16 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -7363,6 +8061,12 @@ "queue-microtask": "^1.2.2" } }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, "safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -7428,6 +8132,12 @@ "object-inspect": "^1.9.0" } }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -7480,6 +8190,15 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -7564,6 +8283,14 @@ "integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==", "requires": {} }, + "superjson": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-1.11.0.tgz", + "integrity": "sha512-6PfAg1FKhqkwWvPb2uXhH4MkMttdc17eJ91+Aoz4s1XUEDZFmLfFx/xVA3wgkPxAGy5dpozgGdK6V/n20Wj9yg==", + "requires": { + "copy-anything": "^3.0.2" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7667,6 +8394,11 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -7869,6 +8601,15 @@ "integrity": "sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ==", "dev": true }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, "when": { "version": "3.7.8", "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", @@ -7925,12 +8666,12 @@ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, "zenstack": { - "version": "0.3.23", - "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.3.23.tgz", - "integrity": "sha512-sJMIVxNpxWGozFbs2kndyLM9NPLucdHvjYASfGRi8tp9FrRg2d4Ji2qDC2W5C7sqIvWrUltxpuoynbdjNljhHA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.5.0.tgz", + "integrity": "sha512-nMYl5b9/9FuKBQP++xnJoeM/9bySavgfeRtT552BP7S8I9f8iRK/SxMJqaD8IS5mdFhXj3sdQULjd43euLs8wA==", "dev": true, "requires": { - "@zenstackhq/runtime": "0.3.23", + "@zenstackhq/runtime": "0.5.0", "async-exit-hook": "^2.0.1", "change-case": "^4.1.2", "chevrotain": "^9.1.0", @@ -7940,6 +8681,7 @@ "langium": "^0.5.0", "mixpanel": "^0.17.0", "node-machine-id": "^1.1.12", + "ora": "^6.1.2", "pluralize": "^8.0.0", "prisma": "~4.7.0", "promisify": "^0.0.3", diff --git a/samples/todo/package.json b/samples/todo/package.json index 6b66745fd..07f2c86d1 100644 --- a/samples/todo/package.json +++ b/samples/todo/package.json @@ -1,6 +1,6 @@ { "name": "todo", - "version": "0.4.0", + "version": "0.5.0", "private": true, "scripts": { "dev": "next dev", @@ -14,14 +14,16 @@ "db:browse": "zenstack studio", "generate": "zenstack generate", "vercel-build": "npm run build && npm run db:deploy", - "deps-local": "npm i -D ../../packages/schema && npm i ../../packages/runtime/dist", - "deps-latest": "npm i -D zenstack@latest && npm i @zenstackhq/runtime@latest", - "deps-dev": "npm i -D zenstack@dev && npm i @zenstackhq/runtime@dev" + "deps-local": "npm i -D ../../packages/schema && npm i ../../packages/runtime/dist ../../packages/next-auth/dist zod zod-validation-error swr", + "deps-latest": "npm rm zod zod-validation-error swr && npm i -D zenstack@latest && npm i @zenstackhq/runtime@latest @zenstackhq/next-auth@latest", + "deps-dev": "npm rm zod zod-validation-error swr && npm i -D zenstack@dev && npm i @zenstackhq/runtime@dev @zenstackhq/next-auth@dev" }, "dependencies": { "@heroicons/react": "^2.0.12", "@prisma/client": "^4.7.0", - "@zenstackhq/runtime": "^0.3.23", + "@zenstackhq/next-auth": "^0.5.0", + "@zenstackhq/runtime": "^0.5.0", + "babel-plugin-superjson-next": "^0.4.5", "bcryptjs": "^2.4.3", "daisyui": "^2.31.0", "moment": "^2.29.4", @@ -44,6 +46,6 @@ "postcss": "^8.4.16", "tailwindcss": "^3.1.8", "typescript": "^4.6.2", - "zenstack": "^0.3.23" + "zenstack": "^0.5.0" } } diff --git a/samples/todo/pages/api/auth/[...nextauth].ts b/samples/todo/pages/api/auth/[...nextauth].ts index 987f5d53b..f1a2dccac 100644 --- a/samples/todo/pages/api/auth/[...nextauth].ts +++ b/samples/todo/pages/api/auth/[...nextauth].ts @@ -1,10 +1,7 @@ import NextAuth, { NextAuthOptions, User } from 'next-auth'; import CredentialsProvider from 'next-auth/providers/credentials'; import GitHubProvider from 'next-auth/providers/github'; -import { - authorize, - NextAuthAdapter as Adapter, -} from '@zenstackhq/runtime/server/auth'; +import { authorize, Adapter } from '@zenstackhq/next-auth'; import service from '@zenstackhq/runtime/server'; import { nanoid } from 'nanoid'; import { SpaceUserRole } from '@zenstackhq/runtime/types'; diff --git a/tests/integration/package.json b/tests/integration/package.json index 6ee5aab3b..b1c4a83de 100644 --- a/tests/integration/package.json +++ b/tests/integration/package.json @@ -26,6 +26,8 @@ "dependencies": { "@types/node": "^14.18.29", "bcryptjs": "^2.4.3", - "sleep-promise": "^9.1.0" + "decimal.js": "^10.4.2", + "sleep-promise": "^9.1.0", + "superjson": "^1.11.0" } } diff --git a/tests/integration/tests/type-coverage.test.ts b/tests/integration/tests/type-coverage.test.ts index c26783776..df879ba96 100644 --- a/tests/integration/tests/type-coverage.test.ts +++ b/tests/integration/tests/type-coverage.test.ts @@ -1,5 +1,6 @@ import path from 'path'; import { makeClient, run, setup } from './utils'; +import { Decimal } from 'decimal.js'; describe('Type Coverage Tests', () => { let origDir: string; @@ -18,13 +19,14 @@ describe('Type Coverage Tests', () => { }); it('all types', async () => { + const date = new Date(); const data = { string: 'string', int: 100, - bigInt: 9007199254740991, - date: new Date(), + bigInt: BigInt(9007199254740991), + date, float: 1.23, - decimal: 1.2345, + decimal: new Decimal(1.2345), boolean: true, bytes: Buffer.from('hello'), }; @@ -35,33 +37,7 @@ describe('Type Coverage Tests', () => { }) .expect(201) .expect((resp) => { - expect(resp.body.bigInt).toEqual( - expect.objectContaining({ - type: 'BigInt', - data: data.bigInt.toString(), - }) - ); - - expect(resp.body.date).toEqual( - expect.objectContaining({ - type: 'Date', - data: data.date.toISOString(), - }) - ); - - expect(resp.body.decimal).toEqual( - expect.objectContaining({ - type: 'Decimal', - data: data.decimal.toString(), - }) - ); - - expect(resp.body.bytes).toEqual( - expect.objectContaining({ - type: 'Bytes', - data: Array.from(data.bytes), - }) - ); + expect(resp.body).toEqual(expect.objectContaining(data)); }); }); }); diff --git a/tests/integration/tests/utils.ts b/tests/integration/tests/utils.ts index 4dcb399d2..1f9953b9b 100644 --- a/tests/integration/tests/utils.ts +++ b/tests/integration/tests/utils.ts @@ -1,4 +1,3 @@ -import * as tmp from 'tmp'; import { execSync } from 'child_process'; import * as path from 'path'; import * as fs from 'fs'; @@ -7,6 +6,8 @@ import { apiResolver } from 'next/dist/server/api-utils/node'; import request from 'supertest'; import { NextApiHandler } from 'next/types'; import supertest from 'supertest'; +import superjson from 'superjson'; +import { registerSerializers } from '../../../packages/runtime/src/serialization-utils'; export function run(cmd: string) { execSync(cmd, { @@ -17,6 +18,8 @@ export function run(cmd: string) { } export async function setup(schemaFile: string) { + registerSerializers(); + const origDir = path.resolve('.'); const workDir = path.resolve('tests/test-run'); @@ -34,10 +37,10 @@ export async function setup(schemaFile: string) { run('npm init -y'); const dependencies = [ 'typescript', - 'swr', + 'swr@1.3.0', 'react', 'prisma@~4.7.0', - 'zod', + 'zod@~3.19.0', '../../../../packages/schema', '../../../../packages/runtime/dist', ]; @@ -86,7 +89,7 @@ export function makeClient(apiPath: string, userId?: string, queryArgs?: any) { const query = { path: pathParts, - ...(queryArgs ? { q: JSON.stringify(queryArgs) } : {}), + ...(queryArgs ? { q: superjson.stringify(queryArgs) } : {}), }; const testClient = (handler: NextApiHandler) => request( @@ -108,16 +111,30 @@ export function makeClient(apiPath: string, userId?: string, queryArgs?: any) { const handler = require(path.resolve('handler.js')); const client = testClient(handler); + // proxy test and superjson marshal post data + const proxyTest = (test: supertest.Test) => { + // return test; + return new Proxy(test, { + get(target: supertest.Test, prop: string | symbol, receiver: any) { + if (prop === 'send') { + return (data: any) => { + return target.send( + JSON.parse(superjson.stringify(data)) + ); + }; + } else { + return Reflect.get(target, prop, receiver); + } + }, + }); + }; + const proxied = new Proxy(client, { get( target: supertest.SuperTest, prop: string | symbol, receiver: any ) { - if (userId === undefined) { - return Reflect.get(target, prop, receiver); - } - switch (prop) { case 'get': case 'post': @@ -125,11 +142,28 @@ export function makeClient(apiPath: string, userId?: string, queryArgs?: any) { case 'del': case 'delete': return (url: string) => { + const test = target[prop](url) as supertest.Test; + // use userId cookie to simulate a logged in user - return target[prop](url).set('Cookie', [ - `userId=${userId}`, - ]); + if (userId) { + test.set('Cookie', [`userId=${userId}`]); + } + + test.expect((resp) => { + if ( + (resp.status === 200 || resp.status === 201) && + resp.body + ) { + // unmarshal response + resp.body = superjson.parse( + JSON.stringify(resp.body) + ); + } + }); + + return proxyTest(test); }; + default: return Reflect.get(target, prop, receiver); }