wabe 0.6.8 → 0.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -32
- package/dev/index.ts +215 -0
- package/dist/authentication/OTP.d.ts +3 -0
- package/dist/authentication/Session.d.ts +5 -2
- package/dist/authentication/interface.d.ts +25 -3
- package/dist/authentication/utils.d.ts +0 -1
- package/dist/database/DatabaseController.d.ts +10 -10
- package/dist/database/interface.d.ts +5 -13
- package/dist/email/interface.d.ts +1 -1
- package/dist/graphql/resolvers.d.ts +4 -2
- package/dist/hooks/authentication.d.ts +2 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +9130 -9041
- package/dist/server/index.d.ts +4 -2
- package/dist/server/interface.d.ts +1 -0
- package/dist/utils/crypto.d.ts +18 -0
- package/dist/utils/export.d.ts +1 -0
- package/dist/utils/helper.d.ts +4 -1
- package/dist/utils/index.d.ts +16 -3
- package/generated/schema.graphql +18 -15
- package/generated/wabe.ts +6 -5
- package/package.json +52 -53
- package/src/authentication/OTP.test.ts +69 -0
- package/src/authentication/OTP.ts +66 -0
- package/src/authentication/Session.test.ts +665 -0
- package/src/authentication/Session.ts +529 -0
- package/src/authentication/defaultAuthentication.ts +214 -0
- package/src/authentication/index.ts +3 -0
- package/src/authentication/interface.ts +157 -0
- package/src/authentication/oauth/GitHub.test.ts +105 -0
- package/src/authentication/oauth/GitHub.ts +133 -0
- package/src/authentication/oauth/Google.test.ts +105 -0
- package/src/authentication/oauth/Google.ts +110 -0
- package/src/authentication/oauth/Oauth2Client.test.ts +225 -0
- package/src/authentication/oauth/Oauth2Client.ts +140 -0
- package/src/authentication/oauth/index.ts +2 -0
- package/src/authentication/oauth/utils.test.ts +35 -0
- package/src/authentication/oauth/utils.ts +28 -0
- package/src/authentication/providers/EmailOTP.test.ts +138 -0
- package/src/authentication/providers/EmailOTP.ts +93 -0
- package/src/authentication/providers/EmailPassword.test.ts +187 -0
- package/src/authentication/providers/EmailPassword.ts +130 -0
- package/src/authentication/providers/EmailPasswordSRP.test.ts +206 -0
- package/src/authentication/providers/EmailPasswordSRP.ts +184 -0
- package/src/authentication/providers/GitHub.ts +30 -0
- package/src/authentication/providers/Google.ts +30 -0
- package/src/authentication/providers/OAuth.test.ts +185 -0
- package/src/authentication/providers/OAuth.ts +112 -0
- package/src/authentication/providers/PhonePassword.test.ts +187 -0
- package/src/authentication/providers/PhonePassword.ts +129 -0
- package/src/authentication/providers/QRCodeOTP.test.ts +79 -0
- package/src/authentication/providers/QRCodeOTP.ts +65 -0
- package/src/authentication/providers/index.ts +6 -0
- package/src/authentication/resolvers/refreshResolver.test.ts +37 -0
- package/src/authentication/resolvers/refreshResolver.ts +20 -0
- package/src/authentication/resolvers/signInWithResolver.inte.test.ts +59 -0
- package/src/authentication/resolvers/signInWithResolver.test.ts +307 -0
- package/src/authentication/resolvers/signInWithResolver.ts +102 -0
- package/src/authentication/resolvers/signOutResolver.test.ts +41 -0
- package/src/authentication/resolvers/signOutResolver.ts +22 -0
- package/src/authentication/resolvers/signUpWithResolver.test.ts +186 -0
- package/src/authentication/resolvers/signUpWithResolver.ts +69 -0
- package/src/authentication/resolvers/verifyChallenge.test.ts +136 -0
- package/src/authentication/resolvers/verifyChallenge.ts +69 -0
- package/src/authentication/roles.test.ts +59 -0
- package/src/authentication/roles.ts +40 -0
- package/src/authentication/utils.test.ts +99 -0
- package/src/authentication/utils.ts +43 -0
- package/src/cache/InMemoryCache.test.ts +62 -0
- package/src/cache/InMemoryCache.ts +45 -0
- package/src/cron/index.test.ts +17 -0
- package/src/cron/index.ts +46 -0
- package/src/database/DatabaseController.test.ts +625 -0
- package/src/database/DatabaseController.ts +983 -0
- package/src/database/index.test.ts +1230 -0
- package/src/database/index.ts +9 -0
- package/src/database/interface.ts +312 -0
- package/src/email/DevAdapter.ts +8 -0
- package/src/email/EmailController.test.ts +29 -0
- package/src/email/EmailController.ts +13 -0
- package/src/email/index.ts +2 -0
- package/src/email/interface.ts +36 -0
- package/src/email/templates/sendOtpCode.ts +120 -0
- package/src/file/FileController.ts +28 -0
- package/src/file/FileDevAdapter.ts +54 -0
- package/src/file/hookDeleteFile.ts +27 -0
- package/src/file/hookReadFile.ts +70 -0
- package/src/file/hookUploadFile.ts +53 -0
- package/src/file/index.test.ts +979 -0
- package/src/file/index.ts +2 -0
- package/src/file/interface.ts +42 -0
- package/src/graphql/GraphQLSchema.test.ts +4399 -0
- package/src/graphql/GraphQLSchema.ts +928 -0
- package/src/graphql/index.ts +2 -0
- package/src/graphql/parseGraphqlSchema.ts +94 -0
- package/src/graphql/parser.test.ts +217 -0
- package/src/graphql/parser.ts +566 -0
- package/src/graphql/pointerAndRelationFunction.ts +200 -0
- package/src/graphql/resolvers.ts +467 -0
- package/src/graphql/tests/aggregation.test.ts +1123 -0
- package/src/graphql/tests/e2e.test.ts +596 -0
- package/src/graphql/tests/scalars.test.ts +250 -0
- package/src/graphql/types.ts +219 -0
- package/src/hooks/HookObject.test.ts +122 -0
- package/src/hooks/HookObject.ts +168 -0
- package/src/hooks/authentication.ts +76 -0
- package/src/hooks/createUser.test.ts +77 -0
- package/src/hooks/createUser.ts +10 -0
- package/src/hooks/defaultFields.test.ts +187 -0
- package/src/hooks/defaultFields.ts +40 -0
- package/src/hooks/deleteSession.test.ts +181 -0
- package/src/hooks/deleteSession.ts +20 -0
- package/src/hooks/hashFieldHook.test.ts +163 -0
- package/src/hooks/hashFieldHook.ts +97 -0
- package/src/hooks/index.test.ts +207 -0
- package/src/hooks/index.ts +430 -0
- package/src/hooks/permissions.test.ts +424 -0
- package/src/hooks/permissions.ts +113 -0
- package/src/hooks/protected.test.ts +551 -0
- package/src/hooks/protected.ts +72 -0
- package/src/hooks/searchableFields.test.ts +166 -0
- package/src/hooks/searchableFields.ts +98 -0
- package/src/hooks/session.test.ts +138 -0
- package/src/hooks/session.ts +78 -0
- package/src/hooks/setEmail.test.ts +216 -0
- package/src/hooks/setEmail.ts +35 -0
- package/src/hooks/setupAcl.test.ts +589 -0
- package/src/hooks/setupAcl.ts +29 -0
- package/src/index.ts +9 -0
- package/src/schema/Schema.test.ts +484 -0
- package/src/schema/Schema.ts +795 -0
- package/src/schema/defaultResolvers.ts +94 -0
- package/src/schema/index.ts +1 -0
- package/src/schema/resolvers/meResolver.test.ts +62 -0
- package/src/schema/resolvers/meResolver.ts +14 -0
- package/src/schema/resolvers/newFile.ts +0 -0
- package/src/schema/resolvers/resetPassword.test.ts +345 -0
- package/src/schema/resolvers/resetPassword.ts +64 -0
- package/src/schema/resolvers/sendEmail.test.ts +118 -0
- package/src/schema/resolvers/sendEmail.ts +21 -0
- package/src/schema/resolvers/sendOtpCode.test.ts +153 -0
- package/src/schema/resolvers/sendOtpCode.ts +52 -0
- package/src/security.test.ts +3461 -0
- package/src/server/defaultSessionHandler.test.ts +66 -0
- package/src/server/defaultSessionHandler.ts +115 -0
- package/src/server/generateCodegen.ts +476 -0
- package/src/server/index.test.ts +552 -0
- package/src/server/index.ts +354 -0
- package/src/server/interface.ts +11 -0
- package/src/server/routes/authHandler.ts +187 -0
- package/src/server/routes/index.ts +40 -0
- package/src/utils/crypto.test.ts +41 -0
- package/src/utils/crypto.ts +121 -0
- package/src/utils/export.ts +13 -0
- package/src/utils/helper.ts +195 -0
- package/src/utils/index.test.ts +11 -0
- package/src/utils/index.ts +201 -0
- package/src/utils/preload.ts +8 -0
- package/src/utils/testHelper.ts +117 -0
- package/tsconfig.json +32 -0
- package/bunfig.toml +0 -4
- package/dist/ai/index.d.ts +0 -1
- package/dist/ai/interface.d.ts +0 -9
- /package/dist/server/{defaultHandlers.d.ts → defaultSessionHandler.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,32 +1,63 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<
|
|
2
|
+
<h1 align="center">Wabe</h1>
|
|
3
|
+
<p align="center">🚀 A fully open-source <strong>Firebase alternative</strong> built in TypeScript</p>
|
|
3
4
|
</p>
|
|
4
5
|
|
|
5
|
-
<
|
|
6
|
-
<a href="https://wabe.
|
|
7
|
-
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="https://github.com/palixir/wabe"><img src="https://img.shields.io/github/stars/palixir/wabe?style=flat-square" /></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/wabe"><img src="https://img.shields.io/npm/v/wabe?style=flat-square" /></a>
|
|
9
|
+
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-green?style=flat-square" /></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
Wabe is a modern, batteries-included backend-as-a-service designed for developers who want the flexibility of self-hosting with the ease of Firebase.
|
|
15
|
+
|
|
16
|
+
You define your models → Wabe instantly generates:
|
|
17
|
+
- a **secure GraphQL API**
|
|
18
|
+
- **auth**, **permissions**, **hooks**, **emails**, **files**, and more
|
|
19
|
+
- a fully extensible backend written in clean TypeScript
|
|
20
|
+
|
|
21
|
+
No vendor lock-in. No hidden limits.
|
|
22
|
+
Host it anywhere.
|
|
23
|
+
|
|
24
|
+
📚 **Documentation:** [https://palixir.github.io/wabe](https://palixir.github.io/wabe)
|
|
25
|
+
|
|
26
|
+
---
|
|
8
27
|
|
|
9
|
-
|
|
28
|
+
# ✨ Features
|
|
10
29
|
|
|
11
|
-
|
|
30
|
+
| Feature | Description |
|
|
31
|
+
|--------------------------|-----------------------------------------------------------------------------|
|
|
32
|
+
| 🔐 Authentication | Email/password, OTP, OAuth (Google, GitHub), password reset, email verification |
|
|
33
|
+
| 🔑 Permissions | Fine-grained access control at collection, object, and field levels with secure defaults |
|
|
34
|
+
| ⚡ Auto-generated GraphQL | Fully typed CRUD GraphQL API generated from your schema, ready for production |
|
|
35
|
+
| 🔄 Hooks | Custom logic before/after create, update, delete, and read operations |
|
|
36
|
+
| 📨 Email providers | Resend (official adapter) or custom adapters |
|
|
37
|
+
| 🗄️ Database adapters | MongoDB, PostgreSQL (official), or your own adapter |
|
|
38
|
+
| 📦 Modular architecture | Replaceable and extensible modules: auth, storage, email, database, permissions |
|
|
39
|
+
| 🌍 Self-host anywhere | Docker, Node, Bun, Fly.io, Render, Railway, Hetzner, Raspberry Pi |
|
|
12
40
|
|
|
13
|
-
## Install
|
|
14
41
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
# 🚀 Quickstart
|
|
45
|
+
|
|
46
|
+
### 1. Install
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install wabe
|
|
50
|
+
# or
|
|
51
|
+
bun add wabe
|
|
19
52
|
```
|
|
20
53
|
|
|
21
|
-
|
|
54
|
+
### 2. Create your schema and start your server
|
|
22
55
|
|
|
23
|
-
```ts
|
|
56
|
+
``` ts
|
|
24
57
|
import { Wabe } from "wabe";
|
|
25
58
|
import { MongoAdapter } from "wabe-mongodb";
|
|
26
59
|
|
|
27
60
|
const run = async () => {
|
|
28
|
-
// Ensure your database is running before run the file
|
|
29
|
-
|
|
30
61
|
const wabe = new Wabe({
|
|
31
62
|
isProduction: process.env.NODE_ENV === "production",
|
|
32
63
|
// Root key example (must be long minimal 64 characters, you can generate it online)
|
|
@@ -35,10 +66,30 @@ const run = async () => {
|
|
|
35
66
|
database: {
|
|
36
67
|
adapter: new MongoAdapter({
|
|
37
68
|
databaseName: "WabeApp",
|
|
38
|
-
|
|
69
|
+
databaseUrl: "mongodb://127.0.0.1:27045",
|
|
39
70
|
}),
|
|
40
71
|
},
|
|
41
|
-
|
|
72
|
+
schema: {
|
|
73
|
+
classes: [
|
|
74
|
+
{
|
|
75
|
+
name: 'User',
|
|
76
|
+
description: 'User class',
|
|
77
|
+
fields: {
|
|
78
|
+
name: {
|
|
79
|
+
type: 'String',
|
|
80
|
+
},
|
|
81
|
+
age: {
|
|
82
|
+
type: 'Int',
|
|
83
|
+
},
|
|
84
|
+
email: {
|
|
85
|
+
type: 'Email',
|
|
86
|
+
required: true,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
port: 3000,
|
|
42
93
|
});
|
|
43
94
|
|
|
44
95
|
await wabe.start();
|
|
@@ -47,27 +98,84 @@ const run = async () => {
|
|
|
47
98
|
await run();
|
|
48
99
|
```
|
|
49
100
|
|
|
50
|
-
|
|
101
|
+
### 3. Query your API
|
|
102
|
+
|
|
103
|
+
``` graphql
|
|
104
|
+
mutation createUser {
|
|
105
|
+
createUser(input: { fields: {name: "Wabe", email: "mybackend@wabe.com", age: 10} }) {
|
|
106
|
+
user {
|
|
107
|
+
id
|
|
108
|
+
name
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# 🧩 Official Templates
|
|
116
|
+
|
|
117
|
+
Wabe comes with a set of official templates to help you bootstrap projects instantly:
|
|
118
|
+
|
|
119
|
+
| Template | Stack | Description | Status |
|
|
120
|
+
|------------------------|----------------|---------------------------------|----------------|
|
|
121
|
+
| **wabe-starter** | Wabe + Node | Minimal starter backend | 🟡 Coming soon |
|
|
122
|
+
| **wabe-next-template** | Next.js + Wabe | Authentication + CRUD boilerplate | 🟡 Coming soon |
|
|
123
|
+
| **wabe-saas-kit** | Wabe + Wobe | SaaS starter kit with Stripe | 🟡 Coming soon |
|
|
124
|
+
|
|
125
|
+
More templates are added regularly based on community needs.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
# 🌱 Ecosystem
|
|
130
|
+
|
|
131
|
+
### **Wobe — Full-stack web framework**
|
|
132
|
+
|
|
133
|
+
Wobe is a lightweight, TypeScript-first full-stack framework designed to pair naturally with Wabe.
|
|
134
|
+
For a seamless frontend + backend developer experience:
|
|
135
|
+
|
|
136
|
+
👉 https://github.com/palixir/wobe
|
|
137
|
+
|
|
138
|
+
### **GraphQL Server (coming soon)**
|
|
139
|
+
|
|
140
|
+
A modern, type-safe GraphQL server designed as a companion to Wabe.
|
|
141
|
+
Optimized for DX, performance, and full extensibility.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
# 🗺️ Roadmap
|
|
146
|
+
|
|
147
|
+
- [x] PostgreSQL adapter
|
|
148
|
+
- [ ] Admin dashboard UI
|
|
149
|
+
- [x] File storage adapters (S3, Cloudflare R2, etc.)
|
|
150
|
+
- [ ] CLI (`wabe init`, `wabe generate`)
|
|
151
|
+
- [ ] SaaS starter kit
|
|
152
|
+
- [ ] Improved documentation
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
# 🤝 Contributing
|
|
157
|
+
|
|
158
|
+
Contributions are welcome!
|
|
159
|
+
Before opening a PR, check the `CONTRIBUTING.md` and join the community.
|
|
51
160
|
|
|
52
|
-
|
|
53
|
-
- **Permissions**: Granular permissions control to secure your resources.
|
|
54
|
-
- **Database**: A powerful, scalable database to store and manage you data.
|
|
55
|
-
- **GraphQL API**: A flexible and powerful GraphQL API (following GraphQL Relay standard) to interact with your data.
|
|
56
|
-
- **Hooks**: Powerful hooks system to execute custom actions before or after database requests.
|
|
57
|
-
- **Email**: Send emails with your favorite provider with very simple integration.
|
|
161
|
+
---
|
|
58
162
|
|
|
59
|
-
|
|
163
|
+
# ❤️ Sponsors
|
|
60
164
|
|
|
61
|
-
|
|
165
|
+
Wabe is 100% open-source and maintained in my free time.
|
|
166
|
+
If you want to support development:
|
|
62
167
|
|
|
63
|
-
|
|
168
|
+
👉 **GitHub Sponsors:** https://github.com/sponsors/coratgerl
|
|
64
169
|
|
|
65
|
-
|
|
170
|
+
**Sponsors receive:**
|
|
171
|
+
- Access to a complete, fully tested boilerplate with an admin dashboard to manage users (Vite, Tailwind, Playwright, Wabe, Bun, GraphQL, etc.)
|
|
172
|
+
- Your name featured in the `README.md`
|
|
66
173
|
|
|
67
|
-
|
|
174
|
+
Your support helps keep Wabe sustainable and actively maintained, and allows me to continue creating new projects in my free time to help developers have solid backends with minimal effort.
|
|
68
175
|
|
|
69
|
-
|
|
176
|
+
---
|
|
70
177
|
|
|
71
|
-
|
|
178
|
+
# ⭐ Show your support
|
|
72
179
|
|
|
73
|
-
|
|
180
|
+
If you like the project, please consider starring the repository:
|
|
181
|
+
⭐ → It helps more than you think.
|
package/dev/index.ts
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RoleEnum,
|
|
3
|
+
type WabeSchemaWhereTypes,
|
|
4
|
+
type WabeSchemaEnums,
|
|
5
|
+
type WabeSchemaScalars,
|
|
6
|
+
type WabeSchemaTypes,
|
|
7
|
+
} from '../generated/wabe'
|
|
8
|
+
import { getDatabaseAdapter } from '../src/utils/testHelper'
|
|
9
|
+
import { Wabe } from '../src/server'
|
|
10
|
+
import { FileDevAdapter } from '../src'
|
|
11
|
+
import { runDatabase } from 'wabe-mongodb-launcher'
|
|
12
|
+
|
|
13
|
+
const run = async () => {
|
|
14
|
+
await runDatabase()
|
|
15
|
+
|
|
16
|
+
const wabe = new Wabe<{
|
|
17
|
+
types: WabeSchemaTypes
|
|
18
|
+
scalars: WabeSchemaScalars
|
|
19
|
+
enums: WabeSchemaEnums
|
|
20
|
+
where: WabeSchemaWhereTypes
|
|
21
|
+
}>({
|
|
22
|
+
isProduction: false,
|
|
23
|
+
codegen: {
|
|
24
|
+
enabled: true,
|
|
25
|
+
path: `${import.meta.dirname}/../generated/`,
|
|
26
|
+
},
|
|
27
|
+
rootKey: 'dev',
|
|
28
|
+
authentication: {
|
|
29
|
+
session: {
|
|
30
|
+
cookieSession: true,
|
|
31
|
+
jwtSecret: 'dev',
|
|
32
|
+
jwtTokenFields: {
|
|
33
|
+
id: true,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
roles: ['Admin', 'Client'],
|
|
37
|
+
successRedirectPath: 'https://palixir.github.io/wabe/',
|
|
38
|
+
failureRedirectPath: 'https://palixir.github.io/wabe/',
|
|
39
|
+
},
|
|
40
|
+
database: {
|
|
41
|
+
// @ts-expect-error
|
|
42
|
+
adapter: await getDatabaseAdapter('Wabe'),
|
|
43
|
+
},
|
|
44
|
+
file: {
|
|
45
|
+
adapter: new FileDevAdapter(),
|
|
46
|
+
},
|
|
47
|
+
port: 3001,
|
|
48
|
+
schema: {
|
|
49
|
+
classes: [
|
|
50
|
+
{
|
|
51
|
+
name: 'User',
|
|
52
|
+
description: 'User class',
|
|
53
|
+
fields: {
|
|
54
|
+
name: {
|
|
55
|
+
type: 'String',
|
|
56
|
+
},
|
|
57
|
+
age: {
|
|
58
|
+
type: 'Int',
|
|
59
|
+
},
|
|
60
|
+
email: {
|
|
61
|
+
type: 'Email',
|
|
62
|
+
required: true,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'Post',
|
|
68
|
+
fields: {
|
|
69
|
+
name: { type: 'String', required: true },
|
|
70
|
+
test2: { type: 'RoleEnum' },
|
|
71
|
+
test3: { type: 'Relation', class: 'User', required: true },
|
|
72
|
+
test4: { type: 'Pointer', class: 'User', required: true },
|
|
73
|
+
experiences: {
|
|
74
|
+
type: 'Array',
|
|
75
|
+
typeValue: 'Object',
|
|
76
|
+
object: {
|
|
77
|
+
name: 'Experience',
|
|
78
|
+
required: true,
|
|
79
|
+
fields: {
|
|
80
|
+
jobTitle: {
|
|
81
|
+
type: 'String',
|
|
82
|
+
required: true,
|
|
83
|
+
},
|
|
84
|
+
companyName: {
|
|
85
|
+
type: 'String',
|
|
86
|
+
required: true,
|
|
87
|
+
},
|
|
88
|
+
startDate: {
|
|
89
|
+
type: 'String',
|
|
90
|
+
required: true,
|
|
91
|
+
},
|
|
92
|
+
endDate: {
|
|
93
|
+
type: 'String',
|
|
94
|
+
required: true,
|
|
95
|
+
},
|
|
96
|
+
achievements: {
|
|
97
|
+
type: 'Array',
|
|
98
|
+
typeValue: 'String',
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
permissions: {
|
|
105
|
+
create: {
|
|
106
|
+
requireAuthentication: true,
|
|
107
|
+
authorizedRoles: [RoleEnum.Admin],
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
resolvers: {
|
|
113
|
+
queries: {
|
|
114
|
+
helloWorld: {
|
|
115
|
+
type: 'String',
|
|
116
|
+
description: 'Hello world description',
|
|
117
|
+
args: {
|
|
118
|
+
name: {
|
|
119
|
+
type: 'String',
|
|
120
|
+
required: true,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
resolve: () => 'Hello World',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
mutations: {
|
|
127
|
+
createMutation: {
|
|
128
|
+
type: 'Boolean',
|
|
129
|
+
required: true,
|
|
130
|
+
args: {
|
|
131
|
+
input: {
|
|
132
|
+
name: {
|
|
133
|
+
type: 'Int',
|
|
134
|
+
required: true,
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
resolve: () => true,
|
|
139
|
+
},
|
|
140
|
+
customMutation: {
|
|
141
|
+
type: 'Int',
|
|
142
|
+
args: {
|
|
143
|
+
input: {
|
|
144
|
+
a: {
|
|
145
|
+
type: 'Int',
|
|
146
|
+
required: true,
|
|
147
|
+
},
|
|
148
|
+
b: {
|
|
149
|
+
type: 'Int',
|
|
150
|
+
required: true,
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
resolve: (_: any, args: any) => args.input.a + args.input.b,
|
|
155
|
+
},
|
|
156
|
+
secondCustomMutation: {
|
|
157
|
+
type: 'Int',
|
|
158
|
+
args: {
|
|
159
|
+
input: {
|
|
160
|
+
sum: {
|
|
161
|
+
type: 'Object',
|
|
162
|
+
object: {
|
|
163
|
+
name: 'Sum',
|
|
164
|
+
fields: {
|
|
165
|
+
a: {
|
|
166
|
+
type: 'Int',
|
|
167
|
+
required: true,
|
|
168
|
+
},
|
|
169
|
+
b: {
|
|
170
|
+
type: 'Int',
|
|
171
|
+
required: true,
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
resolve: (_: any, args: any) => args.input.sum.a + args.input.sum.b,
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
// For select test
|
|
186
|
+
// const res = await wabe.controllers.database.getObjects({
|
|
187
|
+
// className: 'Post',
|
|
188
|
+
// context: {} as any,
|
|
189
|
+
// select: {
|
|
190
|
+
// name: true,
|
|
191
|
+
// test3: {
|
|
192
|
+
// age: true,
|
|
193
|
+
// role: {
|
|
194
|
+
// id: true,
|
|
195
|
+
// },
|
|
196
|
+
// },
|
|
197
|
+
// test4: {
|
|
198
|
+
// name: true,
|
|
199
|
+
// },
|
|
200
|
+
// },
|
|
201
|
+
// where: {
|
|
202
|
+
// name: {
|
|
203
|
+
// equalTo: 'test',
|
|
204
|
+
// },
|
|
205
|
+
// },
|
|
206
|
+
// })
|
|
207
|
+
|
|
208
|
+
// res[0]?.test3[0].role?.id
|
|
209
|
+
|
|
210
|
+
await wabe.start()
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
run().catch((err) => {
|
|
214
|
+
console.error(err)
|
|
215
|
+
})
|
|
@@ -3,8 +3,11 @@ export declare class OTP {
|
|
|
3
3
|
private secret;
|
|
4
4
|
internalTotp: TOTP;
|
|
5
5
|
constructor(rootKey: string);
|
|
6
|
+
deriveSecret(userId: string): string;
|
|
6
7
|
generate(userId: string): string;
|
|
7
8
|
verify(otp: string, userId: string): boolean;
|
|
9
|
+
authenticatorGenerate(userId: string): string;
|
|
10
|
+
authenticatorVerify(otp: string, userId: string): boolean;
|
|
8
11
|
generateKeyuri({ userId, emailOrUsername, applicationName }: {
|
|
9
12
|
userId: string;
|
|
10
13
|
emailOrUsername: string;
|
|
@@ -8,14 +8,17 @@ export declare class Session {
|
|
|
8
8
|
getAccessTokenExpireAt(config: WabeConfig<DevWabeTypes>);
|
|
9
9
|
_getRefreshTokenExpiresInMs(config: WabeConfig<DevWabeTypes>);
|
|
10
10
|
getRefreshTokenExpireAt(config: WabeConfig<DevWabeTypes>);
|
|
11
|
-
meFromAccessToken(accessToken
|
|
11
|
+
meFromAccessToken({ accessToken, csrfToken }: {
|
|
12
|
+
accessToken: string;
|
|
13
|
+
csrfToken: string;
|
|
14
|
+
}, context: WabeContext<DevWabeTypes>): Promise<{
|
|
12
15
|
sessionId: string | null;
|
|
13
16
|
user: User | null;
|
|
14
17
|
accessToken: string | null;
|
|
15
18
|
refreshToken?: string | null;
|
|
16
19
|
}>;
|
|
17
20
|
create(userId: string, context: WabeContext<DevWabeTypes>);
|
|
21
|
+
refresh(accessToken: string, refreshToken: string, context: WabeContext<DevWabeTypes>);
|
|
18
22
|
delete(context: WabeContext<DevWabeTypes>);
|
|
19
23
|
_isRefreshTokenExpired(userRefreshTokenExpiresAt: Date, refreshTokenAgeInMs: number);
|
|
20
|
-
refresh(accessToken: string, refreshToken: string, context: WabeContext<DevWabeTypes>);
|
|
21
24
|
}
|
|
@@ -2,6 +2,7 @@ import type { User } from "../../generated/wabe";
|
|
|
2
2
|
import type { WabeContext } from "../server/interface";
|
|
3
3
|
import type { SchemaFields } from "../schema";
|
|
4
4
|
import type { WabeTypes, WobeCustomContext } from "../server";
|
|
5
|
+
import type { SelectType } from "../database/interface";
|
|
5
6
|
export declare enum ProviderEnum {
|
|
6
7
|
google = "google",
|
|
7
8
|
github = "github"
|
|
@@ -82,7 +83,7 @@ export type CustomAuthenticationMethods<
|
|
|
82
83
|
isSecondaryFactor?: boolean;
|
|
83
84
|
};
|
|
84
85
|
export type RoleConfig = Array<string>;
|
|
85
|
-
export interface SessionConfig {
|
|
86
|
+
export interface SessionConfig<T extends WabeTypes> {
|
|
86
87
|
/**
|
|
87
88
|
* The time in milliseconds that the access token will expire
|
|
88
89
|
*/
|
|
@@ -99,9 +100,29 @@ export interface SessionConfig {
|
|
|
99
100
|
* The JWT secret used to sign the session tokens
|
|
100
101
|
*/
|
|
101
102
|
jwtSecret: string;
|
|
103
|
+
/**
|
|
104
|
+
* Optional audience to embed and verify in JWTs
|
|
105
|
+
*/
|
|
106
|
+
jwtAudience?: string;
|
|
107
|
+
/**
|
|
108
|
+
* Optional issuer to embed and verify in JWTs
|
|
109
|
+
*/
|
|
110
|
+
jwtIssuer?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Secret dedicated to CSRF token HMAC (defaults to jwtSecret)
|
|
113
|
+
*/
|
|
114
|
+
csrfSecret?: string;
|
|
115
|
+
/**
|
|
116
|
+
* Secret used to encrypt session tokens at rest (defaults to jwtSecret)
|
|
117
|
+
*/
|
|
118
|
+
tokenSecret?: string;
|
|
119
|
+
/**
|
|
120
|
+
* A selection of fields to include in the JWT token in the "user" fields
|
|
121
|
+
*/
|
|
122
|
+
jwtTokenFields?: SelectType<T, "User", keyof T["types"]["User"]>;
|
|
102
123
|
}
|
|
103
124
|
export interface AuthenticationConfig<T extends WabeTypes> {
|
|
104
|
-
session?: SessionConfig
|
|
125
|
+
session?: SessionConfig<T>;
|
|
105
126
|
roles?: RoleConfig;
|
|
106
127
|
successRedirectPath?: string;
|
|
107
128
|
failureRedirectPath?: string;
|
|
@@ -129,5 +150,6 @@ export declare enum AuthenticationProvider {
|
|
|
129
150
|
PhonePassword = "phonePassword"
|
|
130
151
|
}
|
|
131
152
|
export declare enum SecondaryFactor {
|
|
132
|
-
EmailOTP = "emailOTP"
|
|
153
|
+
EmailOTP = "emailOTP",
|
|
154
|
+
QRCodeOTP = "qrcodeOTP"
|
|
133
155
|
}
|
|
@@ -33,7 +33,7 @@ export declare class DatabaseController<T extends WabeTypes> {
|
|
|
33
33
|
});
|
|
34
34
|
_getWhereObjectWithPointerOrRelation<U extends keyof T["types"]>(className: U, where: WhereType<T, U>, context: WabeContext<T>);
|
|
35
35
|
_buildWhereWithACL<K extends keyof T["types"]>(where: WhereType<T, K>, context: WabeContext<T>, operation: "write" | "read"): WhereType<T, K>;
|
|
36
|
-
_getFinalObjectWithPointerAndRelation({ pointers, context, originClassName, object,
|
|
36
|
+
_getFinalObjectWithPointerAndRelation({ pointers, context, originClassName, object, _skipHooks }: {
|
|
37
37
|
originClassName: string;
|
|
38
38
|
pointers: Record<string, {
|
|
39
39
|
className: string;
|
|
@@ -41,7 +41,7 @@ export declare class DatabaseController<T extends WabeTypes> {
|
|
|
41
41
|
}>;
|
|
42
42
|
context: WabeContext<any>;
|
|
43
43
|
object: Record<string, any>;
|
|
44
|
-
|
|
44
|
+
_skipHooks?: boolean;
|
|
45
45
|
});
|
|
46
46
|
close();
|
|
47
47
|
createClassIfNotExist(className: string, schema: SchemaInterface<T>): Promise<any>;
|
|
@@ -51,42 +51,42 @@ export declare class DatabaseController<T extends WabeTypes> {
|
|
|
51
51
|
getObject<
|
|
52
52
|
K extends keyof T["types"],
|
|
53
53
|
U extends keyof T["types"][K]
|
|
54
|
-
>({ select, className, context,
|
|
54
|
+
>({ select, className, context, _skipHooks, id, where }: GetObjectOptions<T, K, U>): Promise<OutputType<T, K, U>>;
|
|
55
55
|
getObjects<
|
|
56
56
|
K extends keyof T["types"],
|
|
57
57
|
U extends keyof T["types"][K],
|
|
58
58
|
W extends keyof T["types"][K]
|
|
59
|
-
>({ className, select, context, where,
|
|
59
|
+
>({ className, select, context, where, _skipHooks, first, offset, order }: GetObjectsOptions<T, K, U, W>): Promise<OutputType<T, K, W>[]>;
|
|
60
60
|
createObject<
|
|
61
61
|
K extends keyof T["types"],
|
|
62
62
|
U extends keyof T["types"][K],
|
|
63
63
|
W extends keyof T["types"][K]
|
|
64
|
-
>({ className, context, data, select
|
|
64
|
+
>({ className, context, data, select }: CreateObjectOptions<T, K, U, W>): Promise<OutputType<T, K, W>>;
|
|
65
65
|
createObjects<
|
|
66
66
|
K extends keyof T["types"],
|
|
67
67
|
U extends keyof T["types"][K],
|
|
68
68
|
W extends keyof T["types"][K],
|
|
69
69
|
X extends keyof T["types"][K]
|
|
70
|
-
>({ data, select, className, context, first, offset, order
|
|
70
|
+
>({ data, select, className, context, first, offset, order }: CreateObjectsOptions<T, K, U, W, X>): Promise<OutputType<T, K, W>[]>;
|
|
71
71
|
updateObject<
|
|
72
72
|
K extends keyof T["types"],
|
|
73
73
|
U extends keyof T["types"][K],
|
|
74
74
|
W extends keyof T["types"][K]
|
|
75
|
-
>({ id, className, context, data, select,
|
|
75
|
+
>({ id, className, context, data, select, _skipHooks }: UpdateObjectOptions<T, K, U, W>): Promise<OutputType<T, K, W>>;
|
|
76
76
|
updateObjects<
|
|
77
77
|
K extends keyof T["types"],
|
|
78
78
|
U extends keyof T["types"][K],
|
|
79
79
|
W extends keyof T["types"][K],
|
|
80
80
|
X extends keyof T["types"][K]
|
|
81
|
-
>({ className, where, context, select, data, first, offset, order,
|
|
81
|
+
>({ className, where, context, select, data, first, offset, order, _skipHooks }: UpdateObjectsOptions<T, K, U, W, X>): Promise<OutputType<T, K, W>[]>;
|
|
82
82
|
deleteObject<
|
|
83
83
|
K extends keyof T["types"],
|
|
84
84
|
U extends keyof T["types"][K]
|
|
85
|
-
>({ context, className, id, select
|
|
85
|
+
>({ context, className, id, select }: DeleteObjectOptions<T, K, U>): Promise<OutputType<T, K, U>>;
|
|
86
86
|
deleteObjects<
|
|
87
87
|
K extends keyof T["types"],
|
|
88
88
|
U extends keyof T["types"][K],
|
|
89
89
|
W extends keyof T["types"][K]
|
|
90
|
-
>({ className, context, select, where, first, offset, order
|
|
90
|
+
>({ className, context, select, where, first, offset, order }: DeleteObjectsOptions<T, K, U, W>): Promise<OutputType<T, K, W>[]>;
|
|
91
91
|
}
|
|
92
92
|
export {};
|
|
@@ -95,9 +95,8 @@ export interface GetObjectOptions<
|
|
|
95
95
|
id: string;
|
|
96
96
|
where?: WhereType<T, K>;
|
|
97
97
|
context: WabeContext<T>;
|
|
98
|
-
|
|
98
|
+
_skipHooks?: boolean;
|
|
99
99
|
select?: SelectType<T, K, U>;
|
|
100
|
-
isGraphQLCall?: boolean;
|
|
101
100
|
}
|
|
102
101
|
export interface GetObjectsOptions<
|
|
103
102
|
T extends WabeTypes,
|
|
@@ -111,9 +110,8 @@ export interface GetObjectsOptions<
|
|
|
111
110
|
offset?: number;
|
|
112
111
|
first?: number;
|
|
113
112
|
context: WabeContext<T>;
|
|
114
|
-
|
|
113
|
+
_skipHooks?: boolean;
|
|
115
114
|
select?: SelectType<T, K, W>;
|
|
116
|
-
isGraphQLCall?: boolean;
|
|
117
115
|
}
|
|
118
116
|
export interface CreateObjectOptions<
|
|
119
117
|
T extends WabeTypes,
|
|
@@ -125,7 +123,6 @@ export interface CreateObjectOptions<
|
|
|
125
123
|
data: MutationData<T, K, U>;
|
|
126
124
|
context: WabeContext<T>;
|
|
127
125
|
select?: SelectType<T, K, W>;
|
|
128
|
-
isGraphQLCall?: boolean;
|
|
129
126
|
}
|
|
130
127
|
export interface CreateObjectsOptions<
|
|
131
128
|
T extends WabeTypes,
|
|
@@ -141,7 +138,6 @@ export interface CreateObjectsOptions<
|
|
|
141
138
|
order?: OrderType<T, U, X>;
|
|
142
139
|
context: WabeContext<T>;
|
|
143
140
|
select?: SelectType<T, K, W>;
|
|
144
|
-
isGraphQLCall?: boolean;
|
|
145
141
|
}
|
|
146
142
|
export interface UpdateObjectOptions<
|
|
147
143
|
T extends WabeTypes,
|
|
@@ -154,9 +150,8 @@ export interface UpdateObjectOptions<
|
|
|
154
150
|
where?: WhereType<T, K>;
|
|
155
151
|
data: MutationData<T, K, U>;
|
|
156
152
|
context: WabeContext<T>;
|
|
157
|
-
|
|
153
|
+
_skipHooks?: boolean;
|
|
158
154
|
select?: SelectType<T, K, W>;
|
|
159
|
-
isGraphQLCall?: boolean;
|
|
160
155
|
}
|
|
161
156
|
export interface UpdateObjectsOptions<
|
|
162
157
|
T extends WabeTypes,
|
|
@@ -172,9 +167,8 @@ export interface UpdateObjectsOptions<
|
|
|
172
167
|
offset?: number;
|
|
173
168
|
first?: number;
|
|
174
169
|
context: WabeContext<T>;
|
|
175
|
-
|
|
170
|
+
_skipHooks?: boolean;
|
|
176
171
|
select?: SelectType<T, K, W>;
|
|
177
|
-
isGraphQLCall?: boolean;
|
|
178
172
|
}
|
|
179
173
|
export interface DeleteObjectOptions<
|
|
180
174
|
T extends WabeTypes,
|
|
@@ -186,7 +180,6 @@ export interface DeleteObjectOptions<
|
|
|
186
180
|
where?: WhereType<T, K>;
|
|
187
181
|
context: WabeContext<T>;
|
|
188
182
|
select?: SelectType<T, K, U>;
|
|
189
|
-
isGraphQLCall?: boolean;
|
|
190
183
|
}
|
|
191
184
|
export interface DeleteObjectsOptions<
|
|
192
185
|
T extends WabeTypes,
|
|
@@ -201,11 +194,10 @@ export interface DeleteObjectsOptions<
|
|
|
201
194
|
first?: number;
|
|
202
195
|
context: WabeContext<T>;
|
|
203
196
|
select?: SelectType<T, K, W>;
|
|
204
|
-
isGraphQLCall?: boolean;
|
|
205
197
|
}
|
|
206
198
|
export interface DatabaseAdapter<T extends WabeTypes> {
|
|
207
199
|
close(): Promise<void>;
|
|
208
|
-
createClassIfNotExist(className: string, schema: SchemaInterface<T>): Promise<any
|
|
200
|
+
createClassIfNotExist(className: string, schema: SchemaInterface<T>): Promise<any> | any;
|
|
209
201
|
initializeDatabase(schema: SchemaInterface<T>): Promise<void>;
|
|
210
202
|
clearDatabase(): Promise<void>;
|
|
211
203
|
count<K extends keyof T["types"]>(params: CountOptions<T, K>): Promise<number>;
|