mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
25 Commits
@auth/edge
...
@auth/type
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e274c51807 | ||
|
|
2b3836d945 | ||
|
|
b729f8af0b | ||
|
|
9f54222c0e | ||
|
|
a5ac491cb8 | ||
|
|
a96dcdbca3 | ||
|
|
bec01a82ea | ||
|
|
6061bbcde1 | ||
|
|
09c5fe29ba | ||
|
|
6780ed7fee | ||
|
|
5a7c1bb2bb | ||
|
|
6448a7b76e | ||
|
|
db8fcc3c82 | ||
|
|
9aeca63013 | ||
|
|
fee85f3138 | ||
|
|
e5bf8ec9c5 | ||
|
|
e3ec32812e | ||
|
|
c776435268 | ||
|
|
d0cc046e2d | ||
|
|
c818d028aa | ||
|
|
3ba8a0e40a | ||
|
|
770d3565f8 | ||
|
|
ed32236712 | ||
|
|
307f7b5eb9 | ||
|
|
120d7a29ee |
33
.github/DISCUSSION_TEMPLATE/ideas.yml
vendored
Normal file
33
.github/DISCUSSION_TEMPLATE/ideas.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Goals
|
||||
description: Short list of what the feature request aims to address?
|
||||
value: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Non-Goals
|
||||
description: Short list of what the feature request _does not_ aim to address?
|
||||
value: |
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Background
|
||||
description: Discuss prior art, why do you think this feature is needed? Are there current alternatives?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Proposal
|
||||
description: How should this feature be implemented? Are you interested in contributing?
|
||||
validations:
|
||||
required: true
|
||||
20
.github/DISCUSSION_TEMPLATE/questions.yml
vendored
Normal file
20
.github/DISCUSSION_TEMPLATE/questions.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Summary
|
||||
description: What do you need help with?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: Any code snippets, error messages, or dependency details that may be related?
|
||||
render: js
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
attributes:
|
||||
label: Example
|
||||
description: A link to a minimal reproduction is helpful for collaborative debugging!
|
||||
validations:
|
||||
required: false
|
||||
4
.github/ISSUE_TEMPLATE/3_bug_adapter.yml
vendored
4
.github/ISSUE_TEMPLATE/3_bug_adapter.yml
vendored
@@ -21,6 +21,9 @@ body:
|
||||
multiple: true
|
||||
options:
|
||||
- "Custom adapter"
|
||||
- "@auth/azure-tables-adapter"
|
||||
- "@auth/edgedb-adapter"
|
||||
- "@auth/d1-adapter"
|
||||
- "@auth/dgraph-adapter"
|
||||
- "@auth/drizzle-adapter"
|
||||
- "@auth/dynamodb-adapter"
|
||||
@@ -30,6 +33,7 @@ body:
|
||||
- "@auth/mikro-orm-adapter"
|
||||
- "@auth/mongodb-adapter"
|
||||
- "@auth/neo4j-adapter"
|
||||
- "@auth/pg-adapter"
|
||||
- "@auth/pouchdb-adapter"
|
||||
- "@auth/prisma-adapter"
|
||||
- "@auth/sequelize-adapter"
|
||||
|
||||
72
.github/ISSUE_TEMPLATE/5_feature_request.yml
vendored
72
.github/ISSUE_TEMPLATE/5_feature_request.yml
vendored
@@ -1,72 +0,0 @@
|
||||
name: Feature Request
|
||||
description: Suggest an idea for NextAuth.js
|
||||
labels: [triage, enhancement]
|
||||
|
||||
# note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
|
||||
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
|
||||
Thank you very much for reaching out to us regarding the awesome feature that you believe should be included in the NextAuth.js library.
|
||||
|
||||
_NOTE: Feature requests are converted to [discussions (Ideas 💡)](https://github.com/nextauthjs/next-auth/discussions/categories/ideas). Make sure your idea hasn't been asked yet, and upvote the existing one before opening a new instead._
|
||||
|
||||
### Important :exclamation:
|
||||
|
||||
Please proceed by providing the following information:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description 📓
|
||||
description: Please provide a more in-depth description of the feature proposed.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Make sure you provide plenty of [links]() to external documentation and inline code examples like so:
|
||||
|
||||
```js
|
||||
function myAwesomeNextAuthFeature() {
|
||||
return 💚
|
||||
}
|
||||
```
|
||||
|
||||
Take time thinking about what you want to say and help us understand your proposal making sure that this description contains:
|
||||
|
||||
- **purpose of the feature**
|
||||
- **potential problems**
|
||||
- **potential alternatives**
|
||||
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: How to reproduce ☕️
|
||||
description: If you have a CodeSandbox playground or some code snippets to help us visualize your idea better, please provide it here.
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
You can use one of the templates set up on **CodeSandbox** to better illustrate your idea:
|
||||
|
||||
- [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
|
||||
|
||||
- type: dropdown
|
||||
id: pr
|
||||
attributes:
|
||||
label: Contributing 🙌🏽
|
||||
multiple: false
|
||||
options:
|
||||
- "Yes, I am willing to help implement this feature in a PR"
|
||||
- "No, I am afraid I cannot help regarding this"
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
|
||||
57
.github/ISSUE_TEMPLATE/6_typescript.yml
vendored
57
.github/ISSUE_TEMPLATE/6_typescript.yml
vendored
@@ -1,57 +0,0 @@
|
||||
name: TypeScript
|
||||
description: Ask a question about NextAuth.js TypeScript integration
|
||||
labels: [question, TypeScript]
|
||||
assignees: [lluia, balazsorban44]
|
||||
|
||||
# note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
|
||||
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: question
|
||||
attributes:
|
||||
label: Question 💬
|
||||
description: Please provide an in-depth description of the question you have when using NextAuth.js on a Typescript project or when consuming the built-in types for `next-auth`.
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
|
||||
Make sure you [link]() to external documentation if necessary and provide inline code examples like so:
|
||||
|
||||
```js
|
||||
function myAwesomeNextAuthFeature() {
|
||||
return 💚
|
||||
}
|
||||
```
|
||||
|
||||
**NOTE:** Questions will be converted to Discussions. You can find them [here](https://github.com/nextauthjs/next-auth/discussions)!
|
||||
|
||||
- type: textarea
|
||||
id: codesandbox
|
||||
attributes:
|
||||
label: How to reproduce ☕️
|
||||
description: Please provide a link to a minimal reproduction or code snippets that represents your question
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
We encourage you to use the template set-up on **CodeSandbox** as a playground to represent your question or doubt:
|
||||
- [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
|
||||
|
||||
- type: dropdown
|
||||
id: pr
|
||||
attributes:
|
||||
label: Contributing 🙌🏽
|
||||
multiple: false
|
||||
options:
|
||||
- "Yes, I am willing to help answer this question in a PR"
|
||||
- "No, I am afraid I cannot help regarding this"
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
|
||||
61
.github/ISSUE_TEMPLATE/7_question.yml
vendored
61
.github/ISSUE_TEMPLATE/7_question.yml
vendored
@@ -1,61 +0,0 @@
|
||||
name: Question
|
||||
description: Ask a question about NextAuth.js or for help using it
|
||||
labels: [question]
|
||||
|
||||
# note: markdown sections will NOT appear as part of the issue as per documentation, rather they provide context to the user
|
||||
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema#markdown
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**NOTE:** Issues that are potentially security related should be reported to us by following the [Security guidelines](https://next-auth.js.org/security) rather than on GitHub.
|
||||
We are glad that you have a question about this library. Please provide the following information:
|
||||
|
||||
- type: textarea
|
||||
id: question
|
||||
attributes:
|
||||
label: Question 💬
|
||||
description: Please provide an in-depth description of the question you have.
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Make sure you [link]() to external documentation if necessary and provide inline code examples like so:
|
||||
|
||||
```js
|
||||
function myAwesomeNextAuthFeature() {
|
||||
return 💚
|
||||
}
|
||||
```
|
||||
|
||||
**NOTE:** Questions will be converted to Discussions. You can find them [here](https://github.com/nextauthjs/next-auth/discussions)!
|
||||
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: How to reproduce ☕️
|
||||
description: Please provide a link to a minimal reproduction or code snippets that represents your question
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
We encourage you to use the template set-up on **CodeSandbox** as a playground to represent your question or doubt:
|
||||
- [`next-auth-example`](https://codesandbox.io/s/next-auth-example-1kktb)
|
||||
|
||||
- type: dropdown
|
||||
id: pr
|
||||
attributes:
|
||||
label: Contributing 🙌🏽
|
||||
multiple: false
|
||||
options:
|
||||
- "Yes, I am willing to help answer this question in a PR"
|
||||
- "No, I am afraid I cannot help regarding this"
|
||||
validations:
|
||||
required: true
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
It takes a lot of work 🏋🏻♀️ maintaining a library like `next-auth`; any contribution is more than welcome 💚
|
||||
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1 +1,8 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Ask a question
|
||||
url: https://github.com/nextauthjs/next-auth/discussions/new?category=questions
|
||||
about: Ask questions and discuss with other community members
|
||||
- name: Feature request
|
||||
url: https://github.com/nextauthjs/next-auth/discussions/new?category=ideas
|
||||
about: Feature requests should be opened as discussions
|
||||
|
||||
2
.github/actions/issue-validator/.gitignore
vendored
2
.github/actions/issue-validator/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
!dist
|
||||
!package-lock.json
|
||||
7
.github/actions/issue-validator/index.mjs
vendored
7
.github/actions/issue-validator/index.mjs
vendored
File diff suppressed because one or more lines are too long
653
.github/actions/issue-validator/licenses.txt
vendored
653
.github/actions/issue-validator/licenses.txt
vendored
@@ -1,653 +0,0 @@
|
||||
@actions/core
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2019 GitHub
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
@actions/github
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright 2019 GitHub
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
@actions/http-client
|
||||
MIT
|
||||
Actions Http Client for Node.js
|
||||
|
||||
Copyright (c) GitHub, Inc.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/auth-token
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/core
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/endpoint
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2018 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/graphql
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2018 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/plugin-paginate-rest
|
||||
MIT
|
||||
MIT License Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/plugin-rest-endpoint-methods
|
||||
MIT
|
||||
MIT License Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/request
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2018 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@octokit/request-error
|
||||
MIT
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2019 Octokit contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
@vercel/ncc
|
||||
MIT
|
||||
Copyright 2018 ZEIT, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
before-after-hook
|
||||
Apache-2.0
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2018 Gregor Martynus and other contributors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
deprecation
|
||||
ISC
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Gregor Martynus and contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
is-plain-object
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
node-fetch
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 David Frank
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
|
||||
once
|
||||
ISC
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
root
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2022-2023, Balázs Orbán
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
tr46
|
||||
MIT
|
||||
|
||||
tunnel
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012 Koichi Kobayashi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
universal-user-agent
|
||||
ISC
|
||||
# [ISC License](https://spdx.org/licenses/ISC)
|
||||
|
||||
Copyright (c) 2018, Gregor Martynus (https://github.com/gr2m)
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
uuid
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2010-2020 Robert Kieffer and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
webidl-conversions
|
||||
BSD-2-Clause
|
||||
# The BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2014, Domenic Denicola
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
whatwg-url
|
||||
MIT
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015–2016 Sebastian Mayr
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
|
||||
wrappy
|
||||
ISC
|
||||
The ISC License
|
||||
|
||||
Copyright (c) Isaac Z. Schlueter and Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
445
.github/actions/issue-validator/package-lock.json
generated
vendored
445
.github/actions/issue-validator/package-lock.json
generated
vendored
@@ -1,445 +0,0 @@
|
||||
{
|
||||
"name": "issue-validator",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@actions/core": "1.10.0",
|
||||
"@actions/github": "5.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "0.34.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/github": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
|
||||
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
|
||||
"dependencies": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"@octokit/core": "^3.6.0",
|
||||
"@octokit/plugin-paginate-rest": "^2.17.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@actions/http-client": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
||||
"dependencies": {
|
||||
"tunnel": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/core": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
|
||||
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
|
||||
"dependencies": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.3",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"dependencies": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "12.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.10.1.tgz",
|
||||
"integrity": "sha512-P+SukKanjFY0ZhsK6wSVnQmxTP2eVPPE8OPSNuxaMYtgVzwJZgfGdwlYjf4RlRU4vLEw4ts2fsE2icG4nZ5ddQ=="
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
"version": "2.21.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
|
||||
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.40.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=2"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
|
||||
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.39.0",
|
||||
"deprecation": "^2.3.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@octokit/core": ">=3"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
|
||||
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"dependencies": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "6.40.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.40.0.tgz",
|
||||
"integrity": "sha512-MFZOU5r8SwgJWDMhrLUSvyJPtVsqA6VnbVI3TNbsmw+Jnvrktzvq2fYES/6RiJA/5Ykdwq4mJmtlYUfW7CGjmw==",
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^12.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vercel/ncc": {
|
||||
"version": "0.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
|
||||
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"ncc": "dist/ncc/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
},
|
||||
"node_modules/deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
|
||||
"engines": {
|
||||
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"node_modules/uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||
"integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
|
||||
"requires": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
},
|
||||
"@actions/github": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz",
|
||||
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==",
|
||||
"requires": {
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"@octokit/core": "^3.6.0",
|
||||
"@octokit/plugin-paginate-rest": "^2.17.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "^5.13.0"
|
||||
}
|
||||
},
|
||||
"@actions/http-client": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||
"integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
|
||||
"requires": {
|
||||
"tunnel": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"@octokit/auth-token": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
|
||||
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3"
|
||||
}
|
||||
},
|
||||
"@octokit/core": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz",
|
||||
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==",
|
||||
"requires": {
|
||||
"@octokit/auth-token": "^2.4.4",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
"@octokit/request": "^5.6.3",
|
||||
"@octokit/request-error": "^2.0.5",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"before-after-hook": "^2.2.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/endpoint": {
|
||||
"version": "6.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
|
||||
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/graphql": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
|
||||
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
|
||||
"requires": {
|
||||
"@octokit/request": "^5.6.0",
|
||||
"@octokit/types": "^6.0.3",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"version": "12.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.10.1.tgz",
|
||||
"integrity": "sha512-P+SukKanjFY0ZhsK6wSVnQmxTP2eVPPE8OPSNuxaMYtgVzwJZgfGdwlYjf4RlRU4vLEw4ts2fsE2icG4nZ5ddQ=="
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
"version": "2.21.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz",
|
||||
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.40.0"
|
||||
}
|
||||
},
|
||||
"@octokit/plugin-rest-endpoint-methods": {
|
||||
"version": "5.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz",
|
||||
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.39.0",
|
||||
"deprecation": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "5.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz",
|
||||
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==",
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^6.0.1",
|
||||
"@octokit/request-error": "^2.1.0",
|
||||
"@octokit/types": "^6.16.1",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"@octokit/request-error": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
|
||||
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
|
||||
"requires": {
|
||||
"@octokit/types": "^6.0.3",
|
||||
"deprecation": "^2.0.0",
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "6.40.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.40.0.tgz",
|
||||
"integrity": "sha512-MFZOU5r8SwgJWDMhrLUSvyJPtVsqA6VnbVI3TNbsmw+Jnvrktzvq2fYES/6RiJA/5Ykdwq4mJmtlYUfW7CGjmw==",
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^12.10.0"
|
||||
}
|
||||
},
|
||||
"@vercel/ncc": {
|
||||
"version": "0.34.0",
|
||||
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
|
||||
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
|
||||
"dev": true
|
||||
},
|
||||
"before-after-hook": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
|
||||
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
|
||||
},
|
||||
"deprecation": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
|
||||
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
|
||||
},
|
||||
"is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.7",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"tunnel": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
|
||||
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
|
||||
},
|
||||
"universal-user-agent": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
|
||||
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
|
||||
},
|
||||
"uuid": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
14
.github/actions/issue-validator/package.json
vendored
14
.github/actions/issue-validator/package.json
vendored
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"private": true,
|
||||
"exports": "./index.mjs",
|
||||
"scripts": {
|
||||
"build": "ncc -m -o . build src/index.mjs --license licenses.txt"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vercel/ncc": "0.34.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "1.10.0",
|
||||
"@actions/github": "5.1.1"
|
||||
}
|
||||
}
|
||||
37
.github/actions/issue-validator/repro.md
vendored
37
.github/actions/issue-validator/repro.md
vendored
@@ -1,37 +0,0 @@
|
||||
We cannot recreate the issue with the provided information. **Please add a reproduction in order for us to be able to investigate.**
|
||||
|
||||
### **Why was this issue marked with the `incomplete` label?**
|
||||
|
||||
To be able to investigate, we need access to a reproduction to identify what triggered the issue. We prefer a link to a public GitHub repository ([template](https://github.com/nextauthjs/next-auth-example)), but you can also use a tool like [CodeSandbox](https://codesandbox.io/s/github/nextauthjs/next-auth-example/tree/main) or [StackBlitz](https://stackblitz.com/fork/github/nextauthjs/next-auth-example).
|
||||
|
||||
To make sure the issue is resolved as quickly as possible, please make sure that the reproduction is as **minimal** as possible. This means that you should **remove unnecessary code, files, and dependencies** that do not contribute to the issue.
|
||||
|
||||
Please test your reproduction against the latest version of NextAuth.js (`next-auth@latest`) to make sure your issue has not already been fixed.
|
||||
|
||||
### **I added a link, why was it still marked?**
|
||||
|
||||
Ensure the link is pointing to a codebase that is accessible (e.g. not a private repository). "[example.com](http://example.com/)", "n/a", "will add later", etc. are not acceptable links -- we need to see a public codebase. See the above section for accepted links.
|
||||
|
||||
### **What happens if I don't provide a sufficient minimal reproduction?**
|
||||
|
||||
Issues with the `incomplete` label that receives no meaningful activity (e.g. new comments with a reproduction link) are closed after 7 days.
|
||||
|
||||
If your issue has _not_ been resolved in that time and it has been closed/locked, please open a new issue with the required reproduction. (It's less likely that we check back on already closed issues.)
|
||||
|
||||
### **I did not open this issue, but it is relevant to me, what can I do to help?**
|
||||
|
||||
Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps. Furthermore, you can upvote the issue using the :+1: reaction on the topmost comment (please **do not** comment "I have the same issue" without repro steps). Then, we can sort issues by votes to prioritize.
|
||||
|
||||
### **I think my reproduction is good enough, why aren't you looking into it quicker?**
|
||||
|
||||
We look into every NextAuth.js issue and constantly monitor open issues for new comments.
|
||||
|
||||
However, sometimes we might miss one or two. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.
|
||||
|
||||
Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.
|
||||
|
||||
### **Useful Resources**
|
||||
|
||||
- [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve)
|
||||
- [Reporting a NextAuth.js bug](https://github.com/nextauthjs/next-auth/blob/main/.github/ISSUE_TEMPLATE/1_bug_framework.yml)
|
||||
- [How to Contribute to Open Source (Next.js)](https://www.youtube.com/watch?v=cuoNzXFLitc)
|
||||
91
.github/actions/issue-validator/src/index.mjs
vendored
91
.github/actions/issue-validator/src/index.mjs
vendored
@@ -1,91 +0,0 @@
|
||||
// @ts-check
|
||||
// @ts-expect-error
|
||||
import * as github from "@actions/github"
|
||||
// @ts-expect-error
|
||||
import * as core from "@actions/core"
|
||||
import { readFileSync } from "node:fs"
|
||||
import { join } from "node:path"
|
||||
|
||||
const addReproductionLabel = "incomplete"
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* id :number
|
||||
* node_id :string
|
||||
* url :string
|
||||
* name :string
|
||||
* description :string
|
||||
* color :string
|
||||
* default :boolean
|
||||
* }} Label
|
||||
*
|
||||
* @typedef {{
|
||||
* pull_request: any
|
||||
* issue?: {body: string, number: number, labels: Label[]}
|
||||
* label: Label
|
||||
* }} Payload
|
||||
*
|
||||
* @typedef {{
|
||||
* payload: Payload
|
||||
* repo: any
|
||||
* }} Context
|
||||
*/
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
/** @type {Context} */
|
||||
const { payload, repo } = github.context
|
||||
const {
|
||||
issue,
|
||||
pull_request,
|
||||
label: { name: newLabel },
|
||||
} = payload
|
||||
|
||||
if (pull_request || !issue?.body || !process.env.GITHUB_TOKEN) return
|
||||
|
||||
const labels = issue.labels.map((l) => l.name)
|
||||
// const isBugReport =
|
||||
// labels.includes(bugLabel) || newLabel === bugLabel || !labels.length
|
||||
|
||||
if (
|
||||
// !(isBugReport && issue.number > 43554) &&
|
||||
![addReproductionLabel].includes(newLabel) &&
|
||||
!labels.includes(addReproductionLabel)
|
||||
) {
|
||||
return core.info(
|
||||
"Not a bug report or not manually labeled or already labeled."
|
||||
)
|
||||
}
|
||||
|
||||
const client = github.getOctokit(process.env.GITHUB_TOKEN).rest
|
||||
const issueCommon = { ...repo, issue_number: issue.number }
|
||||
|
||||
if (
|
||||
newLabel === addReproductionLabel
|
||||
// || !hasValidRepro
|
||||
) {
|
||||
await Promise.all([
|
||||
client.issues.addLabels({
|
||||
...issueCommon,
|
||||
labels: [addReproductionLabel],
|
||||
}),
|
||||
client.issues.createComment({
|
||||
...issueCommon,
|
||||
body: readFileSync(
|
||||
join(
|
||||
"/home/runner/work/next-auth/next-auth/.github/actions/issue-validator/repro.md"
|
||||
),
|
||||
"utf8"
|
||||
),
|
||||
}),
|
||||
])
|
||||
return core.info(
|
||||
"Commented on issue, because it did not have a sufficient reproduction."
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
core.setFailed(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
run()
|
||||
51
.github/invalid-reproduction.md
vendored
Normal file
51
.github/invalid-reproduction.md
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
We could not detect a valid reproduction link. **Make sure to follow the bug report template carefully.**
|
||||
|
||||
### Why was this issue closed?
|
||||
|
||||
To be able to investigate, we need access to a reproduction to identify what triggered the issue. We need a link to a **public** GitHub repository. Example: ([NextAuth.js example repository](https://github.com/nextauthjs/next-auth-example)).
|
||||
|
||||
The bug template that you filled out has a section called "Reproduction URL", which is where you should provide the link to the reproduction.
|
||||
|
||||
- If you did not provide a link or the link you provided is not valid, we will close the issue.
|
||||
- If you provide a link to a private repository, we will close the issue.
|
||||
- If you provide a link to a repository but not in the correct section, we will close the issue.
|
||||
|
||||
### What should I do?
|
||||
|
||||
Depending on the reason the issue was closed, you can do the following:
|
||||
|
||||
- If you did not provide a link, please open a new issue with a link to a reproduction.
|
||||
- If you provided a link to a private repository, please open a new issue with a link to a public repository.
|
||||
- If you provided a link to a repository but not in the correct section, please open a new issue with a link to a reproduction in the correct section.
|
||||
|
||||
**In general, assume that we should not go through a lengthy onboarding process at your company code only to be able to verify an issue.**
|
||||
|
||||
### My repository is private and cannot make it public
|
||||
|
||||
In most cases, a private repo will not be a sufficient **minimal reproduction**, as this codebase might contain a lot of unrelated parts that would make our investigation take longer. Please do **not** make it public. Instead, create a new repository using the templates above, adding the relevant code to reproduce the issue. Common things to look out for:
|
||||
|
||||
- Remove any code that is not related to the issue. (pages, API Routes, components, etc.)
|
||||
- Remove any dependencies that are not related to the issue.
|
||||
- Remove any third-party service that would require us to sign up for an account to reproduce the issue.
|
||||
- Remove any environment variables that are not related to the issue.
|
||||
- Remove private packages that we do not have access to.
|
||||
- If the issue is not related to a monorepo specifically, try to reproduce the issue without a complex monorepo setup
|
||||
|
||||
### I did not open this issue, but it is relevant to me, what can I do to help?
|
||||
|
||||
Anyone experiencing the same issue is welcome to provide a minimal reproduction following the above steps by opening a new issue.
|
||||
|
||||
### I think my reproduction is good enough, why aren't you looking into it quickly?
|
||||
|
||||
We look into every issue and monitor open issues for new comments.
|
||||
|
||||
However, sometimes we might miss a few due to the popularity/high traffic of the repository. We apologize, and kindly ask you to refrain from tagging core maintainers, as that will usually not result in increased priority.
|
||||
|
||||
Upvoting issues to show your interest will help us prioritize and address them as quickly as possible. That said, every issue is important to us, and if an issue gets closed by accident, we encourage you to open a new one linking to the old issue and we will look into it.
|
||||
|
||||
### Useful Resources
|
||||
|
||||
- [How to create a Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve)
|
||||
- [Bug report: Framework](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage&projects=&template=1_bug_framework.yml)
|
||||
- [Bug report: Provider](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage%2Cproviders&projects=&template=2_bug_provider.yml)
|
||||
- [Bug report: Adapter](https://github.com/nextauthjs/next-auth/issues/new?assignees=&labels=triage%2Cadapters&projects=&template=3_bug_adapter.yml)
|
||||
49
.github/issue-labeler.yml
vendored
49
.github/issue-labeler.yml
vendored
@@ -1,49 +0,0 @@
|
||||
# https://github.com/github/issue-labeler#basic-examples
|
||||
|
||||
dgraph:
|
||||
- "@auth/dgraph-adapter"
|
||||
|
||||
drizzle:
|
||||
- "@auth/drizzle-adapter"
|
||||
|
||||
dynamodb:
|
||||
- "@auth/dynamodb-adapter"
|
||||
|
||||
fauna:
|
||||
- "@auth/fauna-adapter"
|
||||
|
||||
firebase:
|
||||
- "@auth/firebase-adapter"
|
||||
|
||||
kysely:
|
||||
- "@auth/kysely-adapter"
|
||||
|
||||
mikro-orm:
|
||||
- "@auth/mikro-orm-adapter"
|
||||
|
||||
mongodb:
|
||||
- "@auth/mongodb-adapter"
|
||||
|
||||
neo4j:
|
||||
- "@auth/neo4j-adapter"
|
||||
|
||||
pouchdb:
|
||||
- "@auth/pouchdb-adapter"
|
||||
|
||||
prisma:
|
||||
- "@auth/prisma-adapter"
|
||||
|
||||
sequelize:
|
||||
- "@auth/sequelize-adapter"
|
||||
|
||||
supabase:
|
||||
- "@auth/supabase-adapter"
|
||||
|
||||
typeorm:
|
||||
- "@auth/typeorm-adapter"
|
||||
|
||||
upstash-redis:
|
||||
- "@auth/upstash-redis-adapter"
|
||||
|
||||
xata:
|
||||
- "@auth/xata-adapter"
|
||||
6
.github/pr-labeler.yml
vendored
6
.github/pr-labeler.yml
vendored
@@ -1,7 +1,11 @@
|
||||
# https://github.com/actions/labeler#create-githublabeleryml
|
||||
adapters: ["packages/core/src/adapters.ts", "packages/adapter-*/**/*"]
|
||||
core: ["packages/core/src/**/*"]
|
||||
azure-tables: ["packages/adapter-azure-tables/**/*"]
|
||||
edgedb: ["packages/adapter-edgedb/**/*"]
|
||||
d1: ["packages/adapter-d1/**/*"]
|
||||
dgraph: ["packages/adapter-dgraph/**/*"]
|
||||
drizzle: ["packages/adapter-drizzle/**/*"]
|
||||
documentation: ["packages/docs/docs/**/*"]
|
||||
dynamodb: ["packages/adapter-dynamodb/**/*"]
|
||||
examples: ["apps/examples/**/*"]
|
||||
@@ -12,6 +16,7 @@ legacy: ["packages/next-auth/**/*"]
|
||||
mikro-orm: ["packages/adapter-mikro-orm/**/*"]
|
||||
mongodb: ["packages/adapter-mongodb/**/*"]
|
||||
neo4j: ["packages/adapter-neo4j/**/*"]
|
||||
pg: ["packages/adapter-pg/**/*"]
|
||||
playgrounds: ["apps/playgrounds/**/*"]
|
||||
pouchdb: ["packages/adapter-pouchdb/**/*"]
|
||||
prisma: ["packages/adapter-prisma/**/*"]
|
||||
@@ -20,6 +25,7 @@ providers: ["packages/core/src/providers/**/*"]
|
||||
sequelize: ["packages/adapter-sequelize/**/*"]
|
||||
solidjs: ["packages/frameworks-solid-start/**/*"]
|
||||
supabase: ["packages/adapter-supabase/**/*"]
|
||||
surrealdb: ["packages/adapter-surrealdb/**/*"]
|
||||
svelte: ["packages/frameworks-sveltekit/**/*"]
|
||||
test: ["**test**/*"]
|
||||
typeorm: ["packages/adapter-typeorm/**/*"]
|
||||
|
||||
18
.github/workflows/issue-labeler.yml
vendored
18
.github/workflows/issue-labeler.yml
vendored
@@ -1,18 +0,0 @@
|
||||
# https://github.com/github/issue-labeler#create-workflow
|
||||
|
||||
name: Label issues
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
name: Triage
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: github/issue-labeler@v2.5
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
configuration-path: ".github/issue-labeler.yml"
|
||||
enable-versioned-regex: 0
|
||||
17
.github/workflows/issue-validator.yml
vendored
17
.github/workflows/issue-validator.yml
vendored
@@ -1,17 +0,0 @@
|
||||
name: Validate issue
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
- name: Run issue validator
|
||||
run: node /home/runner/work/next-auth/next-auth/.github/actions/issue-validator/index.mjs
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@@ -39,6 +39,7 @@ on:
|
||||
options:
|
||||
- "core"
|
||||
- "frameworks-nextjs"
|
||||
- "adapter-edgedb"
|
||||
- "adapter-dgraph"
|
||||
- "adapter-drizzle"
|
||||
- "adapter-dynamodb"
|
||||
|
||||
23
.github/workflows/triage.yml
vendored
Normal file
23
.github/workflows/triage.yml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Triage issue
|
||||
on:
|
||||
issues:
|
||||
types: [labeled, opened]
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Nissuer
|
||||
uses: balazsorban44/nissuer@1.3.5
|
||||
with:
|
||||
label-area-prefix: ""
|
||||
label-area-section: "[Provider|Adapter] type(.*)### Environment"
|
||||
label-comments: '{ "incomplete": ".github/invalid-reproduction.md" }'
|
||||
reproduction-link-section: "### Reproduction URL(.*)### Describe the issue"
|
||||
reproduction-invalid-label: "invalid reproduction"
|
||||
@@ -74,7 +74,6 @@ declare module "next-auth/jwt" {
|
||||
}
|
||||
|
||||
export const config = {
|
||||
// https://next-auth.js.org/configuration/providers/oauth
|
||||
providers: [
|
||||
Apple({ clientId: process.env.AUTH_APPLE_ID, clientSecret: process.env.AUTH_APPLE_SECRET }),
|
||||
Atlassian({ clientId: process.env.AUTH_ATLASSIAN_ID, clientSecret: process.env.AUTH_ATLASSIAN_SECRET }),
|
||||
|
||||
@@ -61,7 +61,7 @@ pnpm install
|
||||
4. Start the development server
|
||||
|
||||
```bash
|
||||
$ pnpm dev:docs
|
||||
pnpm dev:docs
|
||||
```
|
||||
|
||||
And thats all! Now you should have a local copy of this docs site running at [localhost:3000](http://localhost:3000)!
|
||||
|
||||
@@ -89,7 +89,7 @@ NEXTAUTH_SECRET="This is an example"
|
||||
`NEXTAUTH_SECRET` is a random string used by the library to encrypt tokens and email verification hashes, and **it's mandatory to keep things secure**! 🔥 🔐 . You can use:
|
||||
|
||||
```
|
||||
$ openssl rand -base64 32
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
or https://generate-secret.vercel.app/32 to generate a random value for it.
|
||||
@@ -205,7 +205,7 @@ Create the following [Server hook](https://kit.svelte.dev/docs/hooks) file. This
|
||||
import { SvelteKitAuth } from "@auth/sveltekit"
|
||||
import GitHub from "@auth/core/providers/github"
|
||||
import { GITHUB_ID, GITHUB_SECRET } from "$env/static/private"
|
||||
*
|
||||
|
||||
export const handle = SvelteKitAuth({
|
||||
providers: [GitHub({ clientId: GITHUB_ID, clientSecret: GITHUB_SECRET })],
|
||||
})
|
||||
@@ -242,7 +242,7 @@ AUTH_SECRET="This is an example"
|
||||
`AUTH_SECRET` is a random string used by the library to encrypt tokens and email verification hashes, and **it's mandatory to keep things secure**! 🔥 🔐 . You can use:
|
||||
|
||||
```
|
||||
$ openssl rand -base64 32
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
or https://generate-secret.vercel.app/32 to generate a random value for it.
|
||||
@@ -288,7 +288,7 @@ To protect your API Routes (blocking unauthorized access to resources), you can
|
||||
```ts title="routes/api/movies/+server.ts"
|
||||
import { json, error } from "@sveltejs/kit";
|
||||
import type { RequestEvent } from "./$types";
|
||||
|
||||
|
||||
export async function GET({ locals }: RequestEvent) {
|
||||
const session = await locals.getSession()
|
||||
if (!session?.user) {
|
||||
@@ -429,7 +429,7 @@ export default NextAuth({
|
||||
Great! We're now ready to run our application locally. Start the Next.js app by running on your terminal the following command and navigating to [`http://localhost:3000`](http://localhost:3000):
|
||||
|
||||
```
|
||||
$ npm run next dev
|
||||
npm run next dev
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
@@ -448,7 +448,7 @@ export const handle = SvelteKitAuth({
|
||||
Great! We're now ready to run our application locally. Start the Svelte app by running on your terminal the following command and navigating to [`http://localhost:5173`](http://localhost:5173):
|
||||
|
||||
```
|
||||
$ npm run vite dev
|
||||
npm run vite dev
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -580,7 +580,7 @@ Auth.js used to generate a secret for convenience, when the user did not define
|
||||
You can generate a secret to be placed in the `secret` configuration option via the following command:
|
||||
|
||||
```bash
|
||||
$ openssl rand -base64 32
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
Therefore, your Auth.js config should look something like this:
|
||||
|
||||
@@ -5,6 +5,14 @@ title: Overview
|
||||
Using an Auth.js / NextAuth.js adapter you can connect to any database service or even several different services at the same time. The following listed official adapters are created and maintained by the community:
|
||||
|
||||
<div class="adapter-card-list">
|
||||
<a href="/reference/adapter/azure-tables" class="adapter-card">
|
||||
<img src="/img/adapters/azure-tables.svg" width="40" />
|
||||
<h4 class="adapter-card__title">Azure Table Storage Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/d1" class="adapter-card">
|
||||
<img src="/img/adapters/d1.svg" width="40" />
|
||||
<h4 class="adapter-card__title">D1 Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/edgedb" class="adapter-card">
|
||||
<img src="/img/adapters/edgedb.svg" width="30" />
|
||||
<h4 class="adapter-card__title">EdgeDB Adapter</h4>
|
||||
@@ -45,6 +53,10 @@ Using an Auth.js / NextAuth.js adapter you can connect to any database service o
|
||||
<img src="/img/adapters/neo4j.svg" width="50" />
|
||||
<h4 class="adapter-card__title">Neo4j Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/pg" class="adapter-card">
|
||||
<img src="/img/adapters/pg.png" width="20" />
|
||||
<h4 class="adapter-card__title">Postgres Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/pouchdb" class="adapter-card">
|
||||
<img src="/img/adapters/pouchdb.svg" width="20" />
|
||||
<h4 class="adapter-card__title">PouchDB Adapter</h4>
|
||||
@@ -61,6 +73,10 @@ Using an Auth.js / NextAuth.js adapter you can connect to any database service o
|
||||
<img src="/img/adapters/supabase.svg" width="25" />
|
||||
<h4 class="adapter-card__title">Supabase Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/surrealdb" class="adapter-card">
|
||||
<img src="/img/adapters/surreal.png" width="25" />
|
||||
<h4 class="adapter-card__title">SurrealDB Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/typeorm" class="adapter-card">
|
||||
<img src="/img/adapters/typeorm.png" width="30" />
|
||||
<h4 class="adapter-card__title">TypeORM Adapter</h4>
|
||||
|
||||
@@ -282,6 +282,8 @@ const docusaurusConfig = {
|
||||
...(process.env.TYPEDOC_SKIP_ADAPTERS
|
||||
? []
|
||||
: [
|
||||
typedocAdapter("Azure Tables"),
|
||||
typedocAdapter("D1"),
|
||||
typedocAdapter("EdgeDb"),
|
||||
typedocAdapter("Dgraph"),
|
||||
typedocAdapter("Drizzle"),
|
||||
@@ -292,11 +294,13 @@ const docusaurusConfig = {
|
||||
typedocAdapter("Mikro ORM"),
|
||||
typedocAdapter("MongoDB"),
|
||||
typedocAdapter("Neo4j"),
|
||||
typedocAdapter("PG"),
|
||||
typedocAdapter("PouchDB"),
|
||||
typedocAdapter("Prisma"),
|
||||
typedocAdapter("TypeORM"),
|
||||
typedocAdapter("Sequelize"),
|
||||
typedocAdapter("Supabase"),
|
||||
typedocAdapter("SurrealDB"),
|
||||
typedocAdapter("Upstash Redis"),
|
||||
typedocAdapter("Xata"),
|
||||
]),
|
||||
|
||||
@@ -46,6 +46,9 @@ module.exports = {
|
||||
label: "Database Adapters",
|
||||
link: { type: "doc", id: "reference/adapters/index" },
|
||||
items: [
|
||||
{ type: "doc", id: "reference/adapter/azure-tables/index" },
|
||||
{ type: "doc", id: "reference/adapter/d1/index" },
|
||||
{ type: "doc", id: "reference/adapter/edgedb/index" },
|
||||
{ type: "doc", id: "reference/adapter/dgraph/index" },
|
||||
{ type: "doc", id: "reference/adapter/drizzle/index" },
|
||||
{ type: "doc", id: "reference/adapter/dynamodb/index" },
|
||||
@@ -55,10 +58,12 @@ module.exports = {
|
||||
{ type: "doc", id: "reference/adapter/mikro-orm/index" },
|
||||
{ type: "doc", id: "reference/adapter/mongodb/index" },
|
||||
{ type: "doc", id: "reference/adapter/neo4j/index" },
|
||||
{ type: "doc", id: "reference/adapter/pg/index" },
|
||||
{ type: "doc", id: "reference/adapter/pouchdb/index" },
|
||||
{ type: "doc", id: "reference/adapter/prisma/index" },
|
||||
{ type: "doc", id: "reference/adapter/sequelize/index" },
|
||||
{ type: "doc", id: "reference/adapter/supabase/index" },
|
||||
{ type: "doc", id: "reference/adapter/surrealdb/index" },
|
||||
{ type: "doc", id: "reference/adapter/typeorm/index" },
|
||||
{ type: "doc", id: "reference/adapter/upstash-redis/index" },
|
||||
{ type: "doc", id: "reference/adapter/xata/index" },
|
||||
|
||||
@@ -269,7 +269,7 @@ export default function Home() {
|
||||
}
|
||||
|
||||
const svelteKitCode = `
|
||||
import SvelteKitAuth from "@auth/sveltekit"
|
||||
import { SvelteKitAuth } from "@auth/sveltekit"
|
||||
import GitHub from '@auth/core/providers/github'
|
||||
import Facebook from '@auth/core/providers/facebook'
|
||||
import Google from '@auth/core/providers/google'
|
||||
|
||||
1
docs/static/img/adapters/azure-tables.svg
vendored
Normal file
1
docs/static/img/adapters/azure-tables.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 91 81" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><use xlink:href="#A" x=".5" y=".5"/><symbol id="A" overflow="visible"><path d="M67.678 0H22.559L0 40l22.559 40h44.881L90 40 67.678 0zM42.982 20.976H53.43v10.732H42.982V20.976zm0 13.415H53.43v10.732H42.982V34.39zm0 13.414H53.43v10.732H42.982V47.805zM29.921 20.976h10.448v10.732H29.921V20.976zm0 13.415h10.448v10.732H29.921V34.39zm0 13.414h10.448v10.732H29.921V47.805zM66.254 64.39H23.747V20.732h2.849v40.732h0 0 39.657v2.927zm.237-5.854H56.042V47.805h10.448v10.732zm0-13.414H56.042V34.39h10.448v10.732zm0-13.415H56.042V20.976h10.448v10.732z" fill="#0078d7" stroke="none"/></symbol></svg>
|
||||
|
After Width: | Height: | Size: 782 B |
5
docs/static/img/adapters/d1.svg
vendored
Normal file
5
docs/static/img/adapters/d1.svg
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="49" viewBox="0 0 48 49">
|
||||
<path d="m18.63 37.418-9.645-12.9 9.592-12.533-1.852-2.527L5.917 23.595l-.015 1.808 10.86 14.542 1.868-2.527z" fill="rgb(243, 128, 32)"></path>
|
||||
<path d="M21.997 6.503h-3.712l13.387 18.3-13.072 17.7h3.735L35.4 24.81 21.997 6.503z" fill="rgb(243, 128, 32)"></path>
|
||||
<path d="M29.175 6.503h-3.758l13.598 18.082-13.598 17.918h3.765l12.908-17.01v-1.808L29.175 6.503z" fill="rgb(243, 128, 32)"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 497 B |
BIN
docs/static/img/adapters/pg.png
vendored
Normal file
BIN
docs/static/img/adapters/pg.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
BIN
docs/static/img/adapters/surreal.png
vendored
Normal file
BIN
docs/static/img/adapters/surreal.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
26
packages/adapter-azure-tables/README.md
Normal file
26
packages/adapter-azure-tables/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
<p align="center">
|
||||
<br/>
|
||||
<a href="https://authjs.dev" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/logo/logo-sm.png" />
|
||||
</a>
|
||||
<a href="https://azure.microsoft.com/en-us/products/storage/tables" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/adapters/azure-tables.svg"/>
|
||||
</a>
|
||||
<h3 align="center"><b>Azure Table Storage Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@auth/azure-tables-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@auth/azure-tables-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/azure-tables-adapter?color=green&label=@auth/azure-tables-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@auth/azure-tables-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/azure-tables-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
---
|
||||
59
packages/adapter-azure-tables/package.json
Normal file
59
packages/adapter-azure-tables/package.json
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "@auth/azure-tables-adapter",
|
||||
"version": "0.1.0",
|
||||
"description": "Azure Tables Storage adapter for next-auth.",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"author": "Nikita Dmitrijev <nikitadmitry@gmail.com>",
|
||||
"contributors": [
|
||||
"Thang Huu Vu <hi@thvu.dev>"
|
||||
],
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
"next.js",
|
||||
"oauth",
|
||||
"azure-tables",
|
||||
"adapter"
|
||||
],
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"*.d.ts*",
|
||||
"*.js",
|
||||
"src"
|
||||
],
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./tests/test.sh",
|
||||
"test:watch": "./tests/test.sh -w",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@azure/data-tables": "^13.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@auth/adapter-test": "workspace:*",
|
||||
"@auth/tsconfig": "workspace:*",
|
||||
"jest": "^27.4.3",
|
||||
"@azure/data-tables": "^13.2.1"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
303
packages/adapter-azure-tables/src/index.ts
Normal file
303
packages/adapter-azure-tables/src/index.ts
Normal file
@@ -0,0 +1,303 @@
|
||||
/**
|
||||
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}>
|
||||
* <p style={{fontWeight: "normal"}}>An official <a href="https://azure.microsoft.com/en-us/products/storage/tables">Azure Table Storage</a> adapter for Auth.js / NextAuth.js.</p>
|
||||
* <a href="https://azure.microsoft.com/en-us/products/storage/tables">
|
||||
* <img style={{display: "block"}} src="/img/adapters/azure-tables.svg" width="48" />
|
||||
* </a>
|
||||
* </div>
|
||||
*
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth @auth/azure-tables-adapter
|
||||
* ```
|
||||
*
|
||||
* @module @auth/azure-tables-adapter
|
||||
*/
|
||||
|
||||
import type {
|
||||
Adapter,
|
||||
AdapterUser,
|
||||
AdapterAccount,
|
||||
AdapterSession,
|
||||
VerificationToken,
|
||||
} from "@auth/core/adapters"
|
||||
import {
|
||||
GetTableEntityResponse,
|
||||
TableClient,
|
||||
TableEntityResult,
|
||||
} from "@azure/data-tables"
|
||||
|
||||
globalThis.crypto ??= require("node:crypto").webcrypto
|
||||
|
||||
export const keys = {
|
||||
user: "user",
|
||||
userByEmail: "userByEmail",
|
||||
account: "account",
|
||||
accountByUserId: "accountByUserId",
|
||||
session: "session",
|
||||
sessionByUserId: "sessionByUserId",
|
||||
verificationToken: "verificationToken",
|
||||
}
|
||||
|
||||
export function withoutKeys<T>(
|
||||
entity: GetTableEntityResponse<TableEntityResult<T>>
|
||||
): T {
|
||||
delete entity.partitionKey
|
||||
delete entity.rowKey
|
||||
// @ts-expect-error
|
||||
delete entity.etag
|
||||
delete entity.timestamp
|
||||
// @ts-expect-error
|
||||
delete entity["odata.metadata"]
|
||||
|
||||
return entity
|
||||
}
|
||||
/**
|
||||
*
|
||||
* 1. Create a table for authentication data, `auth` in the example below.
|
||||
*
|
||||
* ```js title="auth.ts"
|
||||
* import type { AuthConfig } from "next-auth"
|
||||
* import { TableStorageAdapter } from "@next-auth/azure-tables-adapter"
|
||||
* import { AzureNamedKeyCredential, TableClient } from "@azure/data-tables"
|
||||
*
|
||||
* const credential = new AzureNamedKeyCredential(
|
||||
* process.env.AZURE_ACCOUNT,
|
||||
* process.env.AZURE_ACCESS_KEY
|
||||
* )
|
||||
* const authClient = new TableClient(
|
||||
* process.env.AZURE_TABLES_ENDPOINT,
|
||||
* "auth",
|
||||
* credential
|
||||
* )
|
||||
*
|
||||
* // For more information on each option (and a full list of options) go to
|
||||
* // https://authjs.dev/reference/configuration/auth-options
|
||||
* export default const authConfig = {
|
||||
* // https://authjs.dev/reference/providers/oauth-builtin
|
||||
* providers: [
|
||||
* // ...
|
||||
* ],
|
||||
* adapter: TableStorageAdapter(authClient),
|
||||
* // ...
|
||||
* } satisfies AuthConfig
|
||||
* ```
|
||||
*
|
||||
* Environment variable are as follows:
|
||||
*
|
||||
* ```
|
||||
* AZURE_ACCOUNT=storageaccountname
|
||||
* AZURE_ACCESS_KEY=longRandomKey
|
||||
* AZURE_TABLES_ENDPOINT=https://$AZURE_ACCOUNT.table.core.windows.net
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
export const TableStorageAdapter = (client: TableClient): Adapter => {
|
||||
return {
|
||||
async createUser(user) {
|
||||
const id = crypto.randomUUID()
|
||||
const newUser = {
|
||||
...user,
|
||||
id,
|
||||
}
|
||||
await Promise.all([
|
||||
client.createEntity({
|
||||
...newUser,
|
||||
partitionKey: keys.userByEmail,
|
||||
rowKey: user.email,
|
||||
}),
|
||||
client.createEntity({
|
||||
...newUser,
|
||||
partitionKey: keys.user,
|
||||
rowKey: id,
|
||||
}),
|
||||
])
|
||||
return newUser
|
||||
},
|
||||
async getUser(id: string) {
|
||||
try {
|
||||
const user = await client.getEntity<AdapterUser>(keys.user, id)
|
||||
return withoutKeys(user)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
async getUserByEmail(email) {
|
||||
try {
|
||||
const user = await client.getEntity<AdapterUser>(
|
||||
keys.userByEmail,
|
||||
email
|
||||
)
|
||||
return withoutKeys(user)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
async getUserByAccount({ providerAccountId, provider }) {
|
||||
try {
|
||||
const rowKey = `${providerAccountId}_${provider}`
|
||||
const account = await client.getEntity<AdapterAccount>(
|
||||
keys.account,
|
||||
rowKey
|
||||
)
|
||||
const user = await client.getEntity<AdapterUser>(
|
||||
keys.user,
|
||||
account.userId
|
||||
)
|
||||
return withoutKeys(user)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
async updateUser(user) {
|
||||
const _user = await client.getEntity<AdapterUser>(keys.user, user.id)
|
||||
const updatedUser = {
|
||||
...user,
|
||||
partitionKey: keys.user,
|
||||
rowKey: _user.id,
|
||||
}
|
||||
await client.updateEntity(updatedUser, "Merge")
|
||||
return { ..._user, ...updatedUser }
|
||||
},
|
||||
async deleteUser(userId) {
|
||||
try {
|
||||
const user = await client.getEntity<AdapterUser>(keys.user, userId)
|
||||
const { sessionToken } = await client.getEntity<AdapterSession>(
|
||||
keys.sessionByUserId,
|
||||
userId
|
||||
)
|
||||
const accounts = withoutKeys(
|
||||
await client.getEntity<AdapterAccount>(keys.accountByUserId, userId)
|
||||
)
|
||||
const deleteAccounts = Object.keys(accounts).map((property) =>
|
||||
client.deleteEntity(keys.account, `${accounts[property]}_${property}`)
|
||||
)
|
||||
await Promise.allSettled([
|
||||
client.deleteEntity(keys.userByEmail, user.email),
|
||||
client.deleteEntity(keys.user, userId),
|
||||
client.deleteEntity(keys.session, sessionToken),
|
||||
client.deleteEntity(keys.sessionByUserId, userId),
|
||||
...deleteAccounts,
|
||||
client.deleteEntity(keys.accountByUserId, userId),
|
||||
])
|
||||
return withoutKeys(user)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
async linkAccount(account) {
|
||||
try {
|
||||
await client.createEntity({
|
||||
...account,
|
||||
partitionKey: keys.account,
|
||||
rowKey: `${account.providerAccountId}_${account.provider}`,
|
||||
})
|
||||
await client.upsertEntity({
|
||||
partitionKey: keys.accountByUserId,
|
||||
rowKey: account.userId,
|
||||
[account.provider]: account.providerAccountId,
|
||||
})
|
||||
return account
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
async unlinkAccount({ providerAccountId, provider }) {
|
||||
const rowKey = `${providerAccountId}_${provider}`
|
||||
const account = await client.getEntity<AdapterAccount>(
|
||||
keys.account,
|
||||
rowKey
|
||||
)
|
||||
await client.deleteEntity(keys.account, rowKey)
|
||||
await client.deleteEntity(keys.accountByUserId, account.userId)
|
||||
},
|
||||
async createSession(session) {
|
||||
await client.createEntity({
|
||||
...session,
|
||||
partitionKey: keys.session,
|
||||
rowKey: session.sessionToken,
|
||||
})
|
||||
await client.upsertEntity({
|
||||
partitionKey: keys.sessionByUserId,
|
||||
rowKey: session.userId,
|
||||
sessionToken: session.sessionToken,
|
||||
})
|
||||
return session
|
||||
},
|
||||
async getSessionAndUser(sessionToken) {
|
||||
try {
|
||||
const session = await client.getEntity<AdapterSession>(
|
||||
keys.session,
|
||||
sessionToken
|
||||
)
|
||||
if (session.expires.valueOf() < Date.now()) {
|
||||
await client.deleteEntity(keys.session, sessionToken)
|
||||
}
|
||||
const user = await client.getEntity<AdapterUser>(
|
||||
keys.user,
|
||||
session.userId
|
||||
)
|
||||
return {
|
||||
session: withoutKeys(session),
|
||||
user: withoutKeys(user),
|
||||
}
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
async updateSession(session) {
|
||||
const _session = await client.getEntity<AdapterSession>(
|
||||
keys.session,
|
||||
session.sessionToken
|
||||
)
|
||||
const newSession = {
|
||||
expires: session.expires ?? _session.expires,
|
||||
}
|
||||
await client.updateEntity({
|
||||
...newSession,
|
||||
partitionKey: keys.session,
|
||||
rowKey: session.sessionToken,
|
||||
})
|
||||
return { ...withoutKeys(_session), ...newSession }
|
||||
},
|
||||
async deleteSession(sessionToken) {
|
||||
try {
|
||||
const session = await client.getEntity<AdapterSession>(
|
||||
keys.session,
|
||||
sessionToken
|
||||
)
|
||||
await Promise.allSettled([
|
||||
client.deleteEntity(keys.session, sessionToken),
|
||||
client.deleteEntity(keys.sessionByUserId, session.userId),
|
||||
])
|
||||
return withoutKeys(session)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
async createVerificationToken(token) {
|
||||
await client.createEntity({
|
||||
...token,
|
||||
partitionKey: keys.verificationToken,
|
||||
rowKey: token.token,
|
||||
})
|
||||
return token
|
||||
},
|
||||
async useVerificationToken({ identifier, token }) {
|
||||
try {
|
||||
const tokenEntity = await client.getEntity<VerificationToken>(
|
||||
keys.verificationToken,
|
||||
token
|
||||
)
|
||||
if (tokenEntity.identifier !== identifier) {
|
||||
return null
|
||||
}
|
||||
await client.deleteEntity(keys.verificationToken, token)
|
||||
return withoutKeys(tokenEntity)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
90
packages/adapter-azure-tables/tests/index.test.ts
Normal file
90
packages/adapter-azure-tables/tests/index.test.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { runBasicTests } from "@auth/adapter-test"
|
||||
import {
|
||||
AzureNamedKeyCredential,
|
||||
TableServiceClient,
|
||||
TableClient,
|
||||
} from "@azure/data-tables"
|
||||
import { keys, TableStorageAdapter, withoutKeys } from "../src"
|
||||
import type { AdapterUser, VerificationToken } from "@auth/core/adapters"
|
||||
|
||||
const testAccount = {
|
||||
// default constants used by a dev instance of azurite
|
||||
name: "devstoreaccount1",
|
||||
key: "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==",
|
||||
tableEndpoint: "http://127.0.0.1:10002/devstoreaccount1",
|
||||
}
|
||||
|
||||
const authTableName = "authTest"
|
||||
|
||||
const credential = new AzureNamedKeyCredential(
|
||||
testAccount.name,
|
||||
testAccount.key
|
||||
)
|
||||
|
||||
const authClient = new TableClient(
|
||||
testAccount.tableEndpoint,
|
||||
authTableName,
|
||||
credential,
|
||||
{ allowInsecureConnection: true }
|
||||
)
|
||||
|
||||
runBasicTests({
|
||||
adapter: TableStorageAdapter(authClient),
|
||||
db: {
|
||||
async connect() {
|
||||
const serviceClient = new TableServiceClient(
|
||||
testAccount.tableEndpoint,
|
||||
credential,
|
||||
{ allowInsecureConnection: true }
|
||||
)
|
||||
await serviceClient.createTable(authTableName)
|
||||
},
|
||||
async user(id) {
|
||||
try {
|
||||
const userById = await authClient.getEntity<AdapterUser>(keys.user, id)
|
||||
|
||||
return withoutKeys(userById)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return null
|
||||
}
|
||||
},
|
||||
async account(provider_providerAccountId) {
|
||||
try {
|
||||
const account = await authClient.getEntity(
|
||||
keys.account,
|
||||
`${provider_providerAccountId.providerAccountId}_${provider_providerAccountId.provider}`
|
||||
)
|
||||
|
||||
return withoutKeys(account)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
async session(sessionToken) {
|
||||
try {
|
||||
const session = await authClient.getEntity(keys.session, sessionToken)
|
||||
|
||||
return withoutKeys(session)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
async verificationToken(identifier_token) {
|
||||
try {
|
||||
const verificationToken = await authClient.getEntity<VerificationToken>(
|
||||
keys.verificationToken,
|
||||
identifier_token.token
|
||||
)
|
||||
|
||||
if (verificationToken.identifier !== identifier_token.identifier) {
|
||||
return null
|
||||
}
|
||||
|
||||
return withoutKeys(verificationToken)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
34
packages/adapter-azure-tables/tests/test.sh
Executable file
34
packages/adapter-azure-tables/tests/test.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CONTAINER_NAME=next-auth-azure-tables-test
|
||||
|
||||
JEST_WATCH=false
|
||||
|
||||
# Is the watch flag passed to the script?
|
||||
while getopts w flag
|
||||
do
|
||||
case "${flag}" in
|
||||
w) JEST_WATCH=true;;
|
||||
*) continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Start db
|
||||
docker run -d -p 10002:10002 --name ${CONTAINER_NAME} mcr.microsoft.com/azure-storage/azurite azurite-table -l /workspace -d /workspace/debug.log --tableHost 0.0.0.0 --loose
|
||||
|
||||
echo "Waiting 3 sec for db to start..."
|
||||
sleep 3
|
||||
|
||||
if $JEST_WATCH; then
|
||||
# Run jest in watch mode
|
||||
npx jest tests --watch
|
||||
# Only stop the container after jest has been quit
|
||||
docker stop "${CONTAINER_NAME}"
|
||||
else
|
||||
# Always stop container, but exit with 1 when tests are failing
|
||||
if npx jest;then
|
||||
docker stop ${CONTAINER_NAME}
|
||||
else
|
||||
docker stop ${CONTAINER_NAME} && exit 1
|
||||
fi
|
||||
fi
|
||||
20
packages/adapter-azure-tables/tsconfig.json
Normal file
20
packages/adapter-azure-tables/tsconfig.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "@auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["*.js", "*.d.ts"]
|
||||
}
|
||||
28
packages/adapter-d1/README.md
Normal file
28
packages/adapter-d1/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
<p align="center">
|
||||
<br/>
|
||||
<a href="https://authjs.dev" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/logo/logo-sm.png" />
|
||||
</a>
|
||||
<a href="https://developers.cloudflare.com/d1/" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/adapters/d1.svg"/>
|
||||
</a>
|
||||
<h3 align="center"><b>Cloudflare D1 Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@auth/drizzle-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@auth/d1-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/d1-adapter?color=green&label=@auth/d1-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@auth/d1-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/d1-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
Check out the documentation at [authjs.dev](https://authjs.dev/reference/adapter/d1).
|
||||
58
packages/adapter-d1/package.json
Normal file
58
packages/adapter-d1/package.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "@auth/d1-adapter",
|
||||
"version": "0.2.0",
|
||||
"description": "A Cloudflare D1 adapter for Auth.js",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"author": "Josh Schlesser <josh@schlesser.dev>",
|
||||
"contributors": [
|
||||
"Thang Huu Vu <hi@thvu.dev>"
|
||||
],
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
"@auth",
|
||||
"Auth.js",
|
||||
"next.js",
|
||||
"oauth",
|
||||
"d1"
|
||||
],
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"*.d.ts*",
|
||||
"*.js",
|
||||
"src"
|
||||
],
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@auth/adapter-test": "workspace:*",
|
||||
"@auth/tsconfig": "workspace:*",
|
||||
"@cloudflare/workers-types": "^4.20230321.0",
|
||||
"@miniflare/d1": "^2.12.2",
|
||||
"better-sqlite3": "^7.0.0",
|
||||
"jest": "^29.3.0"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
432
packages/adapter-d1/src/index.ts
Normal file
432
packages/adapter-d1/src/index.ts
Normal file
@@ -0,0 +1,432 @@
|
||||
/**
|
||||
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}>
|
||||
* <p style={{fontWeight: "normal"}}>An official <a href="https://developers.cloudflare.com/d1/">Cloudflare D1</a> adapter for Auth.js / NextAuth.js.</p>
|
||||
* <a href="https://developers.cloudflare.com/d1/">
|
||||
* <img style={{display: "block"}} src="/img/adapters/d1.svg" width="48" />
|
||||
* </a>
|
||||
* </div>
|
||||
*
|
||||
* ## Warning
|
||||
* This adapter is not developed or maintained by Clouflare and they haven't declared the D1 api stable. The author will make an effort to keep this adapter up to date.
|
||||
* The adapter is compatible with the D1 api as of March 22, 2023.
|
||||
*
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth @auth/d1-adapter
|
||||
* ```
|
||||
*
|
||||
* @module @auth/d1-adapter
|
||||
*/
|
||||
|
||||
import type { D1Database as WorkerDatabase } from "@cloudflare/workers-types"
|
||||
import type { D1Database as MiniflareD1Database } from "@miniflare/d1"
|
||||
import type {
|
||||
Adapter,
|
||||
AdapterSession,
|
||||
AdapterUser,
|
||||
AdapterAccount,
|
||||
VerificationToken as AdapterVerificationToken,
|
||||
} from "@auth/core/adapters"
|
||||
|
||||
export { up } from "./migrations"
|
||||
|
||||
/**
|
||||
* @type @cloudflare/workers-types.D1Database | @miniflare/d1.D1Database
|
||||
*/
|
||||
export type D1Database = WorkerDatabase | MiniflareD1Database
|
||||
|
||||
// all the sqls
|
||||
// USER
|
||||
export const CREATE_USER_SQL = `INSERT INTO users (id, name, email, emailVerified, image) VALUES (?, ?, ?, ?, ?)`
|
||||
export const GET_USER_BY_ID_SQL = `SELECT * FROM users WHERE id = ?`
|
||||
export const GET_USER_BY_EMAIL_SQL = `SELECT * FROM users WHERE email = ?`
|
||||
export const GET_USER_BY_ACCOUNTL_SQL = `
|
||||
SELECT u.*
|
||||
FROM users u JOIN accounts a ON a.userId = u.id
|
||||
WHERE a.providerAccountId = ? AND a.provider = ?`
|
||||
export const UPDATE_USER_BY_ID_SQL = `
|
||||
UPDATE users
|
||||
SET name = ?, email = ?, emailVerified = ?, image = ?
|
||||
WHERE id = ? `
|
||||
export const DELETE_USER_SQL = `DELETE FROM users WHERE id = ?`
|
||||
|
||||
// SESSION
|
||||
export const CREATE_SESSION_SQL =
|
||||
"INSERT INTO sessions (id, sessionToken, userId, expires) VALUES (?,?,?,?)"
|
||||
export const GET_SESSION_BY_TOKEN_SQL = `
|
||||
SELECT id, sessionToken, userId, expires
|
||||
FROM sessions
|
||||
WHERE sessionToken = ?`
|
||||
export const UPDATE_SESSION_BY_SESSION_TOKEN_SQL = `UPDATE sessions SET expires = ? WHERE sessionToken = ?`
|
||||
export const DELETE_SESSION_SQL = `DELETE FROM sessions WHERE sessionToken = ?`
|
||||
export const DELETE_SESSION_BY_USER_ID_SQL = `DELETE FROM sessions WHERE userId = ?`
|
||||
|
||||
// ACCOUNT
|
||||
export const CREATE_ACCOUNT_SQL = `
|
||||
INSERT INTO accounts (
|
||||
id, userId, type, provider,
|
||||
providerAccountId, refresh_token, access_token,
|
||||
expires_at, token_type, scope, id_token, session_state,
|
||||
oauth_token, oauth_token_secret
|
||||
)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
|
||||
export const GET_ACCOUNT_BY_ID_SQL = `SELECT * FROM accounts WHERE id = ? `
|
||||
export const GET_ACCOUNT_BY_PROVIDER_AND_PROVIDER_ACCOUNT_ID_SQL = `SELECT * FROM accounts WHERE provider = ? AND providerAccountId = ?`
|
||||
export const DELETE_ACCOUNT_BY_PROVIDER_AND_PROVIDER_ACCOUNT_ID_SQL = `DELETE FROM accounts WHERE provider = ? AND providerAccountId = ?`
|
||||
export const DELETE_ACCOUNT_BY_USER_ID_SQL = `DELETE FROM accounts WHERE userId = ?`
|
||||
|
||||
// VERIFICATION_TOKEN
|
||||
export const GET_VERIFICATION_TOKEN_BY_IDENTIFIER_AND_TOKEN_SQL = `SELECT * FROM verification_tokens WHERE identifier = ? AND token = ?`
|
||||
export const CREATE_VERIFICATION_TOKEN_SQL = `INSERT INTO verification_tokens (identifier, expires, token) VALUES (?,?,?)`
|
||||
export const DELETE_VERIFICATION_TOKEN_SQL = `DELETE FROM verification_tokens WHERE identifier = ? and token = ?`
|
||||
|
||||
// helper functions
|
||||
|
||||
// isDate is borrowed from the supabase adapter, graciously
|
||||
// depending on error messages ("Invalid Date") is always precarious, but probably fine for a built in native like Date
|
||||
function isDate(date: any) {
|
||||
return (
|
||||
new Date(date).toString() !== "Invalid Date" && !isNaN(Date.parse(date))
|
||||
)
|
||||
}
|
||||
|
||||
// format is borrowed from the supabase adapter, graciously
|
||||
function format<T>(obj: Record<string, any>): T {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
if (value === null) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
delete obj[key]
|
||||
}
|
||||
|
||||
if (isDate(value)) {
|
||||
obj[key] = new Date(value)
|
||||
}
|
||||
}
|
||||
|
||||
return obj as T
|
||||
}
|
||||
|
||||
// D1 doesnt like undefined, it wants null when calling bind
|
||||
function cleanBindings(bindings: any[]) {
|
||||
return bindings.map((e) => (e === undefined ? null : e))
|
||||
}
|
||||
|
||||
export async function createRecord<RecordType>(
|
||||
db: D1Database,
|
||||
CREATE_SQL: string,
|
||||
bindings: any[],
|
||||
GET_SQL: string,
|
||||
getBindings: any[]
|
||||
) {
|
||||
try {
|
||||
bindings = cleanBindings(bindings)
|
||||
await db
|
||||
.prepare(CREATE_SQL)
|
||||
.bind(...bindings)
|
||||
.run()
|
||||
return await getRecord<RecordType>(db, GET_SQL, getBindings)
|
||||
} catch (e: any) {
|
||||
console.error(e.message, e.cause?.message)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
export async function getRecord<RecordType>(
|
||||
db: D1Database,
|
||||
SQL: string,
|
||||
bindings: any[]
|
||||
): Promise<RecordType | null> {
|
||||
try {
|
||||
bindings = cleanBindings(bindings)
|
||||
const res: any = await db
|
||||
.prepare(SQL)
|
||||
.bind(...bindings)
|
||||
.first()
|
||||
if (res) {
|
||||
return format<RecordType>(res)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
} catch (e: any) {
|
||||
console.error(e.message, e.cause?.message)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateRecord(
|
||||
db: D1Database,
|
||||
SQL: string,
|
||||
bindings: any[]
|
||||
) {
|
||||
try {
|
||||
bindings = cleanBindings(bindings)
|
||||
return await db
|
||||
.prepare(SQL)
|
||||
.bind(...bindings)
|
||||
.run()
|
||||
} catch (e: any) {
|
||||
console.error(e.message, e.cause?.message)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteRecord(
|
||||
db: D1Database,
|
||||
SQL: string,
|
||||
bindings: any[]
|
||||
) {
|
||||
// eslint-disable-next-line no-useless-catch
|
||||
try {
|
||||
bindings = cleanBindings(bindings)
|
||||
await db
|
||||
.prepare(SQL)
|
||||
.bind(...bindings)
|
||||
.run()
|
||||
} catch (e: any) {
|
||||
console.error(e.message, e.cause?.message)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* ## Setup
|
||||
*
|
||||
* This is the D1 Adapter for [`next-auth`](https://authjs.dev). This package can only be used in conjunction with the primary `next-auth` package. It is not a standalone package.
|
||||
*
|
||||
* ### Configure Auth.js
|
||||
*
|
||||
* ```javascript title="pages/api/auth/[...nextauth].js"
|
||||
* import NextAuth from "next-auth"
|
||||
* import { D1Adapter, up } from "@auth/d1-adapter"
|
||||
*
|
||||
*
|
||||
* // For more information on each option (and a full list of options) go to
|
||||
* // https://authjs.dev/reference/configuration/auth-options
|
||||
* export default NextAuth({
|
||||
* // https://authjs.dev/reference/providers/
|
||||
* providers: [],
|
||||
* adapter: D1Adapter(env.db)
|
||||
* ...
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* ### Migrations
|
||||
*
|
||||
* Somewhere in the initialization of your application you need to run the `up(env.db)` function to create the tables in D1.
|
||||
* It will create 4 tables if they don't already exist:
|
||||
* `accounts`, `sessions`, `users`, `verification_tokens`.
|
||||
*
|
||||
* The table prefix "" is not configurable at this time.
|
||||
*
|
||||
* You can use something like the following to attempt the migration once each time your worker starts up. Running migrations more than once will not erase your existing tables.
|
||||
* ```javascript
|
||||
* import { up } from "@auth/d1-adapter"
|
||||
*
|
||||
* let migrated = false;
|
||||
* async function migrationHandle({event, resolve}) {
|
||||
* if(!migrated) {
|
||||
* try {
|
||||
* await up(event.platform.env.db)
|
||||
* migrated = true
|
||||
* } catch(e) {
|
||||
* console.log(e.cause.message, e.message)
|
||||
* }
|
||||
* }
|
||||
* return resolve(event)
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*
|
||||
* You can also initialize your tables manually. Look in [init.ts](https://github.com/nextauthjs/next-auth/packages/adapter-d1/src/migrations/init.ts) for the relevant sql.
|
||||
* Paste and run the SQL into your D1 dashboard query tool.
|
||||
*
|
||||
**/
|
||||
export function D1Adapter(db: D1Database): Adapter {
|
||||
// we need to run migrations if we dont have the right tables
|
||||
|
||||
return {
|
||||
async createUser(user) {
|
||||
const id: string = crypto.randomUUID()
|
||||
const createBindings = [
|
||||
id,
|
||||
user.name,
|
||||
user.email,
|
||||
user.emailVerified?.toISOString(),
|
||||
user.image,
|
||||
]
|
||||
const getBindings = [id]
|
||||
|
||||
const newUser = await createRecord<AdapterUser>(
|
||||
db,
|
||||
CREATE_USER_SQL,
|
||||
createBindings,
|
||||
GET_USER_BY_ID_SQL,
|
||||
getBindings
|
||||
)
|
||||
if (newUser) return newUser
|
||||
throw new Error("Error creating user: Cannot get user after creation.")
|
||||
},
|
||||
async getUser(id) {
|
||||
return await getRecord<AdapterUser>(db, GET_USER_BY_ID_SQL, [id])
|
||||
},
|
||||
async getUserByEmail(email) {
|
||||
return await getRecord<AdapterUser>(db, GET_USER_BY_EMAIL_SQL, [email])
|
||||
},
|
||||
async getUserByAccount({ providerAccountId, provider }) {
|
||||
return await getRecord<AdapterUser>(db, GET_USER_BY_ACCOUNTL_SQL, [
|
||||
providerAccountId,
|
||||
provider,
|
||||
])
|
||||
},
|
||||
async updateUser(user) {
|
||||
const params = await getRecord<AdapterUser>(db, GET_USER_BY_ID_SQL, [
|
||||
user.id,
|
||||
])
|
||||
if (params) {
|
||||
// copy any properties not in the update into the existing one and use that for bind params
|
||||
// covers the scenario where the user arg doesnt have all of the current users properties
|
||||
Object.assign(params, user)
|
||||
const res = await updateRecord(db, UPDATE_USER_BY_ID_SQL, [
|
||||
params.name,
|
||||
params.email,
|
||||
params.emailVerified?.toISOString(),
|
||||
params.image,
|
||||
params.id,
|
||||
])
|
||||
if (res.success) {
|
||||
// we could probably just return
|
||||
const user = await getRecord<AdapterUser>(db, GET_USER_BY_ID_SQL, [
|
||||
params.id,
|
||||
])
|
||||
if (user) return user
|
||||
throw new Error(
|
||||
"Error updating user: Cannot get user after updating."
|
||||
)
|
||||
}
|
||||
}
|
||||
throw new Error("Error updating user: Failed to run the update SQL.")
|
||||
},
|
||||
async deleteUser(userId) {
|
||||
// this should probably be in a db.batch but batch has problems right now in miniflare
|
||||
// no multi line sql statements
|
||||
await deleteRecord(db, DELETE_ACCOUNT_BY_USER_ID_SQL, [userId])
|
||||
await deleteRecord(db, DELETE_SESSION_BY_USER_ID_SQL, [userId])
|
||||
await deleteRecord(db, DELETE_USER_SQL, [userId])
|
||||
return null
|
||||
},
|
||||
async linkAccount(a) {
|
||||
// convert user_id to userId and provider_account_id to providerAccountId
|
||||
const id = crypto.randomUUID()
|
||||
const createBindings = [
|
||||
id,
|
||||
a.userId,
|
||||
a.type,
|
||||
a.provider,
|
||||
a.providerAccountId,
|
||||
a.refresh_token,
|
||||
a.access_token,
|
||||
a.expires_at,
|
||||
a.token_type,
|
||||
a.scope,
|
||||
a.id_token,
|
||||
a.session_state,
|
||||
a.oauth_token ?? null,
|
||||
a.oauth_token_secret ?? null,
|
||||
]
|
||||
const getBindings = [id]
|
||||
return await createRecord<AdapterAccount>(
|
||||
db,
|
||||
CREATE_ACCOUNT_SQL,
|
||||
createBindings,
|
||||
GET_ACCOUNT_BY_ID_SQL,
|
||||
getBindings
|
||||
)
|
||||
},
|
||||
async unlinkAccount({ providerAccountId, provider }) {
|
||||
await deleteRecord(
|
||||
db,
|
||||
DELETE_ACCOUNT_BY_PROVIDER_AND_PROVIDER_ACCOUNT_ID_SQL,
|
||||
[provider, providerAccountId]
|
||||
)
|
||||
},
|
||||
async createSession({ sessionToken, userId, expires }) {
|
||||
const id = crypto.randomUUID()
|
||||
const createBindings = [id, sessionToken, userId, expires.toISOString()]
|
||||
const getBindings = [sessionToken]
|
||||
const session = await createRecord<AdapterSession>(
|
||||
db,
|
||||
CREATE_SESSION_SQL,
|
||||
createBindings,
|
||||
GET_SESSION_BY_TOKEN_SQL,
|
||||
getBindings
|
||||
)
|
||||
if (session) return session
|
||||
throw new Error(`Couldn't create session`)
|
||||
},
|
||||
async getSessionAndUser(sessionToken) {
|
||||
const session: any = await getRecord<AdapterSession>(
|
||||
db,
|
||||
GET_SESSION_BY_TOKEN_SQL,
|
||||
[sessionToken]
|
||||
)
|
||||
// no session? no user!
|
||||
if (session === null) return null
|
||||
|
||||
// this shouldnt happen, but just in case
|
||||
const user = await getRecord<AdapterUser>(db, GET_USER_BY_ID_SQL, [
|
||||
session.userId,
|
||||
])
|
||||
if (user === null) return null
|
||||
|
||||
return { session, user }
|
||||
},
|
||||
async updateSession({ sessionToken, expires }) {
|
||||
// kinda strange that we have to deal with an undefined expires,
|
||||
// we dont have any policy to enforce, lets just expire it now.
|
||||
if (expires === undefined) {
|
||||
await deleteRecord(db, DELETE_SESSION_SQL, [sessionToken])
|
||||
return null
|
||||
}
|
||||
const session = await getRecord<AdapterSession>(
|
||||
db,
|
||||
GET_SESSION_BY_TOKEN_SQL,
|
||||
[sessionToken]
|
||||
)
|
||||
if (!session) return null
|
||||
session.expires = expires
|
||||
await updateRecord(db, UPDATE_SESSION_BY_SESSION_TOKEN_SQL, [
|
||||
expires?.toISOString(),
|
||||
sessionToken,
|
||||
])
|
||||
return await db
|
||||
.prepare(UPDATE_SESSION_BY_SESSION_TOKEN_SQL)
|
||||
.bind(expires?.toISOString(), sessionToken)
|
||||
.first()
|
||||
},
|
||||
async deleteSession(sessionToken) {
|
||||
await deleteRecord(db, DELETE_SESSION_SQL, [sessionToken])
|
||||
return null
|
||||
},
|
||||
async createVerificationToken({ identifier, expires, token }) {
|
||||
return await createRecord(
|
||||
db,
|
||||
CREATE_VERIFICATION_TOKEN_SQL,
|
||||
[identifier, expires.toISOString(), token],
|
||||
GET_VERIFICATION_TOKEN_BY_IDENTIFIER_AND_TOKEN_SQL,
|
||||
[identifier, token]
|
||||
)
|
||||
},
|
||||
async useVerificationToken({ identifier, token }) {
|
||||
const verificationToken = await getRecord<AdapterVerificationToken>(
|
||||
db,
|
||||
GET_VERIFICATION_TOKEN_BY_IDENTIFIER_AND_TOKEN_SQL,
|
||||
[identifier, token]
|
||||
)
|
||||
if (!verificationToken) return null
|
||||
await deleteRecord(db, DELETE_VERIFICATION_TOKEN_SQL, [identifier, token])
|
||||
return verificationToken
|
||||
},
|
||||
}
|
||||
}
|
||||
66
packages/adapter-d1/src/migrations.ts
Normal file
66
packages/adapter-d1/src/migrations.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import type { D1Database } from "."
|
||||
|
||||
export const upSQLStatements = [
|
||||
`CREATE TABLE IF NOT EXISTS "accounts" (
|
||||
"id" text NOT NULL,
|
||||
"userId" text NOT NULL DEFAULT NULL,
|
||||
"type" text NOT NULL DEFAULT NULL,
|
||||
"provider" text NOT NULL DEFAULT NULL,
|
||||
"providerAccountId" text NOT NULL DEFAULT NULL,
|
||||
"refresh_token" text DEFAULT NULL,
|
||||
"access_token" text DEFAULT NULL,
|
||||
"expires_at" number DEFAULT NULL,
|
||||
"token_type" text DEFAULT NULL,
|
||||
"scope" text DEFAULT NULL,
|
||||
"id_token" text DEFAULT NULL,
|
||||
"session_state" text DEFAULT NULL,
|
||||
"oauth_token_secret" text DEFAULT NULL,
|
||||
"oauth_token" text DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);`,
|
||||
`CREATE TABLE IF NOT EXISTS "sessions" (
|
||||
"id" text NOT NULL,
|
||||
"sessionToken" text NOT NULL,
|
||||
"userId" text NOT NULL DEFAULT NULL,
|
||||
"expires" datetime NOT NULL DEFAULT NULL,
|
||||
PRIMARY KEY (sessionToken)
|
||||
);`,
|
||||
`CREATE TABLE IF NOT EXISTS "users" (
|
||||
"id" text NOT NULL DEFAULT '',
|
||||
"name" text DEFAULT NULL,
|
||||
"email" text DEFAULT NULL,
|
||||
"emailVerified" datetime DEFAULT NULL,
|
||||
"image" text DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);`,
|
||||
`CREATE TABLE IF NOT EXISTS "verification_tokens" (
|
||||
"identifier" text NOT NULL,
|
||||
"token" text NOT NULL DEFAULT NULL,
|
||||
"expires" datetime NOT NULL DEFAULT NULL,
|
||||
PRIMARY KEY (token)
|
||||
);`,
|
||||
]
|
||||
|
||||
export const down = [
|
||||
`DROP TABLE IF EXISTS "accounts";`,
|
||||
`DROP TABLE IF EXISTS "sessions";`,
|
||||
`DROP TABLE IF EXISTS "users";`,
|
||||
`DROP TABLE IF EXISTS "verification_token";`,
|
||||
]
|
||||
|
||||
/**
|
||||
*
|
||||
* @param db
|
||||
*/
|
||||
async function up(db: D1Database) {
|
||||
// run the migration
|
||||
upSQLStatements.forEach(async (sql) => {
|
||||
try {
|
||||
const res = await db.prepare(sql).run()
|
||||
} catch (e: any) {
|
||||
console.error(e.cause?.message, e.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export { up }
|
||||
56
packages/adapter-d1/tests/index.test.ts
Normal file
56
packages/adapter-d1/tests/index.test.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import {
|
||||
D1Adapter,
|
||||
up,
|
||||
getRecord,
|
||||
GET_USER_BY_ID_SQL,
|
||||
GET_SESSION_BY_TOKEN_SQL,
|
||||
GET_ACCOUNT_BY_PROVIDER_AND_PROVIDER_ACCOUNT_ID_SQL,
|
||||
GET_VERIFICATION_TOKEN_BY_IDENTIFIER_AND_TOKEN_SQL,
|
||||
} from "../src"
|
||||
import {
|
||||
AdapterSession,
|
||||
AdapterUser,
|
||||
AdapterAccount,
|
||||
} from "@auth/core/adapters"
|
||||
import { D1Database, D1DatabaseAPI } from "@miniflare/d1"
|
||||
import { runBasicTests } from "@auth/adapter-test"
|
||||
import Database from "better-sqlite3"
|
||||
|
||||
globalThis.crypto ??= require("node:crypto").webcrypto
|
||||
|
||||
if (process.env.CI) {
|
||||
// TODO: Fix this
|
||||
test('Skipping D1Adapter tests in CI because of "Error: Must use import to load ES Module: next-auth/node_modules/.pnpm/undici@5.20.0/node_modules/undici/lib/llhttp/llhttp.wasm" errors. Should revisit', () => {
|
||||
expect(true).toBe(true)
|
||||
})
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const sqliteDB = new Database(":memory:")
|
||||
let db = new D1Database(new D1DatabaseAPI(sqliteDB as any))
|
||||
let adapter = D1Adapter(db)
|
||||
|
||||
// put stuff here if we need some async init
|
||||
beforeAll(async () => await up(db))
|
||||
runBasicTests({
|
||||
adapter,
|
||||
db: {
|
||||
user: async (id) =>
|
||||
await getRecord<AdapterUser>(db, GET_USER_BY_ID_SQL, [id]),
|
||||
session: async (sessionToken) =>
|
||||
await getRecord<AdapterSession>(db, GET_SESSION_BY_TOKEN_SQL, [
|
||||
sessionToken,
|
||||
]),
|
||||
account: async ({ provider, providerAccountId }) =>
|
||||
await getRecord<AdapterAccount>(
|
||||
db,
|
||||
GET_ACCOUNT_BY_PROVIDER_AND_PROVIDER_ACCOUNT_ID_SQL,
|
||||
[provider, providerAccountId]
|
||||
),
|
||||
verificationToken: async ({ identifier, token }) =>
|
||||
await getRecord(db, GET_VERIFICATION_TOKEN_BY_IDENTIFIER_AND_TOKEN_SQL, [
|
||||
identifier,
|
||||
token,
|
||||
]),
|
||||
},
|
||||
})
|
||||
20
packages/adapter-d1/tsconfig.json
Normal file
20
packages/adapter-d1/tsconfig.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "@auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["*.js", "*.d.ts"]
|
||||
}
|
||||
@@ -8,6 +8,9 @@
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"author": "Bruno Crosier",
|
||||
"contributors": [
|
||||
"Thang Huu Vu <hi@thvu.dev>"
|
||||
],
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"files": [
|
||||
@@ -37,9 +40,11 @@
|
||||
"build": "tsc",
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"edgedb": "^1.0.1",
|
||||
"@auth/core": "^0.3.0"
|
||||
"edgedb": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@auth/adapter-test": "workspace:^0.0.0",
|
||||
@@ -52,4 +57,4 @@
|
||||
"jest": {
|
||||
"preset": "@auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
28
packages/adapter-pg/README.md
Normal file
28
packages/adapter-pg/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
<p align="center">
|
||||
<br/>
|
||||
<a href="https://authjs.dev" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/logo/logo-sm.png" />
|
||||
</a>
|
||||
<a href="https://www.postgresql.org/" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/adapters/pg.png"/>
|
||||
</a>
|
||||
<h3 align="center"><b>Postgres Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@auth/pg-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@auth/pg-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/pg-adapter?color=green&label=@auth/pg-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@auth/pg-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/pg-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
Check out the documentation at [authjs.dev](https://authjs.dev/reference/adapter/pg).
|
||||
13
packages/adapter-pg/docker-compose.yaml
Normal file
13
packages/adapter-pg/docker-compose.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
version: "3"
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:latest
|
||||
container_name: pg-adapter
|
||||
environment:
|
||||
POSTGRES_DB: adapter-postgres-test
|
||||
POSTGRES_USER: pg
|
||||
POSTGRES_PASSWORD: pg
|
||||
volumes:
|
||||
- ./example-schema.sql:/docker-entrypoint-initdb.d/example-schema.sql
|
||||
ports:
|
||||
- 5432:5432
|
||||
49
packages/adapter-pg/example-schema.sql
Normal file
49
packages/adapter-pg/example-schema.sql
Normal file
@@ -0,0 +1,49 @@
|
||||
\set ON_ERROR_STOP true
|
||||
|
||||
CREATE TABLE verification_token
|
||||
(
|
||||
identifier TEXT NOT NULL,
|
||||
expires TIMESTAMPTZ NOT NULL,
|
||||
token TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (identifier, token)
|
||||
);
|
||||
|
||||
CREATE TABLE accounts
|
||||
(
|
||||
id SERIAL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
type VARCHAR(255) NOT NULL,
|
||||
provider VARCHAR(255) NOT NULL,
|
||||
"providerAccountId" VARCHAR(255) NOT NULL,
|
||||
refresh_token TEXT,
|
||||
access_token TEXT,
|
||||
expires_at BIGINT,
|
||||
id_token TEXT,
|
||||
scope TEXT,
|
||||
session_state TEXT,
|
||||
token_type TEXT,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE sessions
|
||||
(
|
||||
id SERIAL,
|
||||
"userId" INTEGER NOT NULL,
|
||||
expires TIMESTAMPTZ NOT NULL,
|
||||
"sessionToken" VARCHAR(255) NOT NULL,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE users
|
||||
(
|
||||
id SERIAL,
|
||||
name VARCHAR(255),
|
||||
email VARCHAR(255),
|
||||
"emailVerified" TIMESTAMPTZ,
|
||||
image TEXT,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
59
packages/adapter-pg/package.json
Normal file
59
packages/adapter-pg/package.json
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "@auth/pg-adapter",
|
||||
"version": "0.2.0",
|
||||
"description": "Postgres adapter for next-auth.",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"author": "Jake Coppinger",
|
||||
"contributors": [
|
||||
"Thang Huu Vu <hi@thvu.dev>"
|
||||
],
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
"@auth",
|
||||
"Auth.js",
|
||||
"next.js",
|
||||
"oauth",
|
||||
"postgres"
|
||||
],
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"*.d.ts*",
|
||||
"*.js",
|
||||
"src"
|
||||
],
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./tests/test.sh",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"pg": "^8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@auth/adapter-test": "workspace:*",
|
||||
"@auth/tsconfig": "workspace:*",
|
||||
"@types/pg": "^8.6.5",
|
||||
"jest": "^27.4.3",
|
||||
"pg": "^8.7.1"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
346
packages/adapter-pg/src/index.ts
Normal file
346
packages/adapter-pg/src/index.ts
Normal file
@@ -0,0 +1,346 @@
|
||||
/**
|
||||
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}>
|
||||
* <p style={{fontWeight: "normal"}}>An official <a href="https://www.postgresql.org/">PostgreSQL</a> adapter for Auth.js / NextAuth.js.</p>
|
||||
* <a href="https://www.postgresql.org/">
|
||||
* <img style={{display: "block"}} src="/img/adapters/pg.png" width="48" />
|
||||
* </a>
|
||||
* </div>
|
||||
*
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth @auth/pg-adapter pg
|
||||
* ```
|
||||
*
|
||||
* @module @auth/pg-adapter
|
||||
*/
|
||||
|
||||
import type {
|
||||
Adapter,
|
||||
AdapterUser,
|
||||
VerificationToken,
|
||||
AdapterSession,
|
||||
} from "@auth/core/adapters"
|
||||
import type { Pool } from "pg"
|
||||
|
||||
export function mapExpiresAt(account: any): any {
|
||||
const expires_at: number = parseInt(account.expires_at)
|
||||
return {
|
||||
...account,
|
||||
expires_at,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ## Setup
|
||||
*
|
||||
* The SQL schema for the tables used by this adapter is as follows. Learn more about the models at our doc page on [Database Models](http://localhost:3000/reference/adapters#models).
|
||||
* ```sql
|
||||
* CREATE TABLE verification_token
|
||||
* (
|
||||
* identifier TEXT NOT NULL,
|
||||
* expires TIMESTAMPTZ NOT NULL,
|
||||
* token TEXT NOT NULL,
|
||||
*
|
||||
* PRIMARY KEY (identifier, token)
|
||||
* );
|
||||
*
|
||||
* CREATE TABLE accounts
|
||||
* (
|
||||
* id SERIAL,
|
||||
* "userId" INTEGER NOT NULL,
|
||||
* type VARCHAR(255) NOT NULL,
|
||||
* provider VARCHAR(255) NOT NULL,
|
||||
* "providerAccountId" VARCHAR(255) NOT NULL,
|
||||
* refresh_token TEXT,
|
||||
* access_token TEXT,
|
||||
* expires_at BIGINT,
|
||||
* id_token TEXT,
|
||||
* scope TEXT,
|
||||
* session_state TEXT,
|
||||
* token_type TEXT,
|
||||
*
|
||||
* PRIMARY KEY (id)
|
||||
* );
|
||||
*
|
||||
* CREATE TABLE sessions
|
||||
* (
|
||||
* id SERIAL,
|
||||
* "userId" INTEGER NOT NULL,
|
||||
* expires TIMESTAMPTZ NOT NULL,
|
||||
* "sessionToken" VARCHAR(255) NOT NULL,
|
||||
*
|
||||
* PRIMARY KEY (id)
|
||||
* );
|
||||
*
|
||||
* CREATE TABLE users
|
||||
* (
|
||||
* id SERIAL,
|
||||
* name VARCHAR(255),
|
||||
* email VARCHAR(255),
|
||||
* "emailVerified" TIMESTAMPTZ,
|
||||
* image TEXT,
|
||||
*
|
||||
* PRIMARY KEY (id)
|
||||
* );
|
||||
*
|
||||
* ```
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install pg @auth/pg-adapter next-auth
|
||||
* ```
|
||||
*
|
||||
* ```typescript title="auth.ts"
|
||||
* import NextAuth from "next-auth"
|
||||
* import GoogleProvider from "next-auth/providers/google"
|
||||
* import { PostgresAdapter } from "@auth/pg-adapter"
|
||||
* import { Pool } from 'pg'
|
||||
*
|
||||
* const pool = new Pool({
|
||||
* host: 'localhost',
|
||||
* user: 'database-user',
|
||||
* max: 20,
|
||||
* idleTimeoutMillis: 30000,
|
||||
* connectionTimeoutMillis: 2000,
|
||||
* })
|
||||
*
|
||||
* export default NextAuth({
|
||||
* adapter: PostgresAdapter(pool),
|
||||
* providers: [
|
||||
* GoogleProvider({
|
||||
* clientId: process.env.GOOGLE_CLIENT_ID,
|
||||
* clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
* }),
|
||||
* ],
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
export default function PostgresAdapter(client: Pool): Adapter {
|
||||
return {
|
||||
async createVerificationToken(
|
||||
verificationToken: VerificationToken
|
||||
): Promise<VerificationToken> {
|
||||
const { identifier, expires, token } = verificationToken
|
||||
const sql = `
|
||||
INSERT INTO verification_token ( identifier, expires, token )
|
||||
VALUES ($1, $2, $3)
|
||||
`
|
||||
await client.query(sql, [identifier, expires, token])
|
||||
return verificationToken
|
||||
},
|
||||
async useVerificationToken({
|
||||
identifier,
|
||||
token,
|
||||
}: {
|
||||
identifier: string
|
||||
token: string
|
||||
}): Promise<VerificationToken> {
|
||||
const sql = `delete from verification_token
|
||||
where identifier = $1 and token = $2
|
||||
RETURNING identifier, expires, token `
|
||||
const result = await client.query(sql, [identifier, token])
|
||||
return result.rowCount !== 0 ? result.rows[0] : null
|
||||
},
|
||||
|
||||
async createUser(user: Omit<AdapterUser, "id">) {
|
||||
const { name, email, emailVerified, image } = user
|
||||
const sql = `
|
||||
INSERT INTO users (name, email, "emailVerified", image)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id, name, email, "emailVerified", image`
|
||||
const result = await client.query(sql, [
|
||||
name,
|
||||
email,
|
||||
emailVerified,
|
||||
image,
|
||||
])
|
||||
return result.rows[0]
|
||||
},
|
||||
async getUser(id) {
|
||||
const sql = `select * from users where id = $1`
|
||||
try {
|
||||
const result = await client.query(sql, [id])
|
||||
return result.rowCount === 0 ? null : result.rows[0]
|
||||
} catch (e) {
|
||||
return null
|
||||
}
|
||||
},
|
||||
async getUserByEmail(email) {
|
||||
const sql = `select * from users where email = $1`
|
||||
const result = await client.query(sql, [email])
|
||||
return result.rowCount !== 0 ? result.rows[0] : null
|
||||
},
|
||||
async getUserByAccount({
|
||||
providerAccountId,
|
||||
provider,
|
||||
}): Promise<AdapterUser | null> {
|
||||
const sql = `
|
||||
select u.* from users u join accounts a on u.id = a."userId"
|
||||
where
|
||||
a.provider = $1
|
||||
and
|
||||
a."providerAccountId" = $2`
|
||||
|
||||
const result = await client.query(sql, [provider, providerAccountId])
|
||||
return result.rowCount !== 0 ? result.rows[0] : null
|
||||
},
|
||||
async updateUser(user: Partial<AdapterUser>): Promise<AdapterUser> {
|
||||
const fetchSql = `select * from users where id = $1`
|
||||
const query1 = await client.query(fetchSql, [user.id])
|
||||
const oldUser = query1.rows[0]
|
||||
|
||||
const newUser = {
|
||||
...oldUser,
|
||||
...user,
|
||||
}
|
||||
|
||||
const { id, name, email, emailVerified, image } = newUser
|
||||
const updateSql = `
|
||||
UPDATE users set
|
||||
name = $2, email = $3, "emailVerified" = $4, image = $5
|
||||
where id = $1
|
||||
RETURNING name, id, email, "emailVerified", image
|
||||
`
|
||||
const query2 = await client.query(updateSql, [
|
||||
id,
|
||||
name,
|
||||
email,
|
||||
emailVerified,
|
||||
image,
|
||||
])
|
||||
return query2.rows[0]
|
||||
},
|
||||
async linkAccount(account) {
|
||||
const sql = `
|
||||
insert into accounts
|
||||
(
|
||||
"userId",
|
||||
provider,
|
||||
type,
|
||||
"providerAccountId",
|
||||
access_token,
|
||||
expires_at,
|
||||
refresh_token,
|
||||
id_token,
|
||||
scope,
|
||||
session_state,
|
||||
token_type
|
||||
)
|
||||
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
||||
returning
|
||||
id,
|
||||
"userId",
|
||||
provider,
|
||||
type,
|
||||
"providerAccountId",
|
||||
access_token,
|
||||
expires_at,
|
||||
refresh_token,
|
||||
id_token,
|
||||
scope,
|
||||
session_state,
|
||||
token_type
|
||||
`
|
||||
|
||||
const params = [
|
||||
account.userId,
|
||||
account.provider,
|
||||
account.type,
|
||||
account.providerAccountId,
|
||||
account.access_token,
|
||||
account.expires_at,
|
||||
account.refresh_token,
|
||||
account.id_token,
|
||||
account.scope,
|
||||
account.session_state,
|
||||
account.token_type,
|
||||
]
|
||||
|
||||
const result = await client.query(sql, params)
|
||||
return mapExpiresAt(result.rows[0])
|
||||
},
|
||||
async createSession({ sessionToken, userId, expires }) {
|
||||
if (userId === undefined) {
|
||||
throw Error(`userId is undef in createSession`)
|
||||
}
|
||||
const sql = `insert into sessions ("userId", expires, "sessionToken")
|
||||
values ($1, $2, $3)
|
||||
RETURNING id, "sessionToken", "userId", expires`
|
||||
|
||||
const result = await client.query(sql, [userId, expires, sessionToken])
|
||||
return result.rows[0]
|
||||
},
|
||||
|
||||
async getSessionAndUser(sessionToken: string | undefined): Promise<{
|
||||
session: AdapterSession
|
||||
user: AdapterUser
|
||||
} | null> {
|
||||
if (sessionToken === undefined) {
|
||||
return null
|
||||
}
|
||||
const result1 = await client.query(
|
||||
`select * from sessions where "sessionToken" = $1`,
|
||||
[sessionToken]
|
||||
)
|
||||
if (result1.rowCount === 0) {
|
||||
return null
|
||||
}
|
||||
let session: AdapterSession = result1.rows[0]
|
||||
|
||||
const result2 = await client.query("select * from users where id = $1", [
|
||||
session.userId,
|
||||
])
|
||||
if (result2.rowCount === 0) {
|
||||
return null
|
||||
}
|
||||
const user = result2.rows[0]
|
||||
return {
|
||||
session,
|
||||
user,
|
||||
}
|
||||
},
|
||||
async updateSession(
|
||||
session: Partial<AdapterSession> & Pick<AdapterSession, "sessionToken">
|
||||
): Promise<AdapterSession | null | undefined> {
|
||||
const { sessionToken } = session
|
||||
const result1 = await client.query(
|
||||
`select * from sessions where "sessionToken" = $1`,
|
||||
[sessionToken]
|
||||
)
|
||||
if (result1.rowCount === 0) {
|
||||
return null
|
||||
}
|
||||
const originalSession: AdapterSession = result1.rows[0]
|
||||
|
||||
const newSession: AdapterSession = {
|
||||
...originalSession,
|
||||
...session,
|
||||
}
|
||||
const sql = `
|
||||
UPDATE sessions set
|
||||
expires = $2
|
||||
where "sessionToken" = $1
|
||||
`
|
||||
const result = await client.query(sql, [
|
||||
newSession.sessionToken,
|
||||
newSession.expires,
|
||||
])
|
||||
return result.rows[0]
|
||||
},
|
||||
async deleteSession(sessionToken) {
|
||||
const sql = `delete from sessions where "sessionToken" = $1`
|
||||
await client.query(sql, [sessionToken])
|
||||
},
|
||||
async unlinkAccount(partialAccount) {
|
||||
const { provider, providerAccountId } = partialAccount
|
||||
const sql = `delete from accounts where "providerAccountId" = $1 and provider = $2`
|
||||
await client.query(sql, [providerAccountId, provider])
|
||||
},
|
||||
async deleteUser(userId: string) {
|
||||
await client.query(`delete from users where id = $1`, [userId])
|
||||
await client.query(`delete from sessions where "userId" = $1`, [userId])
|
||||
await client.query(`delete from accounts where "userId" = $1`, [userId])
|
||||
},
|
||||
}
|
||||
}
|
||||
50
packages/adapter-pg/tests/index.test.ts
Normal file
50
packages/adapter-pg/tests/index.test.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { runBasicTests } from "@auth/adapter-test"
|
||||
import PostgresAdapter, { mapExpiresAt } from "../src"
|
||||
import { Pool } from "pg"
|
||||
|
||||
const POOL_SIZE = 20
|
||||
|
||||
const client = new Pool({
|
||||
host: "127.0.0.1",
|
||||
database: "adapter-postgres-test",
|
||||
user: "pg",
|
||||
password: "pg",
|
||||
port: 5432,
|
||||
max: POOL_SIZE,
|
||||
})
|
||||
|
||||
runBasicTests({
|
||||
adapter: PostgresAdapter(client),
|
||||
db: {
|
||||
disconnect: async () => {
|
||||
await client.end()
|
||||
},
|
||||
user: async (id: string) => {
|
||||
const sql = `select * from users where id = $1`
|
||||
const result = await client.query(sql, [id])
|
||||
return result.rowCount !== 0 ? result.rows[0] : null
|
||||
},
|
||||
account: async (account) => {
|
||||
const sql = `
|
||||
select * from accounts where "providerAccountId" = $1`
|
||||
|
||||
const result = await client.query(sql, [account.providerAccountId])
|
||||
return result.rowCount !== 0 ? mapExpiresAt(result.rows[0]) : null
|
||||
},
|
||||
session: async (sessionToken) => {
|
||||
const result1 = await client.query(
|
||||
`select * from sessions where "sessionToken" = $1`,
|
||||
[sessionToken]
|
||||
)
|
||||
return result1.rowCount !== 0 ? result1.rows[0] : null
|
||||
},
|
||||
async verificationToken(identifier_token) {
|
||||
const { identifier, token } = identifier_token
|
||||
const sql = `
|
||||
select * from verification_token where identifier = $1 and token = $2`
|
||||
|
||||
const result = await client.query(sql, [identifier, token])
|
||||
return result.rowCount !== 0 ? result.rows[0] : null
|
||||
},
|
||||
},
|
||||
})
|
||||
13
packages/adapter-pg/tests/test.sh
Executable file
13
packages/adapter-pg/tests/test.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
docker-compose up -d
|
||||
|
||||
echo "waiting 10 seconds for databases to start..."
|
||||
sleep 10
|
||||
|
||||
# Always stop container, but exit with 1 when tests are failing
|
||||
if npx jest tests; then
|
||||
docker stop pg-adapter
|
||||
else
|
||||
docker stop pg-adapter && exit 1
|
||||
fi
|
||||
20
packages/adapter-pg/tsconfig.json
Normal file
20
packages/adapter-pg/tsconfig.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "@auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["*.js", "*.d.ts"]
|
||||
}
|
||||
28
packages/adapter-surrealdb/README.md
Normal file
28
packages/adapter-surrealdb/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
<p align="center">
|
||||
<br/>
|
||||
<a href="https://authjs.dev" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/logo/logo-sm.png" />
|
||||
</a>
|
||||
<a href="https://surrealdb.com/" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/adapters/surrealdb.png"/>
|
||||
</a>
|
||||
<h3 align="center"><b>Surreal DB Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@auth/surrealdb-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@auth/surrealdb-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/surrealdb-adapter?color=green&label=@auth/surrealdb-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@auth/surrealdb-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/surrealdb-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
Check out the documentation at [authjs.dev](https://authjs.dev/reference/adapter/surrealdb).
|
||||
58
packages/adapter-surrealdb/package.json
Normal file
58
packages/adapter-surrealdb/package.json
Normal file
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "@auth/surrealdb-adapter",
|
||||
"version": "0.1.0",
|
||||
"description": "SurrealDB adapter for next-auth.",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"author": "Martin Schaer <martin@schaerweb.com>",
|
||||
"contributors": [
|
||||
"Thang Huu Vu <hi@thvu.dev>"
|
||||
],
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.d.ts*",
|
||||
"src"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
"next.js",
|
||||
"oauth",
|
||||
"mongodb",
|
||||
"adapter"
|
||||
],
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./tests/test.sh",
|
||||
"test:watch": "./tests/test.sh -w",
|
||||
"build": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"surrealdb.js": "^0.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@auth/adapter-test": "workspace:*",
|
||||
"@auth/tsconfig": "workspace:*",
|
||||
"jest": "^27.4.3"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
366
packages/adapter-surrealdb/src/index.ts
Normal file
366
packages/adapter-surrealdb/src/index.ts
Normal file
@@ -0,0 +1,366 @@
|
||||
import Surreal, { ExperimentalSurrealHTTP } from "surrealdb.js"
|
||||
import type {
|
||||
Adapter,
|
||||
AdapterUser,
|
||||
AdapterAccount,
|
||||
AdapterSession,
|
||||
VerificationToken,
|
||||
} from "@auth/core/adapters"
|
||||
import type { ProviderType } from "@auth/core/providers"
|
||||
|
||||
type Document = Record<string, string | null | undefined> & { id: string }
|
||||
export type UserDoc = Document & { email: string }
|
||||
export type AccountDoc<T = string> = {
|
||||
id: string
|
||||
userId: T
|
||||
refresh_token?: string
|
||||
access_token?: string
|
||||
type: Extract<ProviderType, "oauth" | "oidc" | "email">
|
||||
provider: string
|
||||
providerAccountId: string
|
||||
expires_at?: number
|
||||
}
|
||||
export type SessionDoc<T = string> = Document & { userId: T }
|
||||
|
||||
const extractId = (surrealId: string) => surrealId.split(":")[1] ?? surrealId
|
||||
|
||||
// Convert DB object to AdapterUser
|
||||
export const docToUser = (doc: UserDoc): AdapterUser => ({
|
||||
...doc,
|
||||
id: extractId(doc.id),
|
||||
emailVerified: doc.emailVerified ? new Date(doc.emailVerified) : null,
|
||||
})
|
||||
|
||||
// Convert DB object to AdapterAccount
|
||||
export const docToAccount = (doc: AccountDoc) => {
|
||||
const account: AdapterAccount = {
|
||||
...doc,
|
||||
id: extractId(doc.id),
|
||||
userId: doc.userId ? extractId(doc.userId) : "",
|
||||
}
|
||||
return account
|
||||
}
|
||||
|
||||
// Convert DB object to AdapterSession
|
||||
export const docToSession = (
|
||||
doc: SessionDoc<string | UserDoc>
|
||||
): AdapterSession => ({
|
||||
userId: extractId(
|
||||
typeof doc.userId === "string" ? doc.userId : doc.userId.id
|
||||
),
|
||||
expires: new Date(doc.expires ?? ""),
|
||||
sessionToken: doc.sessionToken ?? "",
|
||||
})
|
||||
|
||||
// Convert AdapterUser to DB object
|
||||
const userToDoc = (
|
||||
user: Omit<AdapterUser, "id"> | Partial<AdapterUser>
|
||||
): Omit<UserDoc, "id"> => {
|
||||
const doc = {
|
||||
...user,
|
||||
emailVerified: user.emailVerified?.toISOString(),
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
// Convert AdapterAccount to DB object
|
||||
const accountToDoc = (account: AdapterAccount): Omit<AccountDoc, "id"> => {
|
||||
const doc = {
|
||||
...account,
|
||||
userId: `user:${account.userId}`,
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
// Convert AdapterSession to DB object
|
||||
export const sessionToDoc = (
|
||||
session: AdapterSession
|
||||
): Omit<SessionDoc, "id"> => {
|
||||
const doc = {
|
||||
...session,
|
||||
expires: session.expires.toISOString(),
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
export function SurrealDBAdapter<T>(
|
||||
client: Promise<Surreal | ExperimentalSurrealHTTP<T>>
|
||||
// options = {}
|
||||
): Adapter {
|
||||
return {
|
||||
async createUser(user: Omit<AdapterUser, "id">) {
|
||||
const surreal = await client
|
||||
const doc = userToDoc(user)
|
||||
const userDoc = await surreal.create<UserDoc, Omit<UserDoc, "id">>("user", doc)
|
||||
if (userDoc.length) {
|
||||
return docToUser(userDoc[0])
|
||||
}
|
||||
throw new Error("User not created")
|
||||
},
|
||||
async getUser(id: string) {
|
||||
const surreal = await client
|
||||
try {
|
||||
const queryResult = await surreal.query<[UserDoc[]]>(
|
||||
"SELECT * FROM $user",
|
||||
{
|
||||
user: `user:${id}`,
|
||||
}
|
||||
)
|
||||
const doc = queryResult[0].result?.[0]
|
||||
if (doc) {
|
||||
return docToUser(doc)
|
||||
}
|
||||
} catch (e) { }
|
||||
return null
|
||||
},
|
||||
async getUserByEmail(email: string) {
|
||||
const surreal = await client
|
||||
try {
|
||||
const users = await surreal.query<[UserDoc[]]>(
|
||||
`SELECT * FROM user WHERE email = $email`,
|
||||
{ email }
|
||||
)
|
||||
const doc = users[0].result?.[0]
|
||||
if (doc) return docToUser(doc)
|
||||
} catch (e) { }
|
||||
return null
|
||||
},
|
||||
async getUserByAccount({
|
||||
providerAccountId,
|
||||
provider,
|
||||
}: Pick<AdapterAccount, "provider" | "providerAccountId">) {
|
||||
const surreal = await client
|
||||
try {
|
||||
const users = await surreal.query<[AccountDoc<UserDoc>[]]>(
|
||||
`SELECT userId
|
||||
FROM account
|
||||
WHERE providerAccountId = $providerAccountId
|
||||
AND provider = $provider
|
||||
FETCH userId`,
|
||||
{ providerAccountId, provider }
|
||||
)
|
||||
const user = users[0].result?.[0]
|
||||
?.userId
|
||||
if (user) return docToUser(user)
|
||||
} catch (e) { }
|
||||
return null
|
||||
},
|
||||
async updateUser(user: Partial<AdapterUser>) {
|
||||
const surreal = await client
|
||||
const doc = { ...user, emailVerified: user.emailVerified?.toISOString(), id: undefined }
|
||||
let updatedUser = await surreal.merge<UserDoc, Omit<UserDoc, "id">>(`user:${user.id}`, doc)
|
||||
if (updatedUser.length) {
|
||||
return docToUser(updatedUser[0])
|
||||
} else {
|
||||
throw new Error("User not updated")
|
||||
}
|
||||
},
|
||||
async deleteUser(userId: string) {
|
||||
const surreal = await client
|
||||
|
||||
// delete account
|
||||
try {
|
||||
const accounts = await surreal.query<[AccountDoc[]]>(
|
||||
`SELECT *
|
||||
FROM account
|
||||
WHERE userId = $userId
|
||||
LIMIT 1`,
|
||||
{ userId: `user:${userId}` }
|
||||
)
|
||||
const account = accounts[0].result?.[0]
|
||||
if (account) {
|
||||
const accountId = extractId(account.id)
|
||||
await surreal.delete(`account:${accountId}`)
|
||||
}
|
||||
} catch (e) { }
|
||||
|
||||
// delete session
|
||||
try {
|
||||
const sessions = await surreal.query<[SessionDoc[]]>(
|
||||
`SELECT *
|
||||
FROM session
|
||||
WHERE userId = $userId
|
||||
LIMIT 1`,
|
||||
{ userId: `user:${userId}` }
|
||||
)
|
||||
const session = sessions[0].result?.[0]
|
||||
if (session) {
|
||||
const sessionId = extractId(session.id)
|
||||
await surreal.delete(`session:${sessionId}`)
|
||||
}
|
||||
} catch (e) { }
|
||||
|
||||
// delete user
|
||||
await surreal.delete(`user:${userId}`)
|
||||
|
||||
// TODO: put all 3 deletes inside a Promise all
|
||||
},
|
||||
async linkAccount(account: AdapterAccount) {
|
||||
const surreal = await client
|
||||
const doc = await surreal.create("account", accountToDoc(account))
|
||||
return docToAccount(doc[0])
|
||||
},
|
||||
async unlinkAccount({
|
||||
providerAccountId,
|
||||
provider,
|
||||
}: Pick<AdapterAccount, "provider" | "providerAccountId">) {
|
||||
const surreal = await client
|
||||
try {
|
||||
const accounts = await surreal.query<[AccountDoc[]]>(
|
||||
`SELECT *
|
||||
FROM account
|
||||
WHERE providerAccountId = $providerAccountId
|
||||
AND provider = $provider
|
||||
LIMIT 1`,
|
||||
{ providerAccountId, provider }
|
||||
)
|
||||
const account = accounts[0].result?.[0]
|
||||
if (account) {
|
||||
const accountId = extractId(account.id)
|
||||
await surreal.delete(`account:${accountId}`)
|
||||
}
|
||||
} catch (e) { }
|
||||
},
|
||||
async createSession({
|
||||
sessionToken,
|
||||
userId,
|
||||
expires,
|
||||
}: {
|
||||
sessionToken: string
|
||||
userId: string
|
||||
expires: Date
|
||||
}) {
|
||||
const surreal = await client
|
||||
const doc = {
|
||||
sessionToken,
|
||||
userId: `user:${userId}`,
|
||||
expires,
|
||||
}
|
||||
const result = await surreal.create("session", doc)
|
||||
return result[0] ?? null
|
||||
},
|
||||
async getSessionAndUser(sessionToken: string) {
|
||||
const surreal = await client
|
||||
try {
|
||||
// Can't use limit 1 because it prevent userId to be fetched.
|
||||
// Works setting limit to 2
|
||||
const sessions = await surreal.query<[SessionDoc<UserDoc>[]]>(
|
||||
`SELECT *
|
||||
FROM session
|
||||
WHERE sessionToken = $sessionToken
|
||||
FETCH userId`,
|
||||
{ sessionToken }
|
||||
)
|
||||
const session = sessions[0].result?.[0]
|
||||
if (session) {
|
||||
const userDoc = session.userId
|
||||
if (!userDoc) return null
|
||||
return {
|
||||
user: docToUser(userDoc),
|
||||
session: docToSession({
|
||||
...session,
|
||||
userId: userDoc.id,
|
||||
}),
|
||||
}
|
||||
}
|
||||
} catch (e) { }
|
||||
return null
|
||||
},
|
||||
async updateSession(
|
||||
session: Partial<AdapterSession> & Pick<AdapterSession, "sessionToken">
|
||||
) {
|
||||
const surreal = await client
|
||||
try {
|
||||
const sessions = await surreal.query<[SessionDoc[]]>(
|
||||
`SELECT *
|
||||
FROM session
|
||||
WHERE sessionToken = $sessionToken
|
||||
LIMIT 1`,
|
||||
{ sessionToken: session.sessionToken }
|
||||
)
|
||||
const sessionDoc = sessions[0].result?.[0]
|
||||
if (sessionDoc && session.expires) {
|
||||
const sessionId = extractId(sessionDoc.id)
|
||||
let updatedSession = await surreal.merge<SessionDoc, Omit<SessionDoc, "id">>(
|
||||
`session:${sessionId}`,
|
||||
sessionToDoc({
|
||||
...sessionDoc,
|
||||
...session,
|
||||
userId: sessionDoc.userId,
|
||||
expires: session.expires,
|
||||
})
|
||||
)
|
||||
if (updatedSession.length) {
|
||||
return docToSession(updatedSession[0])
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
} catch (e) { }
|
||||
return null
|
||||
},
|
||||
async deleteSession(sessionToken: string) {
|
||||
const surreal = await client
|
||||
try {
|
||||
const sessions = await surreal.query<[SessionDoc[]]>(
|
||||
`SELECT *
|
||||
FROM session
|
||||
WHERE sessionToken = $sessionToken
|
||||
LIMIT 1`,
|
||||
{ sessionToken }
|
||||
)
|
||||
const session = sessions[0].result?.[0]
|
||||
if (session) {
|
||||
const sessionId = extractId(session.id)
|
||||
await surreal.delete(`session:${sessionId}`)
|
||||
return
|
||||
}
|
||||
} catch (e) { }
|
||||
},
|
||||
async createVerificationToken({
|
||||
identifier,
|
||||
expires,
|
||||
token,
|
||||
}: VerificationToken) {
|
||||
const surreal = await client
|
||||
const doc = {
|
||||
identifier,
|
||||
expires,
|
||||
token,
|
||||
}
|
||||
const result = await surreal.create("verification_token", doc)
|
||||
return result[0] ?? null
|
||||
},
|
||||
async useVerificationToken({
|
||||
identifier,
|
||||
token,
|
||||
}: {
|
||||
identifier: string
|
||||
token: string
|
||||
}) {
|
||||
const surreal = await client
|
||||
try {
|
||||
const tokens = await surreal.query<[{ identifier: string, expires: string, token: string, id: string }[]]>(
|
||||
`SELECT *
|
||||
FROM verification_token
|
||||
WHERE identifier = $identifier
|
||||
AND token = $verificationToken
|
||||
LIMIT 1`,
|
||||
{ identifier, verificationToken: token }
|
||||
)
|
||||
if (tokens.length && tokens[0].result) {
|
||||
const vt = tokens[0].result[0]
|
||||
if (vt) {
|
||||
await surreal.delete(vt.id)
|
||||
return {
|
||||
identifier: vt.identifier,
|
||||
expires: new Date(vt.expires),
|
||||
token: vt.token,
|
||||
}
|
||||
}
|
||||
} else { return null }
|
||||
} catch (e) { }
|
||||
return null
|
||||
},
|
||||
}
|
||||
}
|
||||
77
packages/adapter-surrealdb/tests/common.ts
Normal file
77
packages/adapter-surrealdb/tests/common.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import Surreal, { ExperimentalSurrealHTTP } from "surrealdb.js"
|
||||
|
||||
import {
|
||||
SurrealDBAdapter,
|
||||
docToUser,
|
||||
docToAccount,
|
||||
docToSession,
|
||||
} from "../src/index"
|
||||
import type { UserDoc, AccountDoc, SessionDoc } from "../src/index"
|
||||
|
||||
export const config = (
|
||||
clientPromise: Promise<Surreal | ExperimentalSurrealHTTP<typeof fetch>>
|
||||
) => ({
|
||||
adapter: SurrealDBAdapter(clientPromise),
|
||||
db: {
|
||||
async disconnect() {
|
||||
const surreal = await clientPromise
|
||||
if (surreal.close) surreal.close()
|
||||
},
|
||||
async user(id: string) {
|
||||
const surreal = await clientPromise
|
||||
try {
|
||||
const users = await surreal.query<[UserDoc[]]>("SELECT * FROM $user", {
|
||||
user: `user:${id}`,
|
||||
})
|
||||
const user = users[0]
|
||||
if (user.result?.[0] !== undefined) return docToUser(user.result[0])
|
||||
} catch (e) {}
|
||||
return null
|
||||
},
|
||||
async account({ provider, providerAccountId }) {
|
||||
const surreal = await clientPromise
|
||||
const accounts = await surreal.query<[AccountDoc[]]>(
|
||||
`SELECT * FROM account WHERE provider = $provider AND providerAccountId = $providerAccountId`,
|
||||
{ provider, providerAccountId }
|
||||
)
|
||||
const account = accounts[0]
|
||||
if (account.result?.[0] !== undefined)
|
||||
return docToAccount(account.result[0])
|
||||
return null
|
||||
},
|
||||
async session(sessionToken: string) {
|
||||
const surreal = await clientPromise
|
||||
const sessions = await surreal.query<[SessionDoc[]]>(
|
||||
`SELECT * FROM session WHERE sessionToken = $sessionToken`,
|
||||
{ sessionToken }
|
||||
)
|
||||
const session = sessions[0].result?.[0]
|
||||
if (session !== undefined) {
|
||||
return docToSession(session)
|
||||
}
|
||||
return null
|
||||
},
|
||||
async verificationToken({ identifier, token }) {
|
||||
const surreal = await clientPromise
|
||||
const tokens = await surreal.query<
|
||||
[{ identifier: string; expires: string; token: string; id: string }[]]
|
||||
>(
|
||||
`SELECT *
|
||||
FROM verification_token
|
||||
WHERE identifier = $identifier
|
||||
AND token = $verificationToken
|
||||
LIMIT 1`,
|
||||
{ identifier, verificationToken: token }
|
||||
)
|
||||
const verificationToken = tokens[0].result?.[0]
|
||||
if (verificationToken) {
|
||||
return {
|
||||
identifier: verificationToken.identifier,
|
||||
expires: new Date(verificationToken.expires),
|
||||
token: verificationToken.token,
|
||||
}
|
||||
}
|
||||
return null
|
||||
},
|
||||
},
|
||||
})
|
||||
23
packages/adapter-surrealdb/tests/index.test.ts
Normal file
23
packages/adapter-surrealdb/tests/index.test.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import Surreal from "surrealdb.js"
|
||||
import { runBasicTests } from "@auth/adapter-test"
|
||||
|
||||
import { config } from "./common"
|
||||
|
||||
const clientPromise = new Promise<Surreal>(async (resolve, reject) => {
|
||||
const db = new Surreal();
|
||||
try {
|
||||
await db.connect('http://0.0.0.0:8000/rpc', {
|
||||
ns: "test",
|
||||
db: "test",
|
||||
auth: {
|
||||
user: "test",
|
||||
pass: "test",
|
||||
}
|
||||
})
|
||||
resolve(db)
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
|
||||
runBasicTests(config(clientPromise))
|
||||
27
packages/adapter-surrealdb/tests/rest.test.ts
Normal file
27
packages/adapter-surrealdb/tests/rest.test.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
test("TODO: test rest", () => {
|
||||
expect(true).toBe(true)
|
||||
})
|
||||
// import { ExperimentalSurrealHTTP } from "surrealdb.js"
|
||||
// import { runBasicTests } from "@auth/adapter-test"
|
||||
// import fetch from "node-fetch"
|
||||
|
||||
// import { config } from "./common"
|
||||
|
||||
// const clientPromise = new Promise<ExperimentalSurrealHTTP<typeof fetch>>(async (resolve, reject) => {
|
||||
// try {
|
||||
// const db = new ExperimentalSurrealHTTP("http://0.0.0.0:8000", {
|
||||
// fetch,
|
||||
// auth: {
|
||||
// user: "test",
|
||||
// pass: "test",
|
||||
// },
|
||||
// ns: "test",
|
||||
// db: "test",
|
||||
// })
|
||||
// resolve(db)
|
||||
// } catch (e) {
|
||||
// reject(e)
|
||||
// }
|
||||
// })
|
||||
|
||||
// runBasicTests(config(clientPromise))
|
||||
34
packages/adapter-surrealdb/tests/test.sh
Executable file
34
packages/adapter-surrealdb/tests/test.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CONTAINER_NAME=next-auth-surrealdb-test
|
||||
|
||||
JEST_WATCH=false
|
||||
|
||||
# Is the watch flag passed to the script?
|
||||
while getopts w flag
|
||||
do
|
||||
case "${flag}" in
|
||||
w) JEST_WATCH=true;;
|
||||
*) continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Start db
|
||||
docker run -d --rm -p 8000:8000 --name ${CONTAINER_NAME} surrealdb/surrealdb:latest start --log debug --user test --pass test memory
|
||||
|
||||
echo "Waiting 3 sec for db to start..."
|
||||
sleep 3
|
||||
|
||||
if $JEST_WATCH; then
|
||||
# Run jest in watch mode
|
||||
npx jest tests --watch
|
||||
# Only stop the container after jest has been quit
|
||||
docker stop "${CONTAINER_NAME}"
|
||||
else
|
||||
# Always stop container, but exit with 1 when tests are failing
|
||||
if npx jest;then
|
||||
docker stop ${CONTAINER_NAME}
|
||||
else
|
||||
docker stop ${CONTAINER_NAME} && exit 1
|
||||
fi
|
||||
fi
|
||||
25
packages/adapter-surrealdb/tsconfig.json
Normal file
25
packages/adapter-surrealdb/tsconfig.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"extends": "@auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"*.js",
|
||||
"*.d.ts",
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth/typeorm-adapter",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"description": "TypeORM adapter for Auth.js.",
|
||||
"homepage": "https://authjs.dev/reference/adapter/typeorm",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
@@ -85,4 +85,4 @@
|
||||
"jest": {
|
||||
"preset": "@auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,15 +42,16 @@ export async function getManager(options: {
|
||||
dataSource: string | DataSourceOptions
|
||||
entities: Entities
|
||||
}): Promise<EntityManager> {
|
||||
const { dataSource, entities } = options
|
||||
|
||||
const config = {
|
||||
...parseDataSourceConfig(dataSource),
|
||||
entities: Object.values(entities),
|
||||
if (!_dataSource) {
|
||||
const { dataSource, entities } = options
|
||||
const config = {
|
||||
...parseDataSourceConfig(dataSource),
|
||||
entities: Object.values(entities),
|
||||
}
|
||||
_dataSource = new DataSource(config)
|
||||
}
|
||||
|
||||
if (!_dataSource) _dataSource = new DataSource(config)
|
||||
|
||||
const manager = _dataSource?.manager
|
||||
|
||||
if (!manager.connection.isInitialized) {
|
||||
@@ -58,7 +59,7 @@ export async function getManager(options: {
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
await updateConnectionEntities(_dataSource, config.entities)
|
||||
await updateConnectionEntities(_dataSource, Object.values(options.entities))
|
||||
}
|
||||
return manager
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth/core",
|
||||
"version": "0.15.0",
|
||||
"version": "0.15.2",
|
||||
"description": "Authentication for the Web.",
|
||||
"keywords": [
|
||||
"authentication",
|
||||
|
||||
@@ -202,10 +202,10 @@ async function getUserAndAccount(
|
||||
return {
|
||||
user,
|
||||
account: {
|
||||
...tokens,
|
||||
provider: provider.id,
|
||||
type: provider.type,
|
||||
providerAccountId: user.id.toString(),
|
||||
...tokens,
|
||||
},
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -118,7 +118,7 @@ export default function AzureADB2C(
|
||||
return {
|
||||
id: profile.sub,
|
||||
name: profile.name,
|
||||
email: profile.emails[0],
|
||||
email: profile?.emails?.[0],
|
||||
image: null,
|
||||
}
|
||||
},
|
||||
|
||||
@@ -31,7 +31,7 @@ export interface DribbbleProfile extends Record<string, any> {
|
||||
* #### Configuration
|
||||
*```js
|
||||
* import Auth from "@auth/core"
|
||||
* import Google from "@auth/core/providers/dribbble"
|
||||
* import Dribbble from "@auth/core/providers/dribbble"
|
||||
*
|
||||
* const request = new Request(origin)
|
||||
* const response = await Auth(request, {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"Balázs Orbán <info@balazsorban.com>",
|
||||
"Nico Domino <yo@ndo.dev>",
|
||||
"Lluis Agusti <hi@llu.lu>",
|
||||
"Thang Huu Vu <thvu@hey.com>"
|
||||
"Thang Huu Vu <hi@thvu.dev>"
|
||||
],
|
||||
"main": "index.js",
|
||||
"module": "index.js",
|
||||
|
||||
2254
pnpm-lock.yaml
generated
2254
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
51
turbo.json
51
turbo.json
@@ -2,22 +2,12 @@
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"outputs": [
|
||||
"dist/**/*",
|
||||
"lib/**/*",
|
||||
"*.js",
|
||||
"*.d.ts",
|
||||
"*.d.ts.map"
|
||||
],
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": ["dist/**/*", "lib/**/*", "*.js", "*.d.ts", "*.d.ts.map"],
|
||||
"outputMode": "new-only"
|
||||
},
|
||||
"next-auth#build": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [
|
||||
"client/**",
|
||||
"core/**",
|
||||
@@ -32,9 +22,7 @@
|
||||
"outputMode": "new-only"
|
||||
},
|
||||
"@auth/core#build": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [
|
||||
"lib/**",
|
||||
"providers/**",
|
||||
@@ -47,14 +35,8 @@
|
||||
"outputMode": "new-only"
|
||||
},
|
||||
"@auth/sveltekit#build": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"outputs": [
|
||||
".svelte-kit/**",
|
||||
"client.*",
|
||||
"index.*"
|
||||
],
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [".svelte-kit/**", "client.*", "index.*"],
|
||||
"outputMode": "new-only"
|
||||
},
|
||||
"clean": {
|
||||
@@ -67,15 +49,10 @@
|
||||
"outputMode": "new-only"
|
||||
},
|
||||
"e2e": {
|
||||
"outputs": [
|
||||
"playwright-report/**"
|
||||
]
|
||||
"outputs": ["playwright-report/**"]
|
||||
},
|
||||
"@auth/upstash-redis-adapter#test": {
|
||||
"env": [
|
||||
"UPSTASH_REDIS_KEY",
|
||||
"UPSTASH_REDIS_URL"
|
||||
]
|
||||
"env": ["UPSTASH_REDIS_KEY", "UPSTASH_REDIS_URL"]
|
||||
},
|
||||
"docs#dev": {
|
||||
"dependsOn": [
|
||||
@@ -83,6 +60,9 @@
|
||||
"@auth/prisma-adapter#build",
|
||||
"@auth/solid-start#build",
|
||||
"@auth/sveltekit#build",
|
||||
"@auth/azure-tables-adapter#build",
|
||||
"@auth/d1-adapter#build",
|
||||
"@auth/edgedb-adapter#build",
|
||||
"@auth/dgraph-adapter#build",
|
||||
"@auth/drizzle-adapter#build",
|
||||
"@auth/dynamodb-adapter#build",
|
||||
@@ -92,9 +72,11 @@
|
||||
"@auth/mikro-orm-adapter#build",
|
||||
"@auth/mongodb-adapter#build",
|
||||
"@auth/neo4j-adapter#build",
|
||||
"@auth/pg-adapter#build",
|
||||
"@auth/pouchdb-adapter#build",
|
||||
"@auth/sequelize-adapter#build",
|
||||
"@auth/supabase-adapter#build",
|
||||
"@auth/surrealdb-adapter#build",
|
||||
"@auth/typeorm-adapter#build",
|
||||
"@auth/upstash-redis-adapter#build",
|
||||
"@auth/xata-adapter#build",
|
||||
@@ -108,6 +90,9 @@
|
||||
"@auth/prisma-adapter#build",
|
||||
"@auth/solid-start#build",
|
||||
"@auth/sveltekit#build",
|
||||
"@auth/azure-tables-adapter#build",
|
||||
"@auth/d1-adapter#build",
|
||||
"@auth/edgedb-adapter#build",
|
||||
"@auth/dgraph-adapter#build",
|
||||
"@auth/drizzle-adapter#build",
|
||||
"@auth/dynamodb-adapter#build",
|
||||
@@ -117,9 +102,11 @@
|
||||
"@auth/mikro-orm-adapter#build",
|
||||
"@auth/mongodb-adapter#build",
|
||||
"@auth/neo4j-adapter#build",
|
||||
"@auth/pg-adapter#build",
|
||||
"@auth/pouchdb-adapter#build",
|
||||
"@auth/sequelize-adapter#build",
|
||||
"@auth/supabase-adapter#build",
|
||||
"@auth/surrealdb-adapter#build",
|
||||
"@auth/typeorm-adapter#build",
|
||||
"@auth/upstash-redis-adapter#build",
|
||||
"@auth/xata-adapter#build",
|
||||
@@ -134,4 +121,4 @@
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user