Compare commits

..

7 Commits

Author SHA1 Message Date
github-actions[bot]
6d8b243571 release(dashboard): 2.41.0 (#3647)
Co-authored-by: dbarrosop <dbarrosop@users.noreply.github.com>
2025-11-05 08:26:31 +01:00
David Barroso
c9967b1a6d feat(dashboard): get github repositories from github itself (#3640)
Co-authored-by: David BM <correodelnino@gmail.com>
2025-11-04 16:46:01 +01:00
github-actions[bot]
7f72aadff9 release(packages/nhost-js): 4.1.0 (#3586)
Co-authored-by: dbarrosop <dbarrosop@users.noreply.github.com>
2025-11-04 16:21:25 +01:00
github-actions[bot]
8faf9565bb release(services/storage): 0.9.0 (#3654)
Co-authored-by: dbarrosop <dbarrosop@users.noreply.github.com>
2025-11-04 16:21:16 +01:00
github-actions[bot]
7ac3f12852 release(services/auth): 0.43.0 (#3667)
Co-authored-by: dbarrosop <dbarrosop@users.noreply.github.com>
2025-11-04 16:21:10 +01:00
David Barroso
184a3ed190 feat(internal/lib): common oapi middleware for go services (#3663) 2025-11-04 16:17:41 +01:00
David Barroso
372c4e32d4 fix(ci): match the version exactly to avoid matching on pre-releases (#3666) 2025-11-04 15:54:01 +01:00
203 changed files with 3501 additions and 3569 deletions

View File

@@ -32,11 +32,11 @@ Where `PKG` is:
- `deps`: For changes to dependencies
- `docs`: For changes to the documentation
- `examples`: For changes to the examples
- `internal/lib`: For changes to Nhost's common libraries (internal)
- `mintlify-openapi`: For changes to the Mintlify OpenAPI tool
- `nhost-js`: For changes to the Nhost JavaScript SDK
- `nixops`: For changes to the NixOps
- `storage`: For changes to the Nhost Storage service
- `stripe-graphql-js`: For changes to the Stripe GraphQL JS SDK
Where `SUMMARY` is a short description of what the PR does.

View File

@@ -17,7 +17,7 @@ runs:
# Define valid types and packages
VALID_TYPES="feat|fix|chore"
VALID_PKGS="auth|ci|cli|codegen|dashboard|deps|docs|examples|mintlify-openapi|nhost-js|nixops|storage|stripe-graphql-js"
VALID_PKGS="auth|ci|cli|codegen|dashboard|deps|docs|examples|internal\/lib|mintlify-openapi|nhost-js|nixops|storage"
# Check if title matches the pattern TYPE(PKG): SUMMARY
if [[ ! "$PR_TITLE" =~ ^(${VALID_TYPES})\((${VALID_PKGS})\):\ .+ ]]; then

View File

@@ -17,6 +17,7 @@ on:
- '.golangci.yaml'
- 'go.mod'
- 'go.sum'
- 'internal/lib/**'
- 'vendor/**'
# auth

View File

@@ -40,7 +40,7 @@ jobs:
cd ${{ matrix.project }}
TAG_NAME=$(make release-tag-name)
VERSION=$(nix develop .\#cliff -c make changelog-next-version)
if git tag | grep -q "$TAG_NAME@$VERSION"; then
if git tag | grep -qx "$TAG_NAME@$VERSION"; then
echo "Tag $TAG_NAME@$VERSION already exists, skipping release preparation"
else
echo "Tag $TAG_NAME@$VERSION does not exist, proceeding with release preparation"

View File

@@ -17,6 +17,7 @@ on:
- '.golangci.yaml'
- 'go.mod'
- 'go.sum'
- 'internal/lib/**'
- 'vendor/**'
# storage

View File

@@ -1,18 +0,0 @@
import { Context, createStripeGraphQLServer } from '@nhost/stripe-graphql-js';
const isAllowed = async (_stripeCustomerId: string, context: Context) => {
const { isAdmin } = context;
if (isAdmin) {
return true;
}
//TODO: Make sure the user can only access their own stripe customer id
return true;
};
process.env.NODE_ENVIRONMENT = 'development';
const server = createStripeGraphQLServer({ isAllowed });
export default server;

View File

@@ -9,7 +9,6 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@nhost/stripe-graphql-js": "^1.3.0-beta.6",
"@swc/core": "^1.6.5",
"graphql-yoga": "^5.16.0",
"jsonwebtoken": "^9.0.2",
@@ -64,12 +63,12 @@
"license": "MIT"
},
"node_modules/@graphql-tools/executor": {
"version": "1.4.10",
"resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.4.10.tgz",
"integrity": "sha512-/o7QScMdJpx/qIJlQcYs9ohB2qU2jSpuMyPStQy30kKTLHKyMETWpbljvRsuQxHJ2MJmEF3bYZgBHzdNAQHhug==",
"version": "1.4.9",
"resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-1.4.9.tgz",
"integrity": "sha512-SAUlDT70JAvXeqV87gGzvDzUGofn39nvaVcVhNf12Dt+GfWHtNNO/RCn/Ea4VJaSLGzraUd41ObnN3i80EBU7w==",
"license": "MIT",
"dependencies": {
"@graphql-tools/utils": "^10.10.0",
"@graphql-tools/utils": "^10.9.1",
"@graphql-typed-document-node/core": "^3.2.0",
"@repeaterjs/repeater": "^3.0.4",
"@whatwg-node/disposablestack": "^0.0.6",
@@ -84,12 +83,12 @@
}
},
"node_modules/@graphql-tools/merge": {
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.1.2.tgz",
"integrity": "sha512-Ny9YhWKv+KxZFdXYt+wlyEW55GzhFiq4daV4wYgpP0aRbwQaczNJd1L3VjjBsPKjmW8lctZXUoqYTqU5QPcBGw==",
"version": "9.1.1",
"resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.1.1.tgz",
"integrity": "sha512-BJ5/7Y7GOhTuvzzO5tSBFL4NGr7PVqTJY3KeIDlVTT8YLcTXtBR+hlrC3uyEym7Ragn+zyWdHeJ9ev+nRX1X2w==",
"license": "MIT",
"dependencies": {
"@graphql-tools/utils": "^10.10.0",
"@graphql-tools/utils": "^10.9.1",
"tslib": "^2.4.0"
},
"engines": {
@@ -100,13 +99,13 @@
}
},
"node_modules/@graphql-tools/schema": {
"version": "10.0.26",
"resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.26.tgz",
"integrity": "sha512-KOmjuiWa9poP/Lza4HV0ZBPYGJI3VE3QzXA/8e0+wjcsRuEmxMLP82re1PUg0QRzp2UzifAB/gd7DoXmVGG9Fg==",
"version": "10.0.25",
"resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-10.0.25.tgz",
"integrity": "sha512-/PqE8US8kdQ7lB9M5+jlW8AyVjRGCKU7TSktuW3WNKSKmDO0MK1wakvb5gGdyT49MjAIb4a3LWxIpwo5VygZuw==",
"license": "MIT",
"dependencies": {
"@graphql-tools/merge": "^9.1.2",
"@graphql-tools/utils": "^10.10.0",
"@graphql-tools/merge": "^9.1.1",
"@graphql-tools/utils": "^10.9.1",
"tslib": "^2.4.0"
},
"engines": {
@@ -117,9 +116,9 @@
}
},
"node_modules/@graphql-tools/utils": {
"version": "10.10.0",
"resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.10.0.tgz",
"integrity": "sha512-OOeab5Y9qeKq0zfoJCSScMcDfGcIxp05+LW2xYVCS2l3su+K3lYcg5+cAAx9n0SFxpJl8zF5denq2QDsfM7NnQ==",
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-10.9.1.tgz",
"integrity": "sha512-B1wwkXk9UvU7LCBkPs8513WxOQ2H8Fo5p8HR1+Id9WmYE5+bd51vqN+MbrqvWczHCH2gwkREgHJN88tE0n1FCw==",
"license": "MIT",
"dependencies": {
"@graphql-typed-document-node/core": "^3.1.1",
@@ -184,38 +183,6 @@
"node": ">=18.0.0"
}
},
"node_modules/@nhost/stripe-graphql-js": {
"version": "1.3.0-beta.6",
"resolved": "https://registry.npmjs.org/@nhost/stripe-graphql-js/-/stripe-graphql-js-1.3.0-beta.6.tgz",
"integrity": "sha512-ImGZNn66UNelL+MtFyZOUB2djdBg9jbIMBRysdCeGgalbpQO/e4f5APcEiJKyZh0EESqpvnj9xSWYjdurEq3Rg==",
"license": "MIT",
"dependencies": {
"@pothos/core": "^3.41.0",
"graphql": "16.8.1",
"graphql-scalars": "^1.23.0",
"graphql-yoga": "^5.16.0",
"jsonwebtoken": "^9.0.2",
"stripe": "^11.18.0"
}
},
"node_modules/@nhost/stripe-graphql-js/node_modules/graphql": {
"version": "16.8.1",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz",
"integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==",
"license": "MIT",
"engines": {
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
}
},
"node_modules/@pothos/core": {
"version": "3.41.2",
"resolved": "https://registry.npmjs.org/@pothos/core/-/core-3.41.2.tgz",
"integrity": "sha512-iR1gqd93IyD/snTW47HwKSsRCrvnJaYwjVNcUG8BztZPqMxyJKPAnjPHAgu1XB82KEdysrNqIUnXqnzZIs08QA==",
"license": "ISC",
"peerDependencies": {
"graphql": ">=15.1.0"
}
},
"node_modules/@repeaterjs/repeater": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.6.tgz",
@@ -223,14 +190,14 @@
"license": "MIT"
},
"node_modules/@swc/core": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.0.tgz",
"integrity": "sha512-8SnJV+JV0rYbfSiEiUvYOmf62E7QwsEG+aZueqSlKoxFt0pw333+bgZSQXGUV6etXU88nxur0afVMaINujBMSw==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.9.2.tgz",
"integrity": "sha512-dYyEkO6mRYtZFpnOsnYzv9rY69fHAHoawYOjGOEcxk9WYtaJhowMdP/w6NcOKnz2G7GlZaenjkzkMa6ZeQeMsg==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@swc/counter": "^0.1.3",
"@swc/types": "^0.1.25"
"@swc/types": "^0.1.15"
},
"engines": {
"node": ">=10"
@@ -240,19 +207,19 @@
"url": "https://opencollective.com/swc"
},
"optionalDependencies": {
"@swc/core-darwin-arm64": "1.15.0",
"@swc/core-darwin-x64": "1.15.0",
"@swc/core-linux-arm-gnueabihf": "1.15.0",
"@swc/core-linux-arm64-gnu": "1.15.0",
"@swc/core-linux-arm64-musl": "1.15.0",
"@swc/core-linux-x64-gnu": "1.15.0",
"@swc/core-linux-x64-musl": "1.15.0",
"@swc/core-win32-arm64-msvc": "1.15.0",
"@swc/core-win32-ia32-msvc": "1.15.0",
"@swc/core-win32-x64-msvc": "1.15.0"
"@swc/core-darwin-arm64": "1.9.2",
"@swc/core-darwin-x64": "1.9.2",
"@swc/core-linux-arm-gnueabihf": "1.9.2",
"@swc/core-linux-arm64-gnu": "1.9.2",
"@swc/core-linux-arm64-musl": "1.9.2",
"@swc/core-linux-x64-gnu": "1.9.2",
"@swc/core-linux-x64-musl": "1.9.2",
"@swc/core-win32-arm64-msvc": "1.9.2",
"@swc/core-win32-ia32-msvc": "1.9.2",
"@swc/core-win32-x64-msvc": "1.9.2"
},
"peerDependencies": {
"@swc/helpers": ">=0.5.17"
"@swc/helpers": "*"
},
"peerDependenciesMeta": {
"@swc/helpers": {
@@ -261,9 +228,9 @@
}
},
"node_modules/@swc/core-darwin-arm64": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.0.tgz",
"integrity": "sha512-TBKWkbnShnEjlIbO4/gfsrIgAqHBVqgPWLbWmPdZ80bF393yJcLgkrb7bZEnJs6FCbSSuGwZv2rx1jDR2zo6YA==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.9.2.tgz",
"integrity": "sha512-nETmsCoY29krTF2PtspEgicb3tqw7Ci5sInTI03EU5zpqYbPjoPH99BVTjj0OsF53jP5MxwnLI5Hm21lUn1d6A==",
"cpu": [
"arm64"
],
@@ -277,9 +244,9 @@
}
},
"node_modules/@swc/core-darwin-x64": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.0.tgz",
"integrity": "sha512-f5JKL1v1H56CIZc1pVn4RGPOfnWqPwmuHdpf4wesvXunF1Bx85YgcspW5YxwqG5J9g3nPU610UFuExJXVUzOiQ==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.9.2.tgz",
"integrity": "sha512-9gD+bwBz8ZByjP6nZTXe/hzd0tySIAjpDHgkFiUrc+5zGF+rdTwhcNrzxNHJmy6mw+PW38jqII4uspFHUqqxuQ==",
"cpu": [
"x64"
],
@@ -293,9 +260,9 @@
}
},
"node_modules/@swc/core-linux-arm-gnueabihf": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.0.tgz",
"integrity": "sha512-duK6nG+WyuunnfsfiTUQdzC9Fk8cyDLqT9zyXvY2i2YgDu5+BH5W6wM5O4mDNCU5MocyB/SuF5YDF7XySnowiQ==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.9.2.tgz",
"integrity": "sha512-kYq8ief1Qrn+WmsTWAYo4r+Coul4dXN6cLFjiPZ29Cv5pyU+GFvSPAB4bEdMzwy99rCR0u2P10UExaeCjurjvg==",
"cpu": [
"arm"
],
@@ -309,9 +276,9 @@
}
},
"node_modules/@swc/core-linux-arm64-gnu": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.0.tgz",
"integrity": "sha512-ITe9iDtTRXM98B91rvyPP6qDVbhUBnmA/j4UxrHlMQ0RlwpqTjfZYZkD0uclOxSZ6qIrOj/X5CaoJlDUuQ0+Cw==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.9.2.tgz",
"integrity": "sha512-n0W4XiXlmEIVqxt+rD3ZpkogsEWUk1jJ+i5bQNgB+1JuWh0fBE8c/blDgTQXa0GB5lTPVDZQussgdNOCnAZwiA==",
"cpu": [
"arm64"
],
@@ -325,9 +292,9 @@
}
},
"node_modules/@swc/core-linux-arm64-musl": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.0.tgz",
"integrity": "sha512-Q5ldc2bzriuzYEoAuqJ9Vr3FyZhakk5hiwDbniZ8tlEXpbjBhbOleGf9/gkhLaouDnkNUEazFW9mtqwUTRdh7Q==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.9.2.tgz",
"integrity": "sha512-8xzrOmsyCC1zrx2Wzx/h8dVsdewO1oMCwBTLc1gSJ/YllZYTb04pNm6NsVbzUX2tKddJVRgSJXV10j/NECLwpA==",
"cpu": [
"arm64"
],
@@ -341,9 +308,9 @@
}
},
"node_modules/@swc/core-linux-x64-gnu": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.0.tgz",
"integrity": "sha512-pY4is+jEpOxlYCSnI+7N8Oxbap9TmTz5YT84tUvRTlOlTBwFAUlWFCX0FRwWJlsfP0TxbqhIe8dNNzlsEmJbXQ==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.9.2.tgz",
"integrity": "sha512-kZrNz/PjRQKcchWF6W292jk3K44EoVu1ad5w+zbS4jekIAxsM8WwQ1kd+yjUlN9jFcF8XBat5NKIs9WphJCVXg==",
"cpu": [
"x64"
],
@@ -357,9 +324,9 @@
}
},
"node_modules/@swc/core-linux-x64-musl": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.0.tgz",
"integrity": "sha512-zYEt5eT8y8RUpoe7t5pjpoOdGu+/gSTExj8PV86efhj6ugB3bPlj3Y85ogdW3WMVXr4NvwqvzdaYGCZfXzSyVg==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.9.2.tgz",
"integrity": "sha512-TTIpR4rjMkhX1lnFR+PSXpaL83TrQzp9znRdp2TzYrODlUd/R20zOwSo9vFLCyH6ZoD47bccY7QeGZDYT3nlRg==",
"cpu": [
"x64"
],
@@ -373,9 +340,9 @@
}
},
"node_modules/@swc/core-win32-arm64-msvc": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.0.tgz",
"integrity": "sha512-zC1rmOgFH5v2BCbByOazEqs0aRNpTdLRchDExfcCfgKgeaD+IdpUOqp7i3VG1YzkcnbuZjMlXfM0ugpt+CddoA==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.9.2.tgz",
"integrity": "sha512-+Eg2d4icItKC0PMjZxH7cSYFLWk0aIp94LNmOw6tPq0e69ax6oh10upeq0D1fjWsKLmOJAWEvnXlayZcijEXDw==",
"cpu": [
"arm64"
],
@@ -389,9 +356,9 @@
}
},
"node_modules/@swc/core-win32-ia32-msvc": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.0.tgz",
"integrity": "sha512-7t9U9KwMwQblkdJIH+zX1V4q1o3o41i0HNO+VlnAHT5o+5qHJ963PHKJ/pX3P2UlZnBCY465orJuflAN4rAP9A==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.9.2.tgz",
"integrity": "sha512-nLWBi4vZDdM/LkiQmPCakof8Dh1/t5EM7eudue04V1lIcqx9YHVRS3KMwEaCoHLGg0c312Wm4YgrWQd9vwZ5zQ==",
"cpu": [
"ia32"
],
@@ -405,9 +372,9 @@
}
},
"node_modules/@swc/core-win32-x64-msvc": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.0.tgz",
"integrity": "sha512-VE0Zod5vcs8iMLT64m5QS1DlTMXJFI/qSgtMDRx8rtZrnjt6/9NW8XUaiPJuRu8GluEO1hmHoyf1qlbY19gGSQ==",
"version": "1.9.2",
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.9.2.tgz",
"integrity": "sha512-ik/k+JjRJBFkXARukdU82tSVx0CbExFQoQ78qTO682esbYXzjdB5eLVkoUbwen299pnfr88Kn4kyIqFPTje8Xw==",
"cpu": [
"x64"
],
@@ -427,18 +394,18 @@
"license": "Apache-2.0"
},
"node_modules/@swc/types": {
"version": "0.1.25",
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz",
"integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==",
"version": "0.1.15",
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.15.tgz",
"integrity": "sha512-XKaZ+dzDIQ9Ot9o89oJQ/aluI17+VvUnIpYJTcZtvv1iYX6MzHh3Ik2CSR7MdPKpPwfZXHBeCingb2b4PoDVdw==",
"license": "Apache-2.0",
"dependencies": {
"@swc/counter": "^0.1.3"
}
},
"node_modules/@types/body-parser": {
"version": "1.19.6",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz",
"integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==",
"version": "1.19.5",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
"integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
"license": "MIT",
"dependencies": {
"@types/connect": "*",
@@ -455,21 +422,21 @@
}
},
"node_modules/@types/express": {
"version": "4.17.25",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz",
"integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==",
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
"license": "MIT",
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
"@types/qs": "*",
"@types/serve-static": "^1"
"@types/serve-static": "*"
}
},
"node_modules/@types/express-serve-static-core": {
"version": "4.19.7",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz",
"integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==",
"version": "4.19.6",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
"integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
"license": "MIT",
"dependencies": {
"@types/node": "*",
@@ -479,18 +446,17 @@
}
},
"node_modules/@types/http-errors": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz",
"integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
"license": "MIT"
},
"node_modules/@types/jsonwebtoken": {
"version": "9.0.10",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz",
"integrity": "sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==",
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz",
"integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==",
"license": "MIT",
"dependencies": {
"@types/ms": "*",
"@types/node": "*"
}
},
@@ -500,25 +466,19 @@
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
"license": "MIT"
},
"node_modules/@types/ms": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
"license": "MIT"
},
"node_modules/@types/node": {
"version": "24.10.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz",
"integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==",
"version": "22.9.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz",
"integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==",
"license": "MIT",
"dependencies": {
"undici-types": "~7.16.0"
"undici-types": "~6.19.8"
}
},
"node_modules/@types/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==",
"version": "6.9.17",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.17.tgz",
"integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==",
"license": "MIT"
},
"node_modules/@types/range-parser": {
@@ -528,35 +488,26 @@
"license": "MIT"
},
"node_modules/@types/send": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz",
"integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/serve-static": {
"version": "1.15.10",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz",
"integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==",
"license": "MIT",
"dependencies": {
"@types/http-errors": "*",
"@types/node": "*",
"@types/send": "<1"
}
},
"node_modules/@types/serve-static/node_modules/@types/send": {
"version": "0.17.6",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz",
"integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==",
"version": "0.17.4",
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
"license": "MIT",
"dependencies": {
"@types/mime": "^1",
"@types/node": "*"
}
},
"node_modules/@types/serve-static": {
"version": "1.15.7",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz",
"integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
"license": "MIT",
"dependencies": {
"@types/http-errors": "*",
"@types/node": "*",
"@types/send": "*"
}
},
"node_modules/@whatwg-node/disposablestack": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/@whatwg-node/disposablestack/-/disposablestack-0.0.6.tgz",
@@ -596,9 +547,9 @@
}
},
"node_modules/@whatwg-node/node-fetch": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.8.1.tgz",
"integrity": "sha512-cQmQEo7IsI0EPX9VrwygXVzrVlX43Jb7/DBZSmpnC7xH4xkyOnn/HykHpTaQk7TUs7zh59A5uTGqx3p2Ouzffw==",
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.8.0.tgz",
"integrity": "sha512-+z00GpWxKV/q8eMETwbdi80TcOoVEVZ4xSRkxYOZpn3kbV3nej5iViNzXVke/j3v4y1YpO5zMS/CVDIASvJnZQ==",
"license": "MIT",
"dependencies": {
"@fastify/busboy": "^3.1.1",
@@ -623,9 +574,9 @@
}
},
"node_modules/@whatwg-node/server": {
"version": "0.10.13",
"resolved": "https://registry.npmjs.org/@whatwg-node/server/-/server-0.10.13.tgz",
"integrity": "sha512-Otmxo+0mp8az3B48pLI1I4msNOXPIoP7TLm6h5wOEQmynqHt8oP9nR6NJUeJk6iI5OtFpQtkbJFwfGkmplvc3Q==",
"version": "0.10.12",
"resolved": "https://registry.npmjs.org/@whatwg-node/server/-/server-0.10.12.tgz",
"integrity": "sha512-MQIvvQyPvKGna586MzXhgwnEbGtbm7QtOgJ/KPd/tC70M/jbhd1xHdIQQbh3okBw+MrDF/EvaC2vB5oRC7QdlQ==",
"license": "MIT",
"dependencies": {
"@envelop/instrumentation": "^1.0.0",
@@ -644,35 +595,6 @@
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
"license": "BSD-3-Clause"
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/cross-inspect": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cross-inspect/-/cross-inspect-1.0.1.tgz",
@@ -686,9 +608,9 @@
}
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
"integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -711,20 +633,6 @@
"node": ">=4"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
@@ -734,119 +642,16 @@
"safe-buffer": "^5.0.1"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/graphql": {
"version": "16.12.0",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz",
"integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==",
"version": "16.11.0",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz",
"integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==",
"license": "MIT",
"peer": true,
"engines": {
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
}
},
"node_modules/graphql-scalars": {
"version": "1.25.0",
"resolved": "https://registry.npmjs.org/graphql-scalars/-/graphql-scalars-1.25.0.tgz",
"integrity": "sha512-b0xyXZeRFkne4Eq7NAnL400gStGqG/Sx9VqX0A05nHyEbv57UJnWKsjNnrpVqv5e/8N1MUxkt0wwcRXbiyKcFg==",
"license": "MIT",
"dependencies": {
"tslib": "^2.5.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/graphql-yoga": {
"version": "5.16.0",
"resolved": "https://registry.npmjs.org/graphql-yoga/-/graphql-yoga-5.16.0.tgz",
@@ -874,29 +679,11 @@
"graphql": "^15.2.0 || ^16.0.0"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
"node_modules/graphql-yoga/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC"
},
"node_modules/jose": {
"version": "4.15.9",
@@ -930,26 +717,26 @@
}
},
"node_modules/jwa": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
"integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"license": "MIT",
"dependencies": {
"buffer-equal-constant-time": "^1.0.1",
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/jwks-rsa": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz",
"integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz",
"integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==",
"license": "MIT",
"dependencies": {
"@types/express": "^4.17.20",
"@types/jsonwebtoken": "^9.0.4",
"@types/express": "^4.17.17",
"@types/jsonwebtoken": "^9.0.2",
"debug": "^4.3.4",
"jose": "^4.15.4",
"jose": "^4.14.6",
"limiter": "^1.1.5",
"lru-memoizer": "^2.2.0"
},
@@ -1021,22 +808,6 @@
"license": "MIT"
},
"node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC"
},
"node_modules/lru-memoizer": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz",
"integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==",
"license": "MIT",
"dependencies": {
"lodash.clonedeep": "^4.5.0",
"lru-cache": "6.0.0"
}
},
"node_modules/lru-memoizer/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==",
@@ -1048,13 +819,14 @@
"node": ">=10"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"node_modules/lru-memoizer": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz",
"integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
"dependencies": {
"lodash.clonedeep": "^4.5.0",
"lru-cache": "6.0.0"
}
},
"node_modules/ms": {
@@ -1063,33 +835,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/qs": {
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.1.0"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -1111,9 +856,9 @@
"license": "MIT"
},
"node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
"version": "7.6.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -1122,91 +867,6 @@
"node": ">=10"
}
},
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/stripe": {
"version": "11.18.0",
"resolved": "https://registry.npmjs.org/stripe/-/stripe-11.18.0.tgz",
"integrity": "sha512-OUA32uhNoSoM6wOodyFbV+3IBCoO140uzdXmBArQ0S88D4EbH91xl2v+Ml1sKalcFKUBadHLeHfU/p9AbsOfGw==",
"license": "MIT",
"dependencies": {
"@types/node": ">=8.1.0",
"qs": "^6.11.0"
},
"engines": {
"node": ">=12.*"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -1214,9 +874,9 @@
"license": "0BSD"
},
"node_modules/undici-types": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"license": "MIT"
},
"node_modules/urlpattern-polyfill": {

View File

@@ -10,7 +10,6 @@
"author": "",
"license": "ISC",
"dependencies": {
"@nhost/stripe-graphql-js": "^1.3.0-beta.6",
"@swc/core": "^1.6.5",
"graphql-yoga": "^5.16.0",
"jsonwebtoken": "^9.0.2",

View File

@@ -0,0 +1,653 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
'@swc/core':
specifier: ^1.6.5
version: 1.6.5
graphql-yoga:
specifier: ^5.16.0
version: 5.16.0(graphql@16.11.0)
jsonwebtoken:
specifier: ^9.0.2
version: 9.0.2
jwks-rsa:
specifier: ^3.1.0
version: 3.1.0
packages:
'@envelop/core@5.3.2':
resolution: {integrity: sha512-06Mu7fmyKzk09P2i2kHpGfItqLLgCq7uO5/nX4fc/iHMplWPNuAx4iYR+WXUQoFHDnP6EUbceQNQ5iyeMz9f3g==}
engines: {node: '>=18.0.0'}
'@envelop/instrumentation@1.0.0':
resolution: {integrity: sha512-cxgkB66RQB95H3X27jlnxCRNTmPuSTgmBAq6/4n2Dtv4hsk4yz8FadA1ggmd0uZzvKqWD6CR+WFgTjhDqg7eyw==}
engines: {node: '>=18.0.0'}
'@envelop/types@5.2.1':
resolution: {integrity: sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg==}
engines: {node: '>=18.0.0'}
'@fastify/busboy@3.2.0':
resolution: {integrity: sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==}
'@graphql-tools/executor@1.4.9':
resolution: {integrity: sha512-SAUlDT70JAvXeqV87gGzvDzUGofn39nvaVcVhNf12Dt+GfWHtNNO/RCn/Ea4VJaSLGzraUd41ObnN3i80EBU7w==}
engines: {node: '>=16.0.0'}
peerDependencies:
graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
'@graphql-tools/merge@9.1.1':
resolution: {integrity: sha512-BJ5/7Y7GOhTuvzzO5tSBFL4NGr7PVqTJY3KeIDlVTT8YLcTXtBR+hlrC3uyEym7Ragn+zyWdHeJ9ev+nRX1X2w==}
engines: {node: '>=16.0.0'}
peerDependencies:
graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
'@graphql-tools/schema@10.0.25':
resolution: {integrity: sha512-/PqE8US8kdQ7lB9M5+jlW8AyVjRGCKU7TSktuW3WNKSKmDO0MK1wakvb5gGdyT49MjAIb4a3LWxIpwo5VygZuw==}
engines: {node: '>=16.0.0'}
peerDependencies:
graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
'@graphql-tools/utils@10.9.1':
resolution: {integrity: sha512-B1wwkXk9UvU7LCBkPs8513WxOQ2H8Fo5p8HR1+Id9WmYE5+bd51vqN+MbrqvWczHCH2gwkREgHJN88tE0n1FCw==}
engines: {node: '>=16.0.0'}
peerDependencies:
graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
'@graphql-typed-document-node/core@3.2.0':
resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==}
peerDependencies:
graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
'@graphql-yoga/logger@2.0.1':
resolution: {integrity: sha512-Nv0BoDGLMg9QBKy9cIswQ3/6aKaKjlTh87x3GiBg2Z4RrjyrM48DvOOK0pJh1C1At+b0mUIM67cwZcFTDLN4sA==}
engines: {node: '>=18.0.0'}
'@graphql-yoga/subscription@5.0.5':
resolution: {integrity: sha512-oCMWOqFs6QV96/NZRt/ZhTQvzjkGB4YohBOpKM4jH/lDT4qb7Lex/aGCxpi/JD9njw3zBBtMqxbaC22+tFHVvw==}
engines: {node: '>=18.0.0'}
'@graphql-yoga/typed-event-target@3.0.2':
resolution: {integrity: sha512-ZpJxMqB+Qfe3rp6uszCQoag4nSw42icURnBRfFYSOmTgEeOe4rD0vYlbA8spvCu2TlCesNTlEN9BLWtQqLxabA==}
engines: {node: '>=18.0.0'}
'@repeaterjs/repeater@3.0.6':
resolution: {integrity: sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==}
'@swc/core-darwin-arm64@1.6.5':
resolution: {integrity: sha512-RGQhMdni2v1/ANQ/2K+F+QYdzaucekYBewZcX1ogqJ8G5sbPaBdYdDN1qQ4kHLCIkPtGP6qC7c71qPEqL2RidQ==}
engines: {node: '>=10'}
cpu: [arm64]
os: [darwin]
'@swc/core-darwin-x64@1.6.5':
resolution: {integrity: sha512-/pSN0/Jtcbbb9+ovS9rKxR3qertpFAM3OEJr/+Dh/8yy7jK5G5EFPIrfsw/7Q5987ERPIJIH6BspK2CBB2tgcg==}
engines: {node: '>=10'}
cpu: [x64]
os: [darwin]
'@swc/core-linux-arm-gnueabihf@1.6.5':
resolution: {integrity: sha512-B0g/dROCE747RRegs/jPHuKJgwXLracDhnqQa80kFdgWEMjlcb7OMCgs5OX86yJGRS4qcYbiMGD0Pp7Kbqn3yw==}
engines: {node: '>=10'}
cpu: [arm]
os: [linux]
'@swc/core-linux-arm64-gnu@1.6.5':
resolution: {integrity: sha512-W8meapgXTq8AOtSvDG4yKR8ant2WWD++yOjgzAleB5VAC+oC+aa8YJROGxj8HepurU8kurqzcialwoMeq5SZZQ==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
'@swc/core-linux-arm64-musl@1.6.5':
resolution: {integrity: sha512-jyCKqoX50Fg8rJUQqh4u5PqnE7nqYKXHjVH2WcYr114/MU21zlsI+YL6aOQU1XP8bJQ2gPQ1rnlnGJdEHiKS/w==}
engines: {node: '>=10'}
cpu: [arm64]
os: [linux]
'@swc/core-linux-x64-gnu@1.6.5':
resolution: {integrity: sha512-G6HmUn/RRIlXC0YYFfBz2qh6OZkHS/KUPkhoG4X9ADcgWXXjOFh6JrefwsYj8VBAJEnr5iewzjNfj+nztwHaeA==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
'@swc/core-linux-x64-musl@1.6.5':
resolution: {integrity: sha512-AQpBjBnelQDSbeTJA50AXdS6+CP66LsXIMNTwhPSgUfE7Bx1ggZV11Fsi4Q5SGcs6a8Qw1cuYKN57ZfZC5QOuA==}
engines: {node: '>=10'}
cpu: [x64]
os: [linux]
'@swc/core-win32-arm64-msvc@1.6.5':
resolution: {integrity: sha512-MZTWM8kUwS30pVrtbzSGEXtek46aXNb/mT9D6rsS7NvOuv2w+qZhjR1rzf4LNbbn5f8VnR4Nac1WIOYZmfC5ng==}
engines: {node: '>=10'}
cpu: [arm64]
os: [win32]
'@swc/core-win32-ia32-msvc@1.6.5':
resolution: {integrity: sha512-WZdu4gISAr3yOm1fVwKhhk6+MrP7kVX0KMP7+ZQFTN5zXQEiDSDunEJKVgjMVj3vlR+6mnAqa/L0V9Qa8+zKlQ==}
engines: {node: '>=10'}
cpu: [ia32]
os: [win32]
'@swc/core-win32-x64-msvc@1.6.5':
resolution: {integrity: sha512-ezXgucnMTzlFIxQZw7ls/5r2hseFaRoDL04cuXUOs97E8r+nJSmFsRQm/ygH5jBeXNo59nyZCalrjJAjwfgACA==}
engines: {node: '>=10'}
cpu: [x64]
os: [win32]
'@swc/core@1.6.5':
resolution: {integrity: sha512-tyVvUK/HDOUUsK6/GmWvnqUtD9oDpPUA4f7f7JCOV8hXxtfjMtAZeBKf93yrB1XZet69TDR7EN0hFC6i4MF0Ig==}
engines: {node: '>=10'}
peerDependencies:
'@swc/helpers': '*'
peerDependenciesMeta:
'@swc/helpers':
optional: true
'@swc/counter@0.1.3':
resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
'@swc/types@0.1.9':
resolution: {integrity: sha512-qKnCno++jzcJ4lM4NTfYifm1EFSCeIfKiAHAfkENZAV5Kl9PjJIyd2yeeVv6c/2CckuLyv2NmRC5pv6pm2WQBg==}
'@types/body-parser@1.19.5':
resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
'@types/connect@3.4.38':
resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
'@types/express-serve-static-core@4.19.6':
resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==}
'@types/express@4.17.21':
resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==}
'@types/http-errors@2.0.4':
resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==}
'@types/jsonwebtoken@9.0.7':
resolution: {integrity: sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==}
'@types/mime@1.3.5':
resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
'@types/node@22.9.0':
resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==}
'@types/qs@6.9.17':
resolution: {integrity: sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==}
'@types/range-parser@1.2.7':
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
'@types/send@0.17.4':
resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==}
'@types/serve-static@1.15.7':
resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==}
'@whatwg-node/disposablestack@0.0.6':
resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==}
engines: {node: '>=18.0.0'}
'@whatwg-node/events@0.1.2':
resolution: {integrity: sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ==}
engines: {node: '>=18.0.0'}
'@whatwg-node/fetch@0.10.11':
resolution: {integrity: sha512-eR8SYtf9Nem1Tnl0IWrY33qJ5wCtIWlt3Fs3c6V4aAaTFLtkEQErXu3SSZg/XCHrj9hXSJ8/8t+CdMk5Qec/ZA==}
engines: {node: '>=18.0.0'}
'@whatwg-node/node-fetch@0.8.0':
resolution: {integrity: sha512-+z00GpWxKV/q8eMETwbdi80TcOoVEVZ4xSRkxYOZpn3kbV3nej5iViNzXVke/j3v4y1YpO5zMS/CVDIASvJnZQ==}
engines: {node: '>=18.0.0'}
'@whatwg-node/promise-helpers@1.3.2':
resolution: {integrity: sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA==}
engines: {node: '>=16.0.0'}
'@whatwg-node/server@0.10.12':
resolution: {integrity: sha512-MQIvvQyPvKGna586MzXhgwnEbGtbm7QtOgJ/KPd/tC70M/jbhd1xHdIQQbh3okBw+MrDF/EvaC2vB5oRC7QdlQ==}
engines: {node: '>=18.0.0'}
buffer-equal-constant-time@1.0.1:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
cross-inspect@1.0.1:
resolution: {integrity: sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==}
engines: {node: '>=16.0.0'}
debug@4.3.7:
resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dset@3.1.4:
resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==}
engines: {node: '>=4'}
ecdsa-sig-formatter@1.0.11:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
graphql-yoga@5.16.0:
resolution: {integrity: sha512-/R2dJea7WgvNlXRU4F8iFwWd95Qn1mN+R+yC8XBs1wKjUzr0Pvv8cGYtt6UUcVHw5CiDEtu7iQY5oOe3sDAWCQ==}
engines: {node: '>=18.0.0'}
peerDependencies:
graphql: ^15.2.0 || ^16.0.0
graphql@16.11.0:
resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==}
engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0}
jose@4.15.9:
resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==}
jsonwebtoken@9.0.2:
resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==}
engines: {node: '>=12', npm: '>=6'}
jwa@1.4.1:
resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==}
jwks-rsa@3.1.0:
resolution: {integrity: sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==}
engines: {node: '>=14'}
jws@3.2.2:
resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==}
limiter@1.1.5:
resolution: {integrity: sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==}
lodash.clonedeep@4.5.0:
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
lodash.includes@4.3.0:
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
lodash.isboolean@3.0.3:
resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==}
lodash.isinteger@4.0.4:
resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==}
lodash.isnumber@3.0.3:
resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==}
lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
lodash.isstring@4.0.1:
resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==}
lodash.once@4.1.1:
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
lru-cache@6.0.0:
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
engines: {node: '>=10'}
lru-memoizer@2.3.0:
resolution: {integrity: sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==}
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
semver@7.6.3:
resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
engines: {node: '>=10'}
hasBin: true
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
undici-types@6.19.8:
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
urlpattern-polyfill@10.1.0:
resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==}
yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
snapshots:
'@envelop/core@5.3.2':
dependencies:
'@envelop/instrumentation': 1.0.0
'@envelop/types': 5.2.1
'@whatwg-node/promise-helpers': 1.3.2
tslib: 2.8.1
'@envelop/instrumentation@1.0.0':
dependencies:
'@whatwg-node/promise-helpers': 1.3.2
tslib: 2.8.1
'@envelop/types@5.2.1':
dependencies:
'@whatwg-node/promise-helpers': 1.3.2
tslib: 2.8.1
'@fastify/busboy@3.2.0': {}
'@graphql-tools/executor@1.4.9(graphql@16.11.0)':
dependencies:
'@graphql-tools/utils': 10.9.1(graphql@16.11.0)
'@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0)
'@repeaterjs/repeater': 3.0.6
'@whatwg-node/disposablestack': 0.0.6
'@whatwg-node/promise-helpers': 1.3.2
graphql: 16.11.0
tslib: 2.8.1
'@graphql-tools/merge@9.1.1(graphql@16.11.0)':
dependencies:
'@graphql-tools/utils': 10.9.1(graphql@16.11.0)
graphql: 16.11.0
tslib: 2.8.1
'@graphql-tools/schema@10.0.25(graphql@16.11.0)':
dependencies:
'@graphql-tools/merge': 9.1.1(graphql@16.11.0)
'@graphql-tools/utils': 10.9.1(graphql@16.11.0)
graphql: 16.11.0
tslib: 2.8.1
'@graphql-tools/utils@10.9.1(graphql@16.11.0)':
dependencies:
'@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0)
'@whatwg-node/promise-helpers': 1.3.2
cross-inspect: 1.0.1
dset: 3.1.4
graphql: 16.11.0
tslib: 2.8.1
'@graphql-typed-document-node/core@3.2.0(graphql@16.11.0)':
dependencies:
graphql: 16.11.0
'@graphql-yoga/logger@2.0.1':
dependencies:
tslib: 2.8.1
'@graphql-yoga/subscription@5.0.5':
dependencies:
'@graphql-yoga/typed-event-target': 3.0.2
'@repeaterjs/repeater': 3.0.6
'@whatwg-node/events': 0.1.2
tslib: 2.8.1
'@graphql-yoga/typed-event-target@3.0.2':
dependencies:
'@repeaterjs/repeater': 3.0.6
tslib: 2.8.1
'@repeaterjs/repeater@3.0.6': {}
'@swc/core-darwin-arm64@1.6.5':
optional: true
'@swc/core-darwin-x64@1.6.5':
optional: true
'@swc/core-linux-arm-gnueabihf@1.6.5':
optional: true
'@swc/core-linux-arm64-gnu@1.6.5':
optional: true
'@swc/core-linux-arm64-musl@1.6.5':
optional: true
'@swc/core-linux-x64-gnu@1.6.5':
optional: true
'@swc/core-linux-x64-musl@1.6.5':
optional: true
'@swc/core-win32-arm64-msvc@1.6.5':
optional: true
'@swc/core-win32-ia32-msvc@1.6.5':
optional: true
'@swc/core-win32-x64-msvc@1.6.5':
optional: true
'@swc/core@1.6.5':
dependencies:
'@swc/counter': 0.1.3
'@swc/types': 0.1.9
optionalDependencies:
'@swc/core-darwin-arm64': 1.6.5
'@swc/core-darwin-x64': 1.6.5
'@swc/core-linux-arm-gnueabihf': 1.6.5
'@swc/core-linux-arm64-gnu': 1.6.5
'@swc/core-linux-arm64-musl': 1.6.5
'@swc/core-linux-x64-gnu': 1.6.5
'@swc/core-linux-x64-musl': 1.6.5
'@swc/core-win32-arm64-msvc': 1.6.5
'@swc/core-win32-ia32-msvc': 1.6.5
'@swc/core-win32-x64-msvc': 1.6.5
'@swc/counter@0.1.3': {}
'@swc/types@0.1.9':
dependencies:
'@swc/counter': 0.1.3
'@types/body-parser@1.19.5':
dependencies:
'@types/connect': 3.4.38
'@types/node': 22.9.0
'@types/connect@3.4.38':
dependencies:
'@types/node': 22.9.0
'@types/express-serve-static-core@4.19.6':
dependencies:
'@types/node': 22.9.0
'@types/qs': 6.9.17
'@types/range-parser': 1.2.7
'@types/send': 0.17.4
'@types/express@4.17.21':
dependencies:
'@types/body-parser': 1.19.5
'@types/express-serve-static-core': 4.19.6
'@types/qs': 6.9.17
'@types/serve-static': 1.15.7
'@types/http-errors@2.0.4': {}
'@types/jsonwebtoken@9.0.7':
dependencies:
'@types/node': 22.9.0
'@types/mime@1.3.5': {}
'@types/node@22.9.0':
dependencies:
undici-types: 6.19.8
'@types/qs@6.9.17': {}
'@types/range-parser@1.2.7': {}
'@types/send@0.17.4':
dependencies:
'@types/mime': 1.3.5
'@types/node': 22.9.0
'@types/serve-static@1.15.7':
dependencies:
'@types/http-errors': 2.0.4
'@types/node': 22.9.0
'@types/send': 0.17.4
'@whatwg-node/disposablestack@0.0.6':
dependencies:
'@whatwg-node/promise-helpers': 1.3.2
tslib: 2.8.1
'@whatwg-node/events@0.1.2':
dependencies:
tslib: 2.8.1
'@whatwg-node/fetch@0.10.11':
dependencies:
'@whatwg-node/node-fetch': 0.8.0
urlpattern-polyfill: 10.1.0
'@whatwg-node/node-fetch@0.8.0':
dependencies:
'@fastify/busboy': 3.2.0
'@whatwg-node/disposablestack': 0.0.6
'@whatwg-node/promise-helpers': 1.3.2
tslib: 2.8.1
'@whatwg-node/promise-helpers@1.3.2':
dependencies:
tslib: 2.8.1
'@whatwg-node/server@0.10.12':
dependencies:
'@envelop/instrumentation': 1.0.0
'@whatwg-node/disposablestack': 0.0.6
'@whatwg-node/fetch': 0.10.11
'@whatwg-node/promise-helpers': 1.3.2
tslib: 2.8.1
buffer-equal-constant-time@1.0.1: {}
cross-inspect@1.0.1:
dependencies:
tslib: 2.8.1
debug@4.3.7:
dependencies:
ms: 2.1.3
dset@3.1.4: {}
ecdsa-sig-formatter@1.0.11:
dependencies:
safe-buffer: 5.2.1
graphql-yoga@5.16.0(graphql@16.11.0):
dependencies:
'@envelop/core': 5.3.2
'@envelop/instrumentation': 1.0.0
'@graphql-tools/executor': 1.4.9(graphql@16.11.0)
'@graphql-tools/schema': 10.0.25(graphql@16.11.0)
'@graphql-tools/utils': 10.9.1(graphql@16.11.0)
'@graphql-yoga/logger': 2.0.1
'@graphql-yoga/subscription': 5.0.5
'@whatwg-node/fetch': 0.10.11
'@whatwg-node/promise-helpers': 1.3.2
'@whatwg-node/server': 0.10.12
dset: 3.1.4
graphql: 16.11.0
lru-cache: 10.4.3
tslib: 2.8.1
graphql@16.11.0: {}
jose@4.15.9: {}
jsonwebtoken@9.0.2:
dependencies:
jws: 3.2.2
lodash.includes: 4.3.0
lodash.isboolean: 3.0.3
lodash.isinteger: 4.0.4
lodash.isnumber: 3.0.3
lodash.isplainobject: 4.0.6
lodash.isstring: 4.0.1
lodash.once: 4.1.1
ms: 2.1.3
semver: 7.6.3
jwa@1.4.1:
dependencies:
buffer-equal-constant-time: 1.0.1
ecdsa-sig-formatter: 1.0.11
safe-buffer: 5.2.1
jwks-rsa@3.1.0:
dependencies:
'@types/express': 4.17.21
'@types/jsonwebtoken': 9.0.7
debug: 4.3.7
jose: 4.15.9
limiter: 1.1.5
lru-memoizer: 2.3.0
transitivePeerDependencies:
- supports-color
jws@3.2.2:
dependencies:
jwa: 1.4.1
safe-buffer: 5.2.1
limiter@1.1.5: {}
lodash.clonedeep@4.5.0: {}
lodash.includes@4.3.0: {}
lodash.isboolean@3.0.3: {}
lodash.isinteger@4.0.4: {}
lodash.isnumber@3.0.3: {}
lodash.isplainobject@4.0.6: {}
lodash.isstring@4.0.1: {}
lodash.once@4.1.1: {}
lru-cache@10.4.3: {}
lru-cache@6.0.0:
dependencies:
yallist: 4.0.0
lru-memoizer@2.3.0:
dependencies:
lodash.clonedeep: 4.5.0
lru-cache: 6.0.0
ms@2.1.3: {}
safe-buffer@5.2.1: {}
semver@7.6.3: {}
tslib@2.8.1: {}
undici-types@6.19.8: {}
urlpattern-polyfill@10.1.0: {}
yallist@4.0.0: {}

View File

@@ -18,9 +18,3 @@
timeout_seconds: 60
customization: {}
comment: Remote schema example
- name: stripe
definition:
url: '{{NHOST_FUNCTIONS_URL}}/graphql/stripe'
timeout_seconds: 60
customization: {}
comment: ""

View File

@@ -7,10 +7,6 @@ value = 'Sayonara'
name = 'NODE_ENV'
value = 'production'
[[global.environment]]
name = 'STRIPE_SECRET_KEY'
value = '{{ secrets.STRIPE_SECRET_KEY }}'
[hasura]
version = 'v2.46.0-ce'
adminSecret = '{{ secrets.HASURA_GRAPHQL_ADMIN_SECRET }}'

View File

@@ -1,3 +1,15 @@
## [@nhost/dashboard@2.41.0] - 2025-11-04
### 🚀 Features
- *(auth)* Added endpoints to retrieve and refresh oauth2 providers' tokens (#3614)
- *(dashboard)* Get github repositories from github itself (#3640)
### 🐛 Bug Fixes
- *(dashboard)* Update SQL editor to use correct hasura migrations API URL (#3645)
# Changelog
All notable changes to this project will be documented in this file.

View File

@@ -15,7 +15,7 @@ function getCspHeader() {
return [
"default-src 'self' *.nhost.run wss://*.nhost.run nhost.run wss://nhost.run",
"script-src 'self' 'unsafe-eval' cdn.segment.com js.stripe.com challenges.cloudflare.com googletagmanager.com",
"connect-src 'self' *.nhost.run wss://*.nhost.run nhost.run wss://nhost.run discord.com api.segment.io api.segment.com cdn.segment.com nhost.zendesk.com",
"connect-src 'self' *.nhost.run wss://*.nhost.run nhost.run wss://nhost.run discord.com api.segment.io api.segment.com cdn.segment.com nhost.zendesk.com api.github.com",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' blob: data: github.com avatars.githubusercontent.com s.gravatar.com *.nhost.run nhost.run",
"font-src 'self' data:",
@@ -126,4 +126,4 @@ module.exports = withBundleAnalyzer({
},
];
},
});
});

View File

@@ -23,7 +23,7 @@ export default function SocialProvidersSettings() {
if (typeof window !== 'undefined') {
return nhost.auth.signInProviderURL('github', {
connect: token,
redirectTo: `${window.location.origin}/account`,
redirectTo: `${window.location.origin}/account?signinProvider=github`,
});
}
return '';

View File

@@ -3,18 +3,21 @@ import {
useGithubAuthentication,
type UseGithubAuthenticationHookProps,
} from '@/features/auth/AuthProviders/Github/hooks/useGithubAuthentication';
import { cn } from '@/lib/utils';
import { SiGithub } from '@icons-pack/react-simple-icons';
interface Props extends UseGithubAuthenticationHookProps {
buttonText?: string;
withAnonId?: boolean;
redirectTo?: string;
className?: string;
}
function GithubAuthButton({
buttonText = 'Continue with GitHub',
withAnonId = false,
redirectTo,
className,
}: Props) {
const { mutate: signInWithGithub, isLoading } = useGithubAuthentication({
withAnonId,
@@ -22,7 +25,10 @@ function GithubAuthButton({
});
return (
<Button
className="gap-2 !bg-white text-sm+ !text-black hover:ring-2 hover:ring-white hover:ring-opacity-50 disabled:!text-black disabled:!text-opacity-60"
className={cn(
'gap-2 !bg-white text-sm+ !text-black hover:ring-2 hover:ring-white hover:ring-opacity-50 disabled:!text-black disabled:!text-opacity-60',
className,
)}
disabled={isLoading}
loading={isLoading}
onClick={() => signInWithGithub()}

View File

@@ -30,8 +30,8 @@ function useGithubAuthentication({
};
}
const redirectURl = nhost.auth.signInProviderURL('github', options);
window.location.href = redirectURl;
const redirectURL = nhost.auth.signInProviderURL('github', options);
window.location.href = redirectURL;
},
{
onError: () => {

View File

@@ -2,7 +2,7 @@ import { GithubAuthButton } from '@/features/auth/AuthProviders/Github/component
import { useHostName } from '@/features/orgs/projects/common/hooks/useHostName';
function SignInWithGithub() {
const redirectTo = useHostName();
const redirectTo = `${useHostName()}?signinProvider=github`;
return (
<GithubAuthButton
redirectTo={redirectTo}

View File

@@ -1,8 +1,11 @@
import { GithubAuthButton } from '@/features/auth/AuthProviders/Github/components/GithubAuthButton';
import { useHostName } from '@/features/orgs/projects/common/hooks/useHostName';
function SignUpWithGithub() {
const redirectTo = `${useHostName()}?signinProvider=github`;
return (
<GithubAuthButton
redirectTo={redirectTo}
buttonText="Sign Up with GitHub"
errorText="An error occurred while trying to sign up using GitHub. Please try again."
/>

View File

@@ -1,3 +1,4 @@
import { ErrorMessage } from '@/components/presentational/ErrorMessage';
import { RetryableErrorBoundary } from '@/components/presentational/RetryableErrorBoundary';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { Avatar } from '@/components/ui/v2/Avatar';
@@ -11,14 +12,33 @@ import { Link } from '@/components/ui/v2/Link';
import { List } from '@/components/ui/v2/List';
import { ListItem } from '@/components/ui/v2/ListItem';
import { Text } from '@/components/ui/v2/Text';
import { GithubAuthButton } from '@/features/auth/AuthProviders/Github/components/GithubAuthButton';
import { useHostName } from '@/features/orgs/projects/common/hooks/useHostName';
import { EditRepositorySettings } from '@/features/orgs/projects/git/common/components/EditRepositorySettings';
import { useGetGithubRepositoriesQuery } from '@/generated/graphql';
import {
getGitHubToken,
saveGitHubToken,
} from '@/features/orgs/projects/git/common/utils';
import { useCurrentOrg } from '@/features/orgs/projects/hooks/useCurrentOrg';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useGetAuthUserProvidersQuery } from '@/generated/graphql';
import { useAccessToken } from '@/hooks/useAccessToken';
import { GitHubAPIError, listGitHubInstallationRepos } from '@/lib/github';
import { isEmptyValue } from '@/lib/utils';
import { getToastStyleProps } from '@/utils/constants/settings';
import { nhost } from '@/utils/nhost';
import { Divider } from '@mui/material';
import debounce from 'lodash.debounce';
import NavLink from 'next/link';
import type { ChangeEvent } from 'react';
import { Fragment, useEffect, useMemo, useState } from 'react';
import toast from 'react-hot-toast';
export type ConnectGitHubModalState = 'CONNECTING' | 'EDITING';
export type ConnectGitHubModalState =
| 'CONNECTING'
| 'EDITING'
| 'EXPIRED_GITHUB_SESSION'
| 'GITHUB_CONNECTION_REQUIRED';
export interface ConnectGitHubModalProps {
/**
@@ -28,18 +48,153 @@ export interface ConnectGitHubModalProps {
close?: VoidFunction;
}
interface GitHubData {
githubAppInstallations: Array<{
id: number;
accountLogin?: string;
accountAvatarUrl?: string;
}>;
githubRepositories: Array<{
id: number;
node_id: string;
name: string;
fullName: string;
githubAppInstallation: {
accountLogin?: string;
accountAvatarUrl?: string;
};
}>;
}
export default function ConnectGitHubModal({ close }: ConnectGitHubModalProps) {
const [filter, setFilter] = useState('');
const [ConnectGitHubModalState, setConnectGitHubModalState] =
useState<ConnectGitHubModalState>('CONNECTING');
const [selectedRepoId, setSelectedRepoId] = useState<string | null>(null);
const [githubData, setGithubData] = useState<GitHubData | null>(null);
const [loading, setLoading] = useState(true);
const { project, loading: loadingProject } = useProject();
const { org, loading: loadingOrg } = useCurrentOrg();
const hostname = useHostName();
const token = useAccessToken();
const {
data,
loading: loadingGithubConnected,
error: errorGithubConnected,
} = useGetAuthUserProvidersQuery();
const { data, loading, error, startPolling } =
useGetGithubRepositoriesQuery();
const githubProvider = data?.authUserProviders?.find(
(item) => item.providerId === 'github',
);
const getGitHubConnectUrl = () => {
if (typeof window !== 'undefined') {
return nhost.auth.signInProviderURL('github', {
connect: token,
redirectTo: `${window.location.origin}?signinProvider=github&state=signin-refresh:${org.slug}:${project?.subdomain}`,
});
}
return '';
};
useEffect(() => {
startPolling(2000);
}, [startPolling]);
if (loadingGithubConnected) {
return;
}
const fetchGitHubData = async () => {
try {
setLoading(true);
if (isEmptyValue(githubProvider)) {
setConnectGitHubModalState('GITHUB_CONNECTION_REQUIRED');
setLoading(false);
return;
}
const githubToken = getGitHubToken();
if (
!githubToken?.authUserProviderId ||
githubProvider!.id !== githubToken.authUserProviderId
) {
setConnectGitHubModalState('EXPIRED_GITHUB_SESSION');
setLoading(false);
return;
}
const { refreshToken, expiresAt: expiresAtString } = githubToken;
let accessToken = githubToken?.accessToken;
const expiresAt = new Date(expiresAtString).getTime();
const currentTime = Date.now();
const expiresAtMargin = 60 * 1000;
if (expiresAt - currentTime < expiresAtMargin) {
if (!refreshToken) {
setConnectGitHubModalState('EXPIRED_GITHUB_SESSION');
setLoading(false);
return;
}
const refreshResponse = await nhost.auth.refreshProviderToken(
'github',
{ refreshToken },
);
if (!refreshResponse.body) {
setConnectGitHubModalState('EXPIRED_GITHUB_SESSION');
setLoading(false);
return;
}
saveGitHubToken({
...refreshResponse.body,
authUserProviderId: githubProvider!.id,
});
accessToken = refreshResponse.body.accessToken;
}
const installations = await listGitHubInstallationRepos(accessToken);
const transformedData = {
githubAppInstallations: installations.map((item) => ({
id: item.installation.id,
accountLogin: item.installation.account?.login,
accountAvatarUrl: item.installation.account?.avatar_url,
})),
githubRepositories: installations.flatMap((item) =>
item.repositories.map((repo) => ({
id: repo.id,
node_id: repo.node_id,
name: repo.name,
fullName: repo.full_name,
githubAppInstallation: {
accountLogin: item.installation.account?.login,
accountAvatarUrl: item.installation.account?.avatar_url,
},
})),
),
};
setGithubData(transformedData);
setLoading(false);
} catch (err) {
console.error('Error fetching GitHub data:', err);
if (err instanceof GitHubAPIError && err.status === 401) {
setConnectGitHubModalState('EXPIRED_GITHUB_SESSION');
setLoading(false);
return;
}
toast.error(err?.message, getToastStyleProps());
close?.();
}
};
fetchGitHubData();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [githubProvider, loadingGithubConnected]);
const handleSelectAnotherRepository = () => {
setSelectedRepoId(null);
@@ -56,13 +211,91 @@ export default function ConnectGitHubModal({ close }: ConnectGitHubModalProps) {
useEffect(() => () => handleFilterChange.cancel(), [handleFilterChange]);
if (error) {
throw error;
if (errorGithubConnected instanceof Error) {
return (
<div className="px-1 md:w-[653px]">
<div className="flex flex-col">
<div className="mx-auto text-center">
<div className="mx-auto h-8 w-8">
<GitHubIcon className="h-8 w-8" />
</div>
</div>
<div className="flex flex-col gap-2">
<Text className="mt-2.5 text-center text-lg font-medium">
Error fetching GitHub data
</Text>
<ErrorMessage>{errorGithubConnected.message}</ErrorMessage>
</div>
</div>
</div>
);
}
if (loading) {
if (loading || loadingProject || loadingOrg || loadingGithubConnected) {
return (
<ActivityIndicator delay={500} label="Loading GitHub repositories..." />
<div className="px-1 md:w-[653px]">
<div className="flex flex-col">
<div className="mx-auto text-center">
<div className="mx-auto h-8 w-8">
<GitHubIcon className="h-8 w-8" />
</div>
</div>
<div>
<Text className="mt-2.5 text-center text-lg font-medium">
Loading repositories...
</Text>
<Text className="text-center text-xs font-normal" color="secondary">
Fetching your GitHub repositories
</Text>
<div className="mb-2 mt-6 flex w-full">
<Input placeholder="Search..." fullWidth disabled value="" />
</div>
</div>
<div className="flex h-import items-center justify-center border-y">
<ActivityIndicator delay={0} label="" />
</div>
</div>
</div>
);
}
if (ConnectGitHubModalState === 'GITHUB_CONNECTION_REQUIRED') {
return (
<div className="flex flex-col items-center justify-center gap-5 px-1 py-1 md:w-[653px]">
<p className="text-center text-foreground">
You need to connect your GitHub account to continue.
</p>
<NavLink
href={getGitHubConnectUrl()}
passHref
rel="noreferrer noopener"
legacyBehavior
>
<Button
className="w-full max-w-72"
variant="outlined"
color="secondary"
startIcon={<GitHubIcon />}
>
Connect to GitHub
</Button>
</NavLink>
</div>
);
}
if (ConnectGitHubModalState === 'EXPIRED_GITHUB_SESSION') {
return (
<div className="flex w-full flex-col items-center justify-center gap-5 px-1 py-1 md:w-[653px]">
<p className="text-center text-foreground">
Please sign in with GitHub to continue.
</p>
<GithubAuthButton
redirectTo={`${hostname}?signinProvider=github&state=signin-refresh:${org.slug}:${project!.subdomain}`}
buttonText="Sign in with GitHub"
className="w-full max-w-72 gap-2 !bg-primary !text-white disabled:!text-white disabled:!text-opacity-60 dark:!bg-white dark:!text-black dark:disabled:!text-black"
/>
</div>
);
}
@@ -78,25 +311,27 @@ export default function ConnectGitHubModal({ close }: ConnectGitHubModalProps) {
);
}
const { githubAppInstallations } = data || {};
const { githubAppInstallations } = githubData || {};
const filteredGitHubAppInstallations = data?.githubAppInstallations.filter(
(githubApp) => !!githubApp.accountLogin,
);
const filteredGitHubAppInstallations =
githubData?.githubAppInstallations.filter(
(githubApp) => !!githubApp.accountLogin,
);
const filteredGitHubRepositories = data?.githubRepositories.filter(
const filteredGitHubRepositories = githubData?.githubRepositories.filter(
(repo) => !!repo.githubAppInstallation,
);
const filteredGitHubAppInstallationsNullValues =
data?.githubAppInstallations.filter((githubApp) => !!githubApp.accountLogin)
.length === 0;
githubData?.githubAppInstallations.filter(
(githubApp) => !!githubApp.accountLogin,
).length === 0;
const faultyGitHubInstallation =
githubAppInstallations?.length === 0 ||
filteredGitHubAppInstallationsNullValues;
const noRepositoriesAdded = data?.githubRepositories.length === 0;
const noRepositoriesAdded = githubData?.githubRepositories.length === 0;
if (faultyGitHubInstallation) {
return (
@@ -115,11 +350,7 @@ export default function ConnectGitHubModal({ close }: ConnectGitHubModalProps) {
</div>
<Button
href={process.env.NEXT_PUBLIC_GITHUB_APP_INSTALL_URL}
// Both `target` and `rel` are available when `href` is set. This is
// a limitation of MUI.
// @ts-ignore
target="_blank"
href={`${process.env.NEXT_PUBLIC_GITHUB_APP_INSTALL_URL}?state=install-github-app:${org.slug}:${project!.subdomain}`}
rel="noreferrer noopener"
endIcon={<ArrowSquareOutIcon className="h-4 w-4" />}
>
@@ -179,8 +410,7 @@ export default function ConnectGitHubModal({ close }: ConnectGitHubModalProps) {
</List>
<Link
href={process.env.NEXT_PUBLIC_GITHUB_APP_INSTALL_URL}
target="_blank"
href={`${process.env.NEXT_PUBLIC_GITHUB_APP_INSTALL_URL}?state=install-github-app:${org.slug}:${project!.subdomain}`}
rel="noreferrer noopener"
underline="hover"
className="grid grid-flow-col items-center justify-start gap-1"
@@ -199,8 +429,8 @@ export default function ConnectGitHubModal({ close }: ConnectGitHubModalProps) {
className="text-center text-xs font-normal"
color="secondary"
>
Showing repositories from {data?.githubAppInstallations.length}{' '}
GitHub account(s)
Showing repositories from{' '}
{githubData?.githubAppInstallations.length} GitHub account(s)
</Text>
<div className="mb-2 mt-6 flex w-full">
<Input
@@ -226,7 +456,7 @@ export default function ConnectGitHubModal({ close }: ConnectGitHubModalProps) {
<Button
variant="borderless"
color="primary"
onClick={() => setSelectedRepoId(repo.id)}
onClick={() => setSelectedRepoId(repo.node_id)}
>
Connect
</Button>
@@ -268,8 +498,7 @@ export default function ConnectGitHubModal({ close }: ConnectGitHubModalProps) {
Do you miss a repository, or do you need to connect another GitHub
account?{' '}
<Link
href={process.env.NEXT_PUBLIC_GITHUB_APP_INSTALL_URL}
target="_blank"
href={`${process.env.NEXT_PUBLIC_GITHUB_APP_INSTALL_URL}?state=install-github-app:${org.slug}:${project!.subdomain}`}
rel="noreferrer noopener"
className="text-xs font-medium"
underline="hover"

View File

@@ -6,7 +6,7 @@ import { FormProvider, useForm } from 'react-hook-form';
export interface EditRepositorySettingsProps {
close?: () => void;
openConnectGithubModal?: () => void;
selectedRepoId?: string;
selectedRepoId: string;
connectGithubModalState?: ConnectGitHubModalState;
handleSelectAnotherRepository?: () => void;
}

View File

@@ -6,14 +6,14 @@ import { Text } from '@/components/ui/v2/Text';
import { EditRepositoryAndBranchSettings } from '@/features/orgs/projects/git/common/components/EditRepositoryAndBranchSettings';
import type { EditRepositorySettingsFormData } from '@/features/orgs/projects/git/common/components/EditRepositorySettings';
import { useProject } from '@/features/orgs/projects/hooks/useProject';
import { useUpdateApplicationMutation } from '@/generated/graphql';
import { useConnectGithubRepoMutation } from '@/generated/graphql';
import { analytics } from '@/lib/segment';
import { discordAnnounce } from '@/utils/discordAnnounce';
import { triggerToast } from '@/utils/toast';
import { useFormContext } from 'react-hook-form';
export interface EditRepositorySettingsModalProps {
selectedRepoId?: string;
selectedRepoId: string;
close?: () => void;
handleSelectAnotherRepository?: () => void;
}
@@ -33,45 +33,29 @@ export default function EditRepositorySettingsModal({
const { project, refetch: refetchProject } = useProject();
const [updateApp, { loading }] = useUpdateApplicationMutation();
const [connectGithubRepo, { loading }] = useConnectGithubRepoMutation();
const handleEditGitHubIntegration = async (
data: EditRepositorySettingsFormData,
) => {
try {
if (!project?.githubRepository || selectedRepoId) {
await updateApp({
variables: {
appId: project?.id,
app: {
githubRepositoryId: selectedRepoId,
repositoryProductionBranch: data.productionBranch,
nhostBaseFolder: data.repoBaseFolder,
},
},
});
await connectGithubRepo({
variables: {
appID: project?.id,
githubNodeID: selectedRepoId,
productionBranch: data.productionBranch,
baseFolder: data.repoBaseFolder,
},
});
if (selectedRepoId) {
analytics.track('Project Connected to GitHub', {
projectId: project?.id,
projectName: project?.name,
projectSubdomain: project?.subdomain,
repositoryId: selectedRepoId,
productionBranch: data.productionBranch,
baseFolder: data.repoBaseFolder,
});
}
} else {
await updateApp({
variables: {
appId: project.id,
app: {
repositoryProductionBranch: data.productionBranch,
nhostBaseFolder: data.repoBaseFolder,
},
},
});
}
analytics.track('Project Connected to GitHub', {
projectId: project?.id,
projectName: project?.name,
projectSubdomain: project?.subdomain,
repositoryId: selectedRepoId,
productionBranch: data.productionBranch,
baseFolder: data.repoBaseFolder,
});
await refetchProject();

View File

@@ -0,0 +1,13 @@
mutation ConnectGithubRepo(
$appID: uuid!
$githubNodeID: String!
$productionBranch: String!
$baseFolder: String!
) {
connectGithubRepo(
appID: $appID
githubNodeID: $githubNodeID
productionBranch: $productionBranch
baseFolder: $baseFolder
)
}

View File

@@ -2,12 +2,12 @@ import { useDialog } from '@/components/common/DialogProvider';
import { ConnectGitHubModal } from '@/features/orgs/projects/git/common/components/ConnectGitHubModal';
export default function useGitHubModal() {
const { openAlertDialog } = useDialog();
const { openAlertDialog, closeAlertDialog } = useDialog();
function openGitHubModal() {
openAlertDialog({
title: 'Connect GitHub Repository',
payload: <ConnectGitHubModal />,
payload: <ConnectGitHubModal close={closeAlertDialog} />,
props: {
hidePrimaryAction: true,
hideSecondaryAction: true,

View File

@@ -0,0 +1,23 @@
import { isNotEmptyValue } from '@/lib/utils';
import type { ProviderSession } from '@nhost/nhost-js/auth';
const githubProviderTokenKey = 'nhost_provider_tokens_github';
export type GitHubProviderToken = ProviderSession & {
authUserProviderId?: string;
};
export function saveGitHubToken(token: GitHubProviderToken) {
localStorage.setItem(githubProviderTokenKey, JSON.stringify(token));
}
export function getGitHubToken() {
const token = localStorage.getItem(githubProviderTokenKey);
return isNotEmptyValue(token)
? (JSON.parse(token) as GitHubProviderToken)
: null;
}
export function clearGitHubToken() {
localStorage.removeItem(githubProviderTokenKey);
}

View File

@@ -0,0 +1 @@
export * from './githubTokens';

View File

@@ -0,0 +1,99 @@
/**
* Custom error class for GitHub API errors that preserves HTTP status codes
*/
export class GitHubAPIError extends Error {
constructor(
message: string,
public status: number,
public statusText: string,
) {
super(message);
this.name = 'GitHubAPIError';
}
}
interface GitHubAppInstallation {
id: number;
account?: {
login: string;
avatar_url: string;
[key: string]: unknown;
}
[key: string]: unknown;
}
/**
* Lists all GitHub App installations accessible to the user
* @param accessToken - The GitHub OAuth access token
* @returns Array of app installations
*/
export async function listGitHubAppInstallations(accessToken: string): Promise<GitHubAppInstallation[]> {
const response = await fetch('https://api.github.com/user/installations', {
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
},
cache: 'no-cache',
});
if (!response.ok) {
throw new GitHubAPIError(
`Failed to list installations: ${response.statusText}`,
response.status,
response.statusText
);
}
const data = await response.json();
return data.installations;
}
interface GitHubRepo {
id: number;
node_id: string;
name: string;
full_name: string;
[key: string]: unknown;
}
/**
* Lists all repositories accessible through GitHub App installations
* @param accessToken - The GitHub OAuth access token
* @returns Array of repositories grouped by installation
*/
export async function listGitHubInstallationRepos(accessToken: string) {
const installations = await listGitHubAppInstallations(accessToken);
const reposByInstallation = await Promise.all(
installations.map(async (installation) => {
const response = await fetch(
`https://api.github.com/user/installations/${installation.id}/repositories`,
{
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
},
cache: 'no-cache',
}
);
if (!response.ok) {
throw new GitHubAPIError(
`Failed to list repos for installation ${installation.id}: ${response.statusText}`,
response.status,
response.statusText
);
}
const data = await response.json();
return {
installation,
repositories: data.repositories as GitHubRepo[],
};
})
);
return reposByInstallation;
}

View File

@@ -77,12 +77,12 @@ function MyApp({
<CacheProvider value={emotionCache}>
<NhostProvider nhost={nhost}>
<AuthProvider>
<NhostApolloProvider
fetchPolicy="cache-and-network"
nhost={nhost}
connectToDevTools={process.env.NEXT_PUBLIC_ENV === 'dev'}
>
<NhostApolloProvider
fetchPolicy="cache-and-network"
nhost={nhost}
connectToDevTools={process.env.NEXT_PUBLIC_ENV === 'dev'}
>
<AuthProvider>
<UIProvider>
<Toaster position="bottom-center" />
<ThemeProvider
@@ -106,8 +106,8 @@ function MyApp({
</RetryableErrorBoundary>
</ThemeProvider>
</UIProvider>
</NhostApolloProvider>
</AuthProvider>
</AuthProvider>
</NhostApolloProvider>
</NhostProvider>
</CacheProvider>
</QueryClientProvider>

View File

@@ -1,87 +0,0 @@
import { LoadingScreen } from '@/components/presentational/LoadingScreen';
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
import { nhost } from '@/utils/nhost';
import { useAuth } from '@/providers/Auth';
import { useRouter } from 'next/router';
import type { ComponentType } from 'react';
import { useEffect, useState } from 'react';
export function authProtected<P extends JSX.IntrinsicAttributes>(
Comp: ComponentType<P>,
) {
return function AuthProtected(props: P) {
const router = useRouter();
const { isAuthenticated, isLoading } = useAuth();
useEffect(() => {
if (isLoading || isAuthenticated) {
return;
}
router.push('/signin');
}, [isLoading, isAuthenticated, router]);
if (isLoading) {
return <LoadingScreen />;
}
return <Comp {...props} />;
};
}
function Page() {
const [state, setState] = useState({
error: null,
loading: true,
});
const router = useRouter();
const { installation_id: installationId } = router.query;
useEffect(() => {
async function installGithubApp() {
try {
await nhost.functions.fetch('/client/github-app-installation', {
method: 'POST',
body: JSON.stringify({
installationId,
}),
headers: {
'Content-Type': 'application/json',
},
});
} catch (error) {
setState({
error,
loading: false,
});
return;
}
setState({
error: null,
loading: false,
});
window.close();
}
// run in async manner
installGithubApp();
}, [installationId]);
if (state.loading) {
return <ActivityIndicator delay={500} label="Loading..." />;
}
if (state.error) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw state.error;
}
return <div>GitHub connection completed. You can close this tab.</div>;
}
export default authProtected(Page);

View File

@@ -1,12 +1,38 @@
import { Container } from '@/components/layout/Container';
import { OrgLayout } from '@/features/orgs/layout/OrgLayout';
import { SettingsLayout } from '@/features/orgs/layout/SettingsLayout';
import { useGitHubModal } from '@/features/orgs/projects/git/common/hooks/useGitHubModal';
import { BaseDirectorySettings } from '@/features/orgs/projects/git/settings/components/BaseDirectorySettings';
import { DeploymentBranchSettings } from '@/features/orgs/projects/git/settings/components/DeploymentBranchSettings';
import { GitConnectionSettings } from '@/features/orgs/projects/git/settings/components/GitConnectionSettings';
import type { ReactElement } from 'react';
import { useRouter } from 'next/router';
import { useCallback, useEffect, type ReactElement } from 'react';
export default function GitSettingsPage() {
const router = useRouter();
const { pathname, replace, isReady: isRouterReady } = router;
const { 'github-modal': githubModal, ...remainingQuery } = router.query;
const { openGitHubModal } = useGitHubModal();
const removeQueryParamsFromURL = useCallback(() => {
replace({ pathname, query: remainingQuery }, undefined, {
shallow: true,
});
}, [replace, remainingQuery, pathname]);
useEffect(() => {
if (!isRouterReady) {
return;
}
if (typeof githubModal === 'string') {
removeQueryParamsFromURL();
openGitHubModal();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [githubModal, isRouterReady]);
return (
<Container
className="grid max-w-5xl grid-flow-row gap-y-6 bg-transparent"

View File

@@ -1,19 +1,27 @@
import {
clearGitHubToken,
saveGitHubToken,
type GitHubProviderToken,
} from '@/features/orgs/projects/git/common/utils';
import { isNotEmptyValue } from '@/lib/utils';
import { useNhostClient } from '@/providers/nhost/';
import { useGetAuthUserProvidersLazyQuery } from '@/utils/__generated__/graphql';
import { getToastStyleProps } from '@/utils/constants/settings';
import { type Session } from '@nhost/nhost-js/auth';
import { useRouter } from 'next/router';
import {
type PropsWithChildren,
useCallback,
useEffect,
useMemo,
useState,
type PropsWithChildren,
} from 'react';
import { toast } from 'react-hot-toast';
import { AuthContext, type AuthContextType } from './AuthContext';
function AuthProvider({ children }: PropsWithChildren) {
const nhost = useNhostClient();
const [getAuthUserProviders] = useGetAuthUserProvidersLazyQuery();
const {
query,
isReady: isRouterReady,
@@ -21,7 +29,15 @@ function AuthProvider({ children }: PropsWithChildren) {
pathname,
push,
} = useRouter();
const { refreshToken, error, errorDescription, ...remainingQuery } = query;
const {
refreshToken,
error,
errorDescription,
signinProvider,
state,
provider_state: providerState,
...remainingQuery
} = query;
const [session, setSession] = useState<Session | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [isSigningOut, setIsSigningOut] = useState(false);
@@ -55,7 +71,6 @@ function AuthProvider({ children }: PropsWithChildren) {
return;
}
setIsLoading(true);
// reset state if we have just signed out
setIsSigningOut(false);
if (refreshToken && typeof refreshToken === 'string') {
const sessionResponse = await nhost.auth.refreshToken({
@@ -63,24 +78,84 @@ function AuthProvider({ children }: PropsWithChildren) {
});
setSession(sessionResponse.body);
removeQueryParamsFromURL();
if (sessionResponse.body && signinProvider === 'github') {
try {
const providerTokensResponse =
await nhost.auth.getProviderTokens(signinProvider);
if (providerTokensResponse.body) {
const { data } = await getAuthUserProviders();
const githubProvider = data?.authUserProviders?.find(
(provider) => provider.providerId === 'github',
);
const newGitHubToken: GitHubProviderToken =
providerTokensResponse.body;
if (isNotEmptyValue(githubProvider?.id)) {
newGitHubToken.authUserProviderId = githubProvider!.id;
}
saveGitHubToken(newGitHubToken);
}
} catch (err) {
console.error('Failed to fetch provider tokens:', err);
}
}
} else {
const currentSession = nhost.getUserSession();
setSession(currentSession);
}
// handle OAuth redirect errors (e.g., error=unverified-user)
if (
state &&
typeof state === 'string' &&
state.startsWith('signin-refresh:')
) {
const [, orgSlug, projectSubdomain] = state.split(':');
removeQueryParamsFromURL();
await push(
`/orgs/${orgSlug}/projects/${projectSubdomain}/settings/git?github-modal`,
);
}
if (typeof error === 'string') {
if (error === 'unverified-user') {
removeQueryParamsFromURL();
await push('/email/verify');
} else {
const description =
typeof errorDescription === 'string'
? errorDescription
: 'An error occurred during the sign-in process. Please try again.';
toast.error(description, getToastStyleProps());
removeQueryParamsFromURL();
await push('/signin');
switch (error) {
case 'unverified-user': {
removeQueryParamsFromURL();
await push('/email/verify');
break;
}
/*
* If the state isn't handled by Hasura auth, it returns `invalid-state`.
* However, we check the provider_state search param to see if it has this format:
* `install-github-app:<org-slug>:<project-subdomain>`.
* If it has this format, that means that we connected to GitHub in `/settings/git`,
* thus we need to show the connect GitHub modal again.
* Otherwise, we fall through to default error handling.
*/
case 'invalid-state': {
if (
isNotEmptyValue(providerState) &&
typeof providerState === 'string' &&
providerState.startsWith('install-github-app:')
) {
const [, orgSlug, projectSubdomain] = providerState.split(':');
removeQueryParamsFromURL();
await push(
`/orgs/${orgSlug}/projects/${projectSubdomain}/settings/git?github-modal`,
);
break;
}
// Fall through to default error handling if state search param is invalid
}
default: {
const description =
typeof errorDescription === 'string'
? errorDescription
: 'An error occurred during the sign-in process. Please try again.';
toast.error(description, getToastStyleProps());
removeQueryParamsFromURL();
await push('/signin');
}
}
}
@@ -103,6 +178,7 @@ function AuthProvider({ children }: PropsWithChildren) {
nhost.auth.signOut({
refreshToken: session!.refreshToken,
});
clearGitHubToken();
await push('/signin');
},

View File

@@ -108,16 +108,16 @@ function Providers({ children }: PropsWithChildren<{}>) {
<QueryClientProvider client={queryClient}>
<CacheProvider value={emotionCache}>
<NhostProvider nhost={nhost}>
<AuthProvider>
<ApolloProvider client={mockClient}>
<ApolloProvider client={mockClient}>
<AuthProvider>
<UIProvider>
<Toaster position="bottom-center" />
<ThemeProvider theme={theme}>
<DialogProvider>{children}</DialogProvider>
</ThemeProvider>
</UIProvider>
</ApolloProvider>
</AuthProvider>
</AuthProvider>
</ApolloProvider>
</NhostProvider>
</CacheProvider>
</QueryClientProvider>

View File

@@ -3118,7 +3118,9 @@ export type ConfigSystemConfigPostgres = {
database: Scalars['String'];
disk?: Maybe<ConfigSystemConfigPostgresDisk>;
enabled?: Maybe<Scalars['Boolean']>;
encryptColumnKey?: Maybe<Scalars['String']>;
majorVersion?: Maybe<Scalars['String']>;
oldEncryptColumnKey?: Maybe<Scalars['String']>;
};
export type ConfigSystemConfigPostgresComparisonExp = {
@@ -3129,7 +3131,9 @@ export type ConfigSystemConfigPostgresComparisonExp = {
database?: InputMaybe<ConfigStringComparisonExp>;
disk?: InputMaybe<ConfigSystemConfigPostgresDiskComparisonExp>;
enabled?: InputMaybe<ConfigBooleanComparisonExp>;
encryptColumnKey?: InputMaybe<ConfigStringComparisonExp>;
majorVersion?: InputMaybe<ConfigStringComparisonExp>;
oldEncryptColumnKey?: InputMaybe<ConfigStringComparisonExp>;
};
export type ConfigSystemConfigPostgresConnectionString = {
@@ -3193,7 +3197,9 @@ export type ConfigSystemConfigPostgresInsertInput = {
database: Scalars['String'];
disk?: InputMaybe<ConfigSystemConfigPostgresDiskInsertInput>;
enabled?: InputMaybe<Scalars['Boolean']>;
encryptColumnKey?: InputMaybe<Scalars['String']>;
majorVersion?: InputMaybe<Scalars['String']>;
oldEncryptColumnKey?: InputMaybe<Scalars['String']>;
};
export type ConfigSystemConfigPostgresUpdateInput = {
@@ -3201,7 +3207,9 @@ export type ConfigSystemConfigPostgresUpdateInput = {
database?: InputMaybe<Scalars['String']>;
disk?: InputMaybe<ConfigSystemConfigPostgresDiskUpdateInput>;
enabled?: InputMaybe<Scalars['Boolean']>;
encryptColumnKey?: InputMaybe<Scalars['String']>;
majorVersion?: InputMaybe<Scalars['String']>;
oldEncryptColumnKey?: InputMaybe<Scalars['String']>;
};
export type ConfigSystemConfigUpdateInput = {
@@ -4426,6 +4434,7 @@ export type Apps = {
billingDedicatedCompute?: Maybe<Billing_Dedicated_Compute>;
/** An object relationship */
billingSubscriptions?: Maybe<Billing_Subscriptions>;
/** main entrypoint to the configuration */
config?: Maybe<ConfigConfig>;
createdAt: Scalars['timestamptz'];
/** An object relationship */
@@ -11094,6 +11103,7 @@ export type Deployments = {
commitSHA: Scalars['String'];
commitUserAvatarUrl?: Maybe<Scalars['String']>;
commitUserName?: Maybe<Scalars['String']>;
createdAt: Scalars['timestamptz'];
deploymentEndedAt?: Maybe<Scalars['timestamptz']>;
/** An array relationship */
deploymentLogs: Array<DeploymentLogs>;
@@ -11191,6 +11201,7 @@ export type Deployments_Bool_Exp = {
commitSHA?: InputMaybe<String_Comparison_Exp>;
commitUserAvatarUrl?: InputMaybe<String_Comparison_Exp>;
commitUserName?: InputMaybe<String_Comparison_Exp>;
createdAt?: InputMaybe<Timestamptz_Comparison_Exp>;
deploymentEndedAt?: InputMaybe<Timestamptz_Comparison_Exp>;
deploymentLogs?: InputMaybe<DeploymentLogs_Bool_Exp>;
deploymentLogs_aggregate?: InputMaybe<DeploymentLogs_Aggregate_Bool_Exp>;
@@ -11222,6 +11233,7 @@ export type Deployments_Insert_Input = {
commitSHA?: InputMaybe<Scalars['String']>;
commitUserAvatarUrl?: InputMaybe<Scalars['String']>;
commitUserName?: InputMaybe<Scalars['String']>;
createdAt?: InputMaybe<Scalars['timestamptz']>;
deploymentEndedAt?: InputMaybe<Scalars['timestamptz']>;
deploymentLogs?: InputMaybe<DeploymentLogs_Arr_Rel_Insert_Input>;
deploymentStartedAt?: InputMaybe<Scalars['timestamptz']>;
@@ -11246,6 +11258,7 @@ export type Deployments_Max_Fields = {
commitSHA?: Maybe<Scalars['String']>;
commitUserAvatarUrl?: Maybe<Scalars['String']>;
commitUserName?: Maybe<Scalars['String']>;
createdAt?: Maybe<Scalars['timestamptz']>;
deploymentEndedAt?: Maybe<Scalars['timestamptz']>;
deploymentStartedAt?: Maybe<Scalars['timestamptz']>;
deploymentStatus?: Maybe<Scalars['String']>;
@@ -11268,6 +11281,7 @@ export type Deployments_Max_Order_By = {
commitSHA?: InputMaybe<Order_By>;
commitUserAvatarUrl?: InputMaybe<Order_By>;
commitUserName?: InputMaybe<Order_By>;
createdAt?: InputMaybe<Order_By>;
deploymentEndedAt?: InputMaybe<Order_By>;
deploymentStartedAt?: InputMaybe<Order_By>;
deploymentStatus?: InputMaybe<Order_By>;
@@ -11291,6 +11305,7 @@ export type Deployments_Min_Fields = {
commitSHA?: Maybe<Scalars['String']>;
commitUserAvatarUrl?: Maybe<Scalars['String']>;
commitUserName?: Maybe<Scalars['String']>;
createdAt?: Maybe<Scalars['timestamptz']>;
deploymentEndedAt?: Maybe<Scalars['timestamptz']>;
deploymentStartedAt?: Maybe<Scalars['timestamptz']>;
deploymentStatus?: Maybe<Scalars['String']>;
@@ -11313,6 +11328,7 @@ export type Deployments_Min_Order_By = {
commitSHA?: InputMaybe<Order_By>;
commitUserAvatarUrl?: InputMaybe<Order_By>;
commitUserName?: InputMaybe<Order_By>;
createdAt?: InputMaybe<Order_By>;
deploymentEndedAt?: InputMaybe<Order_By>;
deploymentStartedAt?: InputMaybe<Order_By>;
deploymentStatus?: InputMaybe<Order_By>;
@@ -11359,6 +11375,7 @@ export type Deployments_Order_By = {
commitSHA?: InputMaybe<Order_By>;
commitUserAvatarUrl?: InputMaybe<Order_By>;
commitUserName?: InputMaybe<Order_By>;
createdAt?: InputMaybe<Order_By>;
deploymentEndedAt?: InputMaybe<Order_By>;
deploymentLogs_aggregate?: InputMaybe<DeploymentLogs_Aggregate_Order_By>;
deploymentStartedAt?: InputMaybe<Order_By>;
@@ -11393,6 +11410,8 @@ export enum Deployments_Select_Column {
/** column name */
CommitUserName = 'commitUserName',
/** column name */
CreatedAt = 'createdAt',
/** column name */
DeploymentEndedAt = 'deploymentEndedAt',
/** column name */
DeploymentStartedAt = 'deploymentStartedAt',
@@ -11427,6 +11446,7 @@ export type Deployments_Set_Input = {
commitSHA?: InputMaybe<Scalars['String']>;
commitUserAvatarUrl?: InputMaybe<Scalars['String']>;
commitUserName?: InputMaybe<Scalars['String']>;
createdAt?: InputMaybe<Scalars['timestamptz']>;
deploymentEndedAt?: InputMaybe<Scalars['timestamptz']>;
deploymentStartedAt?: InputMaybe<Scalars['timestamptz']>;
deploymentStatus?: InputMaybe<Scalars['String']>;
@@ -11457,6 +11477,7 @@ export type Deployments_Stream_Cursor_Value_Input = {
commitSHA?: InputMaybe<Scalars['String']>;
commitUserAvatarUrl?: InputMaybe<Scalars['String']>;
commitUserName?: InputMaybe<Scalars['String']>;
createdAt?: InputMaybe<Scalars['timestamptz']>;
deploymentEndedAt?: InputMaybe<Scalars['timestamptz']>;
deploymentStartedAt?: InputMaybe<Scalars['timestamptz']>;
deploymentStatus?: InputMaybe<Scalars['String']>;
@@ -11485,6 +11506,8 @@ export enum Deployments_Update_Column {
/** column name */
CommitUserName = 'commitUserName',
/** column name */
CreatedAt = 'createdAt',
/** column name */
DeploymentEndedAt = 'deploymentEndedAt',
/** column name */
DeploymentStartedAt = 'deploymentStartedAt',
@@ -13067,6 +13090,7 @@ export type Mutation_Root = {
billingUpgradeFreeOrganization: Scalars['String'];
billingUploadReports: Scalars['Boolean'];
changeDatabaseVersion: Scalars['Boolean'];
connectGithubRepo: Scalars['Boolean'];
/** delete single row from the table: "announcements_read" */
deleteAnnouncementRead?: Maybe<Announcements_Read>;
/** delete data from the table: "announcements_read" */
@@ -13968,6 +13992,15 @@ export type Mutation_RootChangeDatabaseVersionArgs = {
};
/** mutation root */
export type Mutation_RootConnectGithubRepoArgs = {
appID: Scalars['uuid'];
baseFolder: Scalars['String'];
githubNodeID: Scalars['String'];
productionBranch: Scalars['String'];
};
/** mutation root */
export type Mutation_RootDeleteAnnouncementReadArgs = {
id: Scalars['uuid'];
@@ -27517,6 +27550,16 @@ export type ResetDatabasePasswordMutationVariables = Exact<{
export type ResetDatabasePasswordMutation = { __typename?: 'mutation_root', resetPostgresPassword: boolean };
export type ConnectGithubRepoMutationVariables = Exact<{
appID: Scalars['uuid'];
githubNodeID: Scalars['String'];
productionBranch: Scalars['String'];
baseFolder: Scalars['String'];
}>;
export type ConnectGithubRepoMutation = { __typename?: 'mutation_root', connectGithubRepo: boolean };
export type GetHasuraSettingsQueryVariables = Exact<{
appId: Scalars['uuid'];
}>;
@@ -29446,6 +29489,45 @@ export function useResetDatabasePasswordMutation(baseOptions?: Apollo.MutationHo
export type ResetDatabasePasswordMutationHookResult = ReturnType<typeof useResetDatabasePasswordMutation>;
export type ResetDatabasePasswordMutationResult = Apollo.MutationResult<ResetDatabasePasswordMutation>;
export type ResetDatabasePasswordMutationOptions = Apollo.BaseMutationOptions<ResetDatabasePasswordMutation, ResetDatabasePasswordMutationVariables>;
export const ConnectGithubRepoDocument = gql`
mutation ConnectGithubRepo($appID: uuid!, $githubNodeID: String!, $productionBranch: String!, $baseFolder: String!) {
connectGithubRepo(
appID: $appID
githubNodeID: $githubNodeID
productionBranch: $productionBranch
baseFolder: $baseFolder
)
}
`;
export type ConnectGithubRepoMutationFn = Apollo.MutationFunction<ConnectGithubRepoMutation, ConnectGithubRepoMutationVariables>;
/**
* __useConnectGithubRepoMutation__
*
* To run a mutation, you first call `useConnectGithubRepoMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useConnectGithubRepoMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [connectGithubRepoMutation, { data, loading, error }] = useConnectGithubRepoMutation({
* variables: {
* appID: // value for 'appID'
* githubNodeID: // value for 'githubNodeID'
* productionBranch: // value for 'productionBranch'
* baseFolder: // value for 'baseFolder'
* },
* });
*/
export function useConnectGithubRepoMutation(baseOptions?: Apollo.MutationHookOptions<ConnectGithubRepoMutation, ConnectGithubRepoMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<ConnectGithubRepoMutation, ConnectGithubRepoMutationVariables>(ConnectGithubRepoDocument, options);
}
export type ConnectGithubRepoMutationHookResult = ReturnType<typeof useConnectGithubRepoMutation>;
export type ConnectGithubRepoMutationResult = Apollo.MutationResult<ConnectGithubRepoMutation>;
export type ConnectGithubRepoMutationOptions = Apollo.BaseMutationOptions<ConnectGithubRepoMutation, ConnectGithubRepoMutationVariables>;
export const GetHasuraSettingsDocument = gql`
query GetHasuraSettings($appId: uuid!) {
config(appID: $appId, resolve: false) {

View File

Before

Width:  |  Height:  |  Size: 559 KiB

After

Width:  |  Height:  |  Size: 559 KiB

View File

@@ -1,7 +1,7 @@
import { createServer } from 'http'
import { type Context, createStripeGraphQLServer } from '../src/index'
import { Context, createStripeGraphQLServer } from '../src/index'
const isAllowed = (_stripeCustomerId: string, context: Context) => {
const isAllowed = (stripeCustomerId: string, context: Context) => {
const { isAdmin } = context
if (isAdmin) {

View File

@@ -1,6 +1,6 @@
{
"name": "@nhost/stripe-graphql-js",
"version": "1.3.0-beta.6",
"version": "1.2.0",
"description": "Stripe GraphQL API",
"license": "MIT",
"keywords": [
@@ -17,8 +17,8 @@
"type": "git",
"url": "https://github.com/nhost/nhost.git"
},
"main": "dist/src/index.js",
"types": "dist/src/index.d.ts",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"source": "src/index.ts",
"files": [
"dist",
@@ -43,16 +43,15 @@
"@pothos/core": "^3.41.0",
"graphql": "16.8.1",
"graphql-scalars": "^1.23.0",
"graphql-yoga": "^5.16.0",
"graphql-yoga": "^3.9.1",
"jsonwebtoken": "^9.0.2",
"stripe": "^11.18.0"
},
"devDependencies": {
"@types/jsonwebtoken": "^9.0.6",
"@types/node": "^20.14.8",
"@types/node": "^18.19.28",
"dotenv": "^16.4.5",
"ts-node-dev": "^2.0.0",
"tslib": "^2.8.1",
"typescript": "^5.8.3"
"typescript": "^4.9.5"
}
}
}

View File

@@ -18,11 +18,11 @@ const createStripeGraphQLServer = ({
// check if using correct `x-hasura-admin-secret` header
const adminSecretFromHeader = request.headers.get('x-hasura-admin-secret')
const adminSecret = process.env['NHOST_ADMIN_SECRET']
const adminSecret = process.env.NHOST_ADMIN_SECRET
// check if the request is from Hasura
const nhostWebhookSecretFromHeader = request.headers.get('x-nhost-webhook-secret')
const nhostWebhookSecret = process.env['NHOST_WEBHOOK_SECRET']
const nhostWebhookSecret = process.env.NHOST_WEBHOOK_SECRET
const role = request.headers.get('x-hasura-role')
// variables

View File

@@ -3,11 +3,11 @@ import Stripe from 'stripe'
import { UserHasuraClaims } from './types'
if (!process.env['STRIPE_SECRET_KEY']) {
if (!process.env.STRIPE_SECRET_KEY) {
throw new Error('STRIPE_SECRET_KEY env var is not set')
}
export const stripe = new Stripe(process.env['STRIPE_SECRET_KEY'], {
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2022-11-15'
})
@@ -21,11 +21,11 @@ export const getUserClaims = (req: Request): UserHasuraClaims | undefined => {
return undefined
}
if (!process.env['NHOST_JWT_SECRET']) {
if (!process.env.NHOST_JWT_SECRET) {
throw new Error('NHOST_JWT_SECRET env var is not set')
}
const jwtSecret = JSON.parse(process.env['NHOST_JWT_SECRET'])
const jwtSecret = JSON.parse(process.env.NHOST_JWT_SECRET)
const decodedToken = jwt.verify(accessToken, jwtSecret.key) as any
return decodedToken['https://hasura.io/jwt/claims'] as UserHasuraClaims

View File

@@ -0,0 +1,7 @@
{
"extends": "../../config/tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": ["src/**/*"]
}

View File

@@ -119,6 +119,7 @@
gofumpt
golangci-lint
gqlgenc
oapi-codegen
# internal packages
self.packages.${system}.codegen

2
go.mod
View File

@@ -16,7 +16,6 @@ require (
github.com/davidbyttow/govips/v2 v2.16.0
github.com/gabriel-vasile/mimetype v1.4.8
github.com/getkin/kin-openapi v0.133.0
github.com/gin-contrib/cors v1.7.3
github.com/gin-gonic/gin v1.11.0
github.com/go-git/go-git/v5 v5.16.2
github.com/go-webauthn/webauthn v0.12.2
@@ -30,7 +29,6 @@ require (
github.com/lmittmann/tint v1.0.7
github.com/mark3labs/mcp-go v0.41.1
github.com/nhost/be v0.0.0-20251021065906-8abc7d8dfa48
github.com/oapi-codegen/gin-middleware v1.0.2
github.com/oapi-codegen/runtime v1.1.1
github.com/pb33f/libopenapi v0.21.12
github.com/pelletier/go-toml/v2 v2.2.4

4
go.sum
View File

@@ -162,8 +162,6 @@ github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3G
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ=
github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE=
github.com/gin-contrib/cors v1.7.3 h1:hV+a5xp8hwJoTw7OY+a70FsL8JkVVFTXw9EcfrYUdns=
github.com/gin-contrib/cors v1.7.3/go.mod h1:M3bcKZhxzsvI+rlRSkkxHyljJt1ESd93COUvemZ79j4=
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
@@ -341,8 +339,6 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
github.com/nhost/be v0.0.0-20251021065906-8abc7d8dfa48 h1:+Oh4Rbr1psWlBaQTakoBYFNB8jBioiXuimNMaNPLTHk=
github.com/nhost/be v0.0.0-20251021065906-8abc7d8dfa48/go.mod h1:feVvqP3dft8hWbp9zNZExdGKbFEYv8aLYohfyAeINNQ=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oapi-codegen/gin-middleware v1.0.2 h1:/H99UzvHQAUxXK8pzdcGAZgjCVeXdFDAUUWaJT0k0eI=
github.com/oapi-codegen/gin-middleware v1.0.2/go.mod h1:2HJDQjH8jzK2/k/VKcWl+/T41H7ai2bKa6dN3AA2GpA=
github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro=
github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY=

Some files were not shown because too many files have changed in this diff Show More