over-zero 0.0.5 → 0.0.7
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/dist/cjs/createPermissions.cjs +5 -4
- package/dist/cjs/createPermissions.js +5 -5
- package/dist/cjs/createPermissions.js.map +1 -1
- package/dist/cjs/createPermissions.native.js +8 -5
- package/dist/cjs/createPermissions.native.js.map +1 -1
- package/dist/cjs/createZeroClient.cjs +3 -8
- package/dist/cjs/createZeroClient.js +4 -6
- package/dist/cjs/createZeroClient.js.map +1 -1
- package/dist/cjs/createZeroClient.native.js +4 -6
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/createZeroServer.cjs +24 -18
- package/dist/cjs/createZeroServer.js +24 -16
- package/dist/cjs/createZeroServer.js.map +2 -2
- package/dist/cjs/createZeroServer.native.js +24 -15
- package/dist/cjs/createZeroServer.native.js.map +2 -2
- package/dist/cjs/helpers/createMutators.cjs +4 -2
- package/dist/cjs/helpers/createMutators.js +4 -2
- package/dist/cjs/helpers/createMutators.js.map +1 -1
- package/dist/cjs/helpers/createMutators.native.js +4 -2
- package/dist/cjs/helpers/createMutators.native.js.map +1 -1
- package/dist/cjs/helpers/didRunPermissionCheck.cjs +29 -0
- package/dist/cjs/helpers/didRunPermissionCheck.js +22 -0
- package/dist/cjs/helpers/didRunPermissionCheck.js.map +6 -0
- package/dist/cjs/helpers/didRunPermissionCheck.native.js +32 -0
- package/dist/cjs/helpers/didRunPermissionCheck.native.js.map +6 -0
- package/dist/cjs/helpers/getDidRunPermissionCheck.cjs +27 -0
- package/dist/cjs/helpers/getDidRunPermissionCheck.js +21 -0
- package/dist/cjs/helpers/getDidRunPermissionCheck.js.map +6 -0
- package/dist/cjs/helpers/getDidRunPermissionCheck.native.js +28 -0
- package/dist/cjs/helpers/getDidRunPermissionCheck.native.js.map +6 -0
- package/dist/cjs/mutations.cjs +2 -1
- package/dist/cjs/mutations.js +2 -1
- package/dist/cjs/mutations.js.map +1 -1
- package/dist/cjs/mutations.native.js +2 -1
- package/dist/cjs/mutations.native.js.map +1 -1
- package/dist/esm/createPermissions.js +5 -4
- package/dist/esm/createPermissions.js.map +1 -1
- package/dist/esm/createPermissions.mjs +5 -4
- package/dist/esm/createPermissions.mjs.map +1 -1
- package/dist/esm/createPermissions.native.js +8 -4
- package/dist/esm/createPermissions.native.js.map +1 -1
- package/dist/esm/createZeroClient.js +5 -7
- package/dist/esm/createZeroClient.js.map +1 -1
- package/dist/esm/createZeroClient.mjs +4 -9
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +4 -9
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/createZeroServer.js +24 -16
- package/dist/esm/createZeroServer.js.map +2 -2
- package/dist/esm/createZeroServer.mjs +24 -18
- package/dist/esm/createZeroServer.mjs.map +1 -1
- package/dist/esm/createZeroServer.native.js +26 -18
- package/dist/esm/createZeroServer.native.js.map +1 -1
- package/dist/esm/helpers/createMutators.js +4 -2
- package/dist/esm/helpers/createMutators.js.map +1 -1
- package/dist/esm/helpers/createMutators.mjs +4 -2
- package/dist/esm/helpers/createMutators.mjs.map +1 -1
- package/dist/esm/helpers/createMutators.native.js +4 -2
- package/dist/esm/helpers/createMutators.native.js.map +1 -1
- package/dist/esm/helpers/didRunPermissionCheck.js +6 -0
- package/dist/esm/helpers/didRunPermissionCheck.js.map +6 -0
- package/dist/esm/helpers/didRunPermissionCheck.mjs +5 -0
- package/dist/esm/helpers/didRunPermissionCheck.mjs.map +1 -0
- package/dist/esm/helpers/didRunPermissionCheck.native.js +9 -0
- package/dist/esm/helpers/didRunPermissionCheck.native.js.map +1 -0
- package/dist/esm/helpers/getDidRunPermissionCheck.js +5 -0
- package/dist/esm/helpers/getDidRunPermissionCheck.js.map +6 -0
- package/dist/esm/helpers/getDidRunPermissionCheck.mjs +4 -0
- package/dist/esm/helpers/getDidRunPermissionCheck.mjs.map +1 -0
- package/dist/esm/helpers/getDidRunPermissionCheck.native.js +6 -0
- package/dist/esm/helpers/getDidRunPermissionCheck.native.js.map +1 -0
- package/dist/esm/mutations.js +2 -1
- package/dist/esm/mutations.js.map +1 -1
- package/dist/esm/mutations.mjs +2 -1
- package/dist/esm/mutations.mjs.map +1 -1
- package/dist/esm/mutations.native.js +2 -1
- package/dist/esm/mutations.native.js.map +1 -1
- package/package.json +3 -2
- package/readme.md +15 -11
- package/src/createPermissions.ts +48 -40
- package/src/createZeroClient.tsx +7 -7
- package/src/createZeroServer.ts +39 -22
- package/src/helpers/createMutators.ts +11 -5
- package/src/helpers/didRunPermissionCheck.ts +11 -0
- package/src/mutations.ts +5 -7
- package/src/types.ts +28 -15
- package/types/createPermissions.d.ts +2 -2
- package/types/createPermissions.d.ts.map +1 -1
- package/types/createZeroServer.d.ts +6 -2
- package/types/createZeroServer.d.ts.map +1 -1
- package/types/helpers/createMutators.d.ts +2 -2
- package/types/helpers/createMutators.d.ts.map +1 -1
- package/types/helpers/didRunPermissionCheck.d.ts +4 -0
- package/types/helpers/didRunPermissionCheck.d.ts.map +1 -0
- package/types/mutations.d.ts +1 -1
- package/types/mutations.d.ts.map +1 -1
- package/types/types.d.ts +15 -11
- package/types/types.d.ts.map +1 -1
package/readme.md
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
# over-zero
|
|
2
2
|
|
|
3
|
-
This library is
|
|
4
|
-
|
|
5
|
-
integrating authentication, writing your schema in a DRY way, and getting back
|
|
6
|
-
great types.
|
|
7
|
-
|
|
8
|
-
It's main exports are `createZero` and `createZeroServer`, for your client and
|
|
9
|
-
server-side setup.
|
|
3
|
+
This library is small suite of helpers we extracted after using Zero across a
|
|
4
|
+
few production apps.
|
|
10
5
|
|
|
11
6
|
It's main feature is allowing you to define a `models/*` directory where you can
|
|
12
|
-
define each zero **table** alongside its **permissions** and **mutations
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
define each zero **table** alongside its **permissions** and **mutations** in an
|
|
8
|
+
intuitive and simple way.
|
|
9
|
+
|
|
10
|
+
It also provides `createZero` and `createZeroServer` which return helpers for
|
|
11
|
+
your that make a variety of common client and server patterns simpler.
|
|
12
|
+
|
|
13
|
+
Within models, you can automatically define CRUD-style mutations which apply
|
|
14
|
+
permissions defined using simple `where` and `mutations` helper functions. You
|
|
15
|
+
can then use your permissions in custom mutators with the `can` helper function.
|
|
16
|
+
|
|
17
|
+
For permissions, you get a handy `usePermission` helper for client.
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
On the server, you get helpers to run one-off queries and mutations using
|
|
20
|
+
standard Zero APIs, and a helper to simplify setting up your `/push` endpoint.
|
package/src/createPermissions.ts
CHANGED
|
@@ -7,8 +7,16 @@ import type {
|
|
|
7
7
|
import { ANYONE_CAN, definePermissions } from '@rocicorp/zero'
|
|
8
8
|
import { ensure, EnsureError, objectEntries } from '@vxrn/helpers'
|
|
9
9
|
import { runWithContext } from './helpers/context'
|
|
10
|
+
import { setDidRunPermissionCheck } from './helpers/didRunPermissionCheck'
|
|
10
11
|
import { prettyFormatZeroQuery } from './helpers/prettyFormatZeroQuery'
|
|
11
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
AuthData,
|
|
14
|
+
Can,
|
|
15
|
+
MutatorContext,
|
|
16
|
+
TableName,
|
|
17
|
+
Transaction,
|
|
18
|
+
Where,
|
|
19
|
+
} from './types'
|
|
12
20
|
import { getWhereTableName } from './where'
|
|
13
21
|
|
|
14
22
|
export function createPermissions<Schema extends ZeroSchema>({
|
|
@@ -100,10 +108,7 @@ export function createPermissions<Schema extends ZeroSchema>({
|
|
|
100
108
|
return eb.and(permissionCondition, ...primaryKeyWheres)
|
|
101
109
|
}
|
|
102
110
|
|
|
103
|
-
async
|
|
104
|
-
PWhere extends PermissionsWhere,
|
|
105
|
-
Action extends keyof ReturnType<PWhere>,
|
|
106
|
-
>(where: PWhere, action: Action, obj: any) {
|
|
111
|
+
const can: Can = async (where, action, obj) => {
|
|
107
112
|
const ctx = getContext()
|
|
108
113
|
const tableName = getWhereTableName(where)
|
|
109
114
|
if (!tableName) {
|
|
@@ -120,7 +125,7 @@ export function createPermissions<Schema extends ZeroSchema>({
|
|
|
120
125
|
action as string,
|
|
121
126
|
obj
|
|
122
127
|
)
|
|
123
|
-
ctx
|
|
128
|
+
setDidRunPermissionCheck(ctx)
|
|
124
129
|
}
|
|
125
130
|
}
|
|
126
131
|
|
|
@@ -171,41 +176,44 @@ export function createPermissions<Schema extends ZeroSchema>({
|
|
|
171
176
|
|
|
172
177
|
const readPermissions = definePermissions<AuthData, Schema>(schema, async () => {
|
|
173
178
|
const permissionsEntries = await Promise.all(
|
|
174
|
-
objectEntries(models)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
179
|
+
objectEntries(models)
|
|
180
|
+
// non permissioned models dont turn into read permissions
|
|
181
|
+
.filter(([_, model]) => !!model.permissions)
|
|
182
|
+
.map(async ([key, model]) => {
|
|
183
|
+
return await runWithContext(
|
|
184
|
+
{
|
|
185
|
+
authData: { id: '', role: undefined, email: '' },
|
|
186
|
+
} as any,
|
|
187
|
+
() => {
|
|
188
|
+
return [
|
|
189
|
+
key,
|
|
190
|
+
{
|
|
191
|
+
row: {
|
|
192
|
+
select: [
|
|
193
|
+
(authData: AuthData, eb: ExpressionBuilder<any, any>) => {
|
|
194
|
+
const out = model.permissions(eb, authData).read
|
|
195
|
+
|
|
196
|
+
if (out === true) {
|
|
197
|
+
return eb.and()
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (out === false) {
|
|
201
|
+
return eb.cmpLit(true, '=', false)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return out
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
// we have permissions on these through our model system with custom mutators:
|
|
208
|
+
insert: ANYONE_CAN,
|
|
209
|
+
update: ANYONE_CAN,
|
|
210
|
+
delete: ANYONE_CAN,
|
|
211
|
+
},
|
|
203
212
|
},
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
)
|
|
208
|
-
})
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
)
|
|
216
|
+
})
|
|
209
217
|
)
|
|
210
218
|
|
|
211
219
|
const permissions = Object.fromEntries(permissionsEntries)
|
package/src/createZeroClient.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Row, Zero, ZeroOptions, Schema as ZeroSchema } from '@rocicorp/zero'
|
|
2
2
|
import { useZero, ZeroProvider, useQuery as zeroUseQuery } from '@rocicorp/zero/react'
|
|
3
|
-
import { createEmitter,
|
|
3
|
+
import { createEmitter, mapObject } from '@vxrn/helpers'
|
|
4
4
|
import { createContext, use, useMemo, type ReactNode } from 'react'
|
|
5
5
|
import { createPermissions } from './createPermissions'
|
|
6
6
|
import { context } from './helpers/context'
|
|
@@ -39,9 +39,9 @@ export function createZeroClient<
|
|
|
39
39
|
environment: 'client',
|
|
40
40
|
})
|
|
41
41
|
|
|
42
|
-
const permissionCache = createLocalStorage<string, boolean>('permissions-cache', {
|
|
43
|
-
|
|
44
|
-
})
|
|
42
|
+
// const permissionCache = createLocalStorage<string, boolean>('permissions-cache', {
|
|
43
|
+
// storageLimit: 24,
|
|
44
|
+
// })
|
|
45
45
|
|
|
46
46
|
const zeroEvents = createEmitter<ZeroEvent | null>('zero', null)
|
|
47
47
|
|
|
@@ -65,14 +65,14 @@ export function createZeroClient<
|
|
|
65
65
|
// we fallback to just table.action, to avoid flickers for now
|
|
66
66
|
const keyBase = `${String(table)}${action}`
|
|
67
67
|
const key = `${keyBase}${typeof objOrId === 'string' ? objOrId : JSON.stringify(objOrId)}`
|
|
68
|
-
const cacheVal = permissionCache.get(key) ?? permissionCache.get(keyBase)
|
|
68
|
+
// const cacheVal = permissionCache.get(key) ?? permissionCache.get(keyBase)
|
|
69
69
|
const authData = useAuthData()
|
|
70
70
|
const permission = modelPermissions[table]
|
|
71
71
|
|
|
72
72
|
const query = (() => {
|
|
73
73
|
let baseQuery = zero.query[table].one()
|
|
74
74
|
|
|
75
|
-
if (!enabled) {
|
|
75
|
+
if (!enabled || !permission) {
|
|
76
76
|
return baseQuery
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -88,7 +88,7 @@ export function createZeroClient<
|
|
|
88
88
|
})()
|
|
89
89
|
|
|
90
90
|
const [data, status] = useQuery(query, {
|
|
91
|
-
enabled: Boolean(enabled && authData && objOrId),
|
|
91
|
+
enabled: Boolean(enabled && permission && authData && objOrId),
|
|
92
92
|
})
|
|
93
93
|
|
|
94
94
|
if (debug) {
|
package/src/createZeroServer.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Schema as ZeroSchema } from '@rocicorp/zero'
|
|
1
|
+
import type { Query, Schema as ZeroSchema } from '@rocicorp/zero'
|
|
2
2
|
import type { TransactionProviderInput } from '@rocicorp/zero/pg'
|
|
3
3
|
import { PostgresJSConnection, PushProcessor } from '@rocicorp/zero/pg'
|
|
4
4
|
import { ZQLDatabase } from '@rocicorp/zero/server'
|
|
@@ -21,17 +21,26 @@ export function createZeroServer<
|
|
|
21
21
|
ServerActions extends Record<string, unknown>,
|
|
22
22
|
>({
|
|
23
23
|
createServerActions,
|
|
24
|
+
database,
|
|
24
25
|
schema,
|
|
25
26
|
models,
|
|
26
27
|
}: {
|
|
28
|
+
/**
|
|
29
|
+
* The DB connection string, same as ZERO_UPSTREAM_DB
|
|
30
|
+
*/
|
|
31
|
+
database: string
|
|
27
32
|
schema: Schema
|
|
28
33
|
models: Models
|
|
29
34
|
createServerActions: () => ServerActions
|
|
30
35
|
}) {
|
|
31
|
-
const dbString = assertString(
|
|
36
|
+
const dbString = assertString(database, `"database" prop`)
|
|
37
|
+
const db = postgres(dbString)
|
|
32
38
|
|
|
33
39
|
const zeroServerDatabase = new ZQLDatabase(
|
|
34
|
-
new PostgresJSConnection(
|
|
40
|
+
new PostgresJSConnection(
|
|
41
|
+
// TODO if you have duplicate postgres due to zero having its own in node_modules TS types break
|
|
42
|
+
db as any
|
|
43
|
+
),
|
|
35
44
|
schema
|
|
36
45
|
)
|
|
37
46
|
|
|
@@ -87,7 +96,7 @@ export function createZeroServer<
|
|
|
87
96
|
}
|
|
88
97
|
}
|
|
89
98
|
|
|
90
|
-
const
|
|
99
|
+
const mutate = async (
|
|
91
100
|
run: (tx: Transaction, mutators: GetZeroMutators<Models>) => Promise<void>,
|
|
92
101
|
authData?: Pick<AuthData, 'email' | 'id'> & Partial<AuthData>
|
|
93
102
|
) => {
|
|
@@ -107,26 +116,14 @@ export function createZeroServer<
|
|
|
107
116
|
can: permissions.can,
|
|
108
117
|
})
|
|
109
118
|
|
|
110
|
-
await
|
|
119
|
+
await transaction(async (tx) => {
|
|
111
120
|
await run(tx, mutators)
|
|
112
121
|
})
|
|
113
122
|
|
|
114
123
|
await Promise.all(asyncTasks.map((t) => t()))
|
|
115
124
|
}
|
|
116
125
|
|
|
117
|
-
|
|
118
|
-
// TODO should unwrap q.query
|
|
119
|
-
const serverQuery = serverTransaction
|
|
120
|
-
|
|
121
|
-
// This is needed temporarily and will be cleaned up in the future.
|
|
122
|
-
const dummyTransactionInput: TransactionProviderInput = {
|
|
123
|
-
clientGroupID: 'unused',
|
|
124
|
-
clientID: 'unused',
|
|
125
|
-
mutationID: 42,
|
|
126
|
-
upstreamSchema: 'unused',
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
async function serverTransaction<
|
|
126
|
+
async function transaction<
|
|
130
127
|
CB extends (tx: Transaction) => Promise<any>,
|
|
131
128
|
Returns extends CB extends (tx: Transaction) => Promise<infer X> ? X : never,
|
|
132
129
|
>(query: CB): Promise<Returns> {
|
|
@@ -139,15 +136,35 @@ export function createZeroServer<
|
|
|
139
136
|
const output = await zeroServerDatabase.transaction(query, dummyTransactionInput)
|
|
140
137
|
return output as any
|
|
141
138
|
} catch (err) {
|
|
142
|
-
console.error(`Error running
|
|
139
|
+
console.error(`Error running transaction(): ${err}`)
|
|
143
140
|
throw err
|
|
144
141
|
}
|
|
145
142
|
}
|
|
146
143
|
|
|
144
|
+
type ZeroQueryFn<Response extends Query<any, any>> = (
|
|
145
|
+
query: Transaction['query']
|
|
146
|
+
) => Promise<Response>
|
|
147
|
+
|
|
148
|
+
async function query<GetQuery extends ZeroQueryFn<any>>(
|
|
149
|
+
cb: GetQuery
|
|
150
|
+
): Promise<ReturnType<GetQuery>> {
|
|
151
|
+
return await transaction(async (tx) => {
|
|
152
|
+
return await cb(tx.query)
|
|
153
|
+
})
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// This is needed temporarily and will be cleaned up in the future.
|
|
157
|
+
const dummyTransactionInput: TransactionProviderInput = {
|
|
158
|
+
clientGroupID: 'unused',
|
|
159
|
+
clientID: 'unused',
|
|
160
|
+
mutationID: 42,
|
|
161
|
+
upstreamSchema: 'unused',
|
|
162
|
+
}
|
|
163
|
+
|
|
147
164
|
return {
|
|
148
165
|
handleMutationRequest,
|
|
149
|
-
transaction
|
|
150
|
-
mutate
|
|
151
|
-
query
|
|
166
|
+
transaction,
|
|
167
|
+
mutate,
|
|
168
|
+
query,
|
|
152
169
|
}
|
|
153
170
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { isClient, isServer, mapObject, time } from '@vxrn/helpers'
|
|
2
2
|
import type {
|
|
3
3
|
AuthData,
|
|
4
|
+
Can,
|
|
4
5
|
GenericModels,
|
|
5
6
|
GetZeroMutators,
|
|
7
|
+
MutatorContext,
|
|
6
8
|
Transaction,
|
|
7
|
-
Where,
|
|
8
9
|
} from '../types'
|
|
9
10
|
import { runWithContext } from './context'
|
|
10
11
|
|
|
@@ -18,7 +19,7 @@ export function createMutators<Models extends GenericModels>({
|
|
|
18
19
|
}: {
|
|
19
20
|
environment: 'server' | 'client'
|
|
20
21
|
authData: AuthData | null
|
|
21
|
-
can:
|
|
22
|
+
can: Can
|
|
22
23
|
models: Models
|
|
23
24
|
asyncTasks?: Array<() => Promise<void>>
|
|
24
25
|
createServerActions?: () => Record<string, any>
|
|
@@ -31,13 +32,18 @@ export function createMutators<Models extends GenericModels>({
|
|
|
31
32
|
|
|
32
33
|
function withContext<Args extends any[]>(fn: (...args: Args) => Promise<void>) {
|
|
33
34
|
return async (tx: Transaction, ...args: Args): Promise<void> => {
|
|
34
|
-
const mutationContext = {
|
|
35
|
+
const mutationContext: MutatorContext = {
|
|
35
36
|
tx,
|
|
36
37
|
authData,
|
|
37
38
|
environment,
|
|
38
39
|
can,
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
server:
|
|
41
|
+
environment === 'server'
|
|
42
|
+
? {
|
|
43
|
+
actions: serverActions || {},
|
|
44
|
+
asyncTasks: asyncTasks || {},
|
|
45
|
+
}
|
|
46
|
+
: undefined,
|
|
41
47
|
}
|
|
42
48
|
|
|
43
49
|
return await runWithContext(mutationContext, () => {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MutatorContext } from '../types'
|
|
2
|
+
|
|
3
|
+
const PermissionCheckRan = new WeakMap<MutatorContext, boolean>()
|
|
4
|
+
|
|
5
|
+
export const getDidRunPermissionCheck = (ctx: MutatorContext) => {
|
|
6
|
+
return PermissionCheckRan.get(ctx)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const setDidRunPermissionCheck = (ctx: MutatorContext) => {
|
|
10
|
+
return PermissionCheckRan.set(ctx, true)
|
|
11
|
+
}
|
package/src/mutations.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TableBuilderWithColumns } from '@rocicorp/zero'
|
|
2
|
+
import { getDidRunPermissionCheck } from './helpers/didRunPermissionCheck'
|
|
2
3
|
import type {
|
|
3
4
|
MutatorContext,
|
|
4
5
|
TableInsertRow,
|
|
@@ -46,11 +47,13 @@ type MutationsWithCRUD<Table extends GenericTable, Mutations extends MutationBui
|
|
|
46
47
|
: never
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
export function mutations<Mutations extends MutationBuilders>(
|
|
51
|
+
mutations: Mutations
|
|
52
|
+
): Mutations
|
|
49
53
|
export function mutations<Table extends GenericTable, Permissions extends Where>(
|
|
50
54
|
table: Table,
|
|
51
55
|
permissions: Permissions
|
|
52
56
|
): MutationsWithCRUD<Table, {}>
|
|
53
|
-
|
|
54
57
|
export function mutations<
|
|
55
58
|
Table extends GenericTable,
|
|
56
59
|
Permissions extends Where,
|
|
@@ -60,11 +63,6 @@ export function mutations<
|
|
|
60
63
|
permissions: Permissions,
|
|
61
64
|
mutations: Mutations
|
|
62
65
|
): MutationsWithCRUD<Table, Mutations>
|
|
63
|
-
|
|
64
|
-
export function mutations<Mutations extends MutationBuilder>(
|
|
65
|
-
mutations: Mutations
|
|
66
|
-
): Mutations
|
|
67
|
-
|
|
68
66
|
// TODO we should enforece the CRUD mutations obj to the callier so they get it auto-typed
|
|
69
67
|
export function mutations<
|
|
70
68
|
Table extends GenericTable,
|
|
@@ -84,7 +82,7 @@ export function mutations<
|
|
|
84
82
|
* - for the rest: check runs before mutation
|
|
85
83
|
*/
|
|
86
84
|
const runServerPermissionCheck = async () => {
|
|
87
|
-
if (ctx
|
|
85
|
+
if (getDidRunPermissionCheck(ctx)) {
|
|
88
86
|
// if the user-defined CRUD mutation runs their own "can", we avoid running ours
|
|
89
87
|
return
|
|
90
88
|
}
|
package/src/types.ts
CHANGED
|
@@ -32,6 +32,7 @@ export interface Config {}
|
|
|
32
32
|
interface DefaultConfig {
|
|
33
33
|
schema: ZeroSchema
|
|
34
34
|
authData: {}
|
|
35
|
+
serverActions: null
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
interface FinalConfig extends Omit<DefaultConfig, keyof Config>, Config {}
|
|
@@ -48,10 +49,26 @@ export type AuthData = FinalConfig['authData'] extends Record<string, unknown>
|
|
|
48
49
|
? FinalConfig['authData']
|
|
49
50
|
: Record<string, unknown>
|
|
50
51
|
|
|
52
|
+
export type ServerActions = FinalConfig['serverActions'] extends Record<string, unknown>
|
|
53
|
+
? FinalConfig['serverActions']
|
|
54
|
+
: Record<string, unknown>
|
|
55
|
+
|
|
51
56
|
/**
|
|
52
57
|
* ➗0️⃣ END OVERRIDDEN TYPES
|
|
53
58
|
*/
|
|
54
59
|
|
|
60
|
+
// the first argument passed to every mutation:
|
|
61
|
+
export type MutatorContext = {
|
|
62
|
+
tx: Transaction
|
|
63
|
+
authData: AuthData | null
|
|
64
|
+
environment: 'server' | 'client'
|
|
65
|
+
server?: {
|
|
66
|
+
actions: ServerActions
|
|
67
|
+
asyncTasks: Array<() => Promise<void>>
|
|
68
|
+
}
|
|
69
|
+
can: Can
|
|
70
|
+
}
|
|
71
|
+
|
|
55
72
|
// turns our mutators with custom context into zero mutators
|
|
56
73
|
export type GetZeroMutators<Models extends GenericModels> = {
|
|
57
74
|
[Key in keyof Models]: TransformMutators<GetModelMutators<Models>[Key]>
|
|
@@ -64,7 +81,7 @@ type GetModelMutators<Models extends GenericModels> = {
|
|
|
64
81
|
export type GenericModels = {
|
|
65
82
|
[key: string]: {
|
|
66
83
|
mutate: Record<string, (ctx: MutatorContext, obj?: any) => Promise<any>>
|
|
67
|
-
permissions
|
|
84
|
+
permissions?: Where
|
|
68
85
|
}
|
|
69
86
|
}
|
|
70
87
|
|
|
@@ -74,15 +91,16 @@ export type TransformMutators<T> = {
|
|
|
74
91
|
: never
|
|
75
92
|
}
|
|
76
93
|
|
|
77
|
-
export type
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
94
|
+
export type Where<Table extends TableName = TableName, ReturnType = any> = (
|
|
95
|
+
expressionBuilder: ExpressionBuilder<Schema, Table>,
|
|
96
|
+
auth: AuthData | null
|
|
97
|
+
) => ReturnType
|
|
98
|
+
|
|
99
|
+
export type Can = <PWhere extends Where, Action extends keyof ReturnType<PWhere>>(
|
|
100
|
+
where: PWhere,
|
|
101
|
+
action: Action,
|
|
102
|
+
obj: string | Record<string, unknown>
|
|
103
|
+
) => Promise<void>
|
|
86
104
|
|
|
87
105
|
export type AsyncAction = () => Promise<void>
|
|
88
106
|
|
|
@@ -108,9 +126,4 @@ export type TablePrimaryKeys<TS extends GenericTable> = TupleToUnion<
|
|
|
108
126
|
GetTableSchema<TS>['primaryKey']
|
|
109
127
|
>
|
|
110
128
|
|
|
111
|
-
export type Where<Table extends TableName = TableName, ReturnType = any> = (
|
|
112
|
-
expressionBuilder: ExpressionBuilder<Schema, Table>,
|
|
113
|
-
auth: AuthData | null
|
|
114
|
-
) => ReturnType
|
|
115
|
-
|
|
116
129
|
export type ZeroEvent = { type: 'error'; message: string }
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { Condition, ExpressionBuilder, Schema as ZeroSchema } from '@rocicorp/zero';
|
|
2
|
-
import type { AuthData, MutatorContext, Where } from './types';
|
|
2
|
+
import type { AuthData, Can, MutatorContext, Where } from './types';
|
|
3
3
|
export declare function createPermissions<Schema extends ZeroSchema>({ environment, schema, models, getContext, }: {
|
|
4
4
|
environment: 'client' | 'server';
|
|
5
5
|
schema: Schema;
|
|
6
6
|
models: any;
|
|
7
7
|
getContext: () => MutatorContext;
|
|
8
8
|
}): {
|
|
9
|
-
can:
|
|
9
|
+
can: Can;
|
|
10
10
|
buildPermissionQuery: <PermissionWhere extends Where<string, Partial<Record<("read" | "write" | "insert" | "update" | "delete" | "select") | (string & {}), boolean | Condition>>>, Action extends string>(authData: AuthData | null, eb: ExpressionBuilder<any, any>, permissionWhere: PermissionWhere, action: Action, objOrId: Record<string, any> | string) => Condition;
|
|
11
11
|
readPermissions: Promise<{
|
|
12
12
|
tables: Record<string, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPermissions.d.ts","sourceRoot":"","sources":["../src/createPermissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,iBAAiB,EAEjB,MAAM,IAAI,UAAU,EACrB,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"createPermissions.d.ts","sourceRoot":"","sources":["../src/createPermissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,iBAAiB,EAEjB,MAAM,IAAI,UAAU,EACrB,MAAM,gBAAgB,CAAA;AAMvB,OAAO,KAAK,EACV,QAAQ,EACR,GAAG,EACH,cAAc,EAGd,KAAK,EACN,MAAM,SAAS,CAAA;AAGhB,wBAAgB,iBAAiB,CAAC,MAAM,SAAS,UAAU,EAAE,EAC3D,WAAW,EACX,MAAM,EACN,MAAM,EACN,UAAU,GACX,EAAE;IACD,WAAW,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,GAAG,CAAA;IACX,UAAU,EAAE,MAAM,cAAc,CAAA;CACjC;;2BA2BG,eAAe,8IACf,MAAM,SAAS,MAAM,YAEX,QAAQ,GAAG,IAAI,MACrB,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,mBACd,eAAe,UACxB,MAAM,WAEL,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM;;;;sBApBtB,CAAC;sBAKN,CAAC;sBAMQ,CAAC;+BACF,CAAC;gCAIF,CAAC;;sBAG6B,CAAC;;;sBAMxC,CAAA;sBAGe,CAAC;sBAMpB,CAAC;+BAA+B,CAAC;gCAEL,CAAC;;sBAIA,CAAC;;;;EA8IrC"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { Schema as ZeroSchema } from '@rocicorp/zero';
|
|
2
2
|
import type { AsyncAction, AuthData, GenericModels, GetZeroMutators, Transaction } from './types';
|
|
3
|
-
export declare function createZeroServer<Schema extends ZeroSchema, Models extends GenericModels, ServerActions extends Record<string, unknown>>({ createServerActions, schema, models, }: {
|
|
3
|
+
export declare function createZeroServer<Schema extends ZeroSchema, Models extends GenericModels, ServerActions extends Record<string, unknown>>({ createServerActions, database, schema, models, }: {
|
|
4
|
+
/**
|
|
5
|
+
* The DB connection string, same as ZERO_UPSTREAM_DB
|
|
6
|
+
*/
|
|
7
|
+
database: string;
|
|
4
8
|
schema: Schema;
|
|
5
9
|
models: Models;
|
|
6
10
|
createServerActions: () => ServerActions;
|
|
@@ -58,6 +62,6 @@ export declare function createZeroServer<Schema extends ZeroSchema, Models exten
|
|
|
58
62
|
}>;
|
|
59
63
|
transaction: <CB extends (tx: Transaction) => Promise<any>, Returns extends CB extends (tx: Transaction) => Promise<infer X> ? X : never>(query: CB) => Promise<Returns>;
|
|
60
64
|
mutate: (run: (tx: Transaction, mutators: GetZeroMutators<Models>) => Promise<void>, authData?: Pick<AuthData, "email" | "id"> & Partial<AuthData>) => Promise<void>;
|
|
61
|
-
query: <
|
|
65
|
+
query: <GetQuery extends (query: Transaction["query"]) => Promise<any>>(cb: GetQuery) => Promise<ReturnType<GetQuery>>;
|
|
62
66
|
};
|
|
63
67
|
//# sourceMappingURL=createZeroServer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createZeroServer.d.ts","sourceRoot":"","sources":["../src/createZeroServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"createZeroServer.d.ts","sourceRoot":"","sources":["../src/createZeroServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAS,MAAM,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAA;AASjE,OAAO,KAAK,EACV,WAAW,EACX,QAAQ,EACR,aAAa,EACb,eAAe,EACf,WAAW,EACZ,MAAM,SAAS,CAAA;AAEhB,wBAAgB,gBAAgB,CAC9B,MAAM,SAAS,UAAU,EACzB,MAAM,SAAS,aAAa,EAC5B,aAAa,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7C,EACA,mBAAmB,EACnB,QAAQ,EACR,MAAM,EACN,MAAM,GACP,EAAE;IACD;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,mBAAmB,EAAE,MAAM,aAAa,CAAA;CACzC;oEAyBI;QACD,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;QACzB,OAAO,EAAE,OAAO,CAAA;QAChB,cAAc,CAAC,EAAE,OAAO,CAAA;KACzB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA+DC,EAAE,SAAS,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,GAAG,CAAC,EAC5C,OAAO,SAAS,EAAE,SAAS,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,SACrE,EAAE,KAAG,OAAO,CAAC,OAAO,CAAC;kBA7BvB,CAAC,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,aAC/D,IAAI,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;YA+C1C,QAAQ,iBAHpB,WAAW,CAAC,OAAO,CAAC,uBAIvB,QAAQ,KACX,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;EAoBjC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { AuthData, GenericModels, GetZeroMutators
|
|
1
|
+
import type { AuthData, Can, GenericModels, GetZeroMutators } from '../types';
|
|
2
2
|
export declare function createMutators<Models extends GenericModels>({ environment, authData, createServerActions, asyncTasks, can, models, }: {
|
|
3
3
|
environment: 'server' | 'client';
|
|
4
4
|
authData: AuthData | null;
|
|
5
|
-
can:
|
|
5
|
+
can: Can;
|
|
6
6
|
models: Models;
|
|
7
7
|
asyncTasks?: Array<() => Promise<void>>;
|
|
8
8
|
createServerActions?: () => Record<string, any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createMutators.d.ts","sourceRoot":"","sources":["../../src/helpers/createMutators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EACb,eAAe,
|
|
1
|
+
{"version":3,"file":"createMutators.d.ts","sourceRoot":"","sources":["../../src/helpers/createMutators.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,GAAG,EACH,aAAa,EACb,eAAe,EAGhB,MAAM,UAAU,CAAA;AAGjB,wBAAgB,cAAc,CAAC,MAAM,SAAS,aAAa,EAAE,EAC3D,WAAW,EACX,QAAQ,EACR,mBAAmB,EACnB,UAAe,EACf,GAAG,EACH,MAAM,GACP,EAAE;IACD,WAAW,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAChC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,GAAG,EAAE,GAAG,CAAA;IACR,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;IACvC,mBAAmB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAChD,GAAG,eAAe,CAAC,MAAM,CAAC,CA6G1B"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MutatorContext } from '../types';
|
|
2
|
+
export declare const getDidRunPermissionCheck: (ctx: MutatorContext) => boolean | undefined;
|
|
3
|
+
export declare const setDidRunPermissionCheck: (ctx: MutatorContext) => WeakMap<MutatorContext, boolean>;
|
|
4
|
+
//# sourceMappingURL=didRunPermissionCheck.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"didRunPermissionCheck.d.ts","sourceRoot":"","sources":["../../src/helpers/didRunPermissionCheck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAI9C,eAAO,MAAM,wBAAwB,GAAI,KAAK,cAAc,wBAE3D,CAAA;AAED,eAAO,MAAM,wBAAwB,GAAI,KAAK,cAAc,qCAE3D,CAAA"}
|
package/types/mutations.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ type CRUDNames = 'insert' | 'upsert' | 'update' | 'delete';
|
|
|
13
13
|
type MutationsWithCRUD<Table extends GenericTable, Mutations extends MutationBuilders> = {
|
|
14
14
|
[Key in CRUDNames | keyof Mutations]: Key extends keyof Mutations ? Mutations[Key] : Key extends keyof CRUDMutations<any> ? CRUDMutations<Table>[Key] : never;
|
|
15
15
|
};
|
|
16
|
+
export declare function mutations<Mutations extends MutationBuilders>(mutations: Mutations): Mutations;
|
|
16
17
|
export declare function mutations<Table extends GenericTable, Permissions extends Where>(table: Table, permissions: Permissions): MutationsWithCRUD<Table, {}>;
|
|
17
18
|
export declare function mutations<Table extends GenericTable, Permissions extends Where, Mutations extends MutationBuilders>(table: Table, permissions: Permissions, mutations: Mutations): MutationsWithCRUD<Table, Mutations>;
|
|
18
|
-
export declare function mutations<Mutations extends MutationBuilder>(mutations: Mutations): Mutations;
|
|
19
19
|
export {};
|
|
20
20
|
//# sourceMappingURL=mutations.d.ts.map
|
package/types/mutations.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutations.d.ts","sourceRoot":"","sources":["../src/mutations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"mutations.d.ts","sourceRoot":"","sources":["../src/mutations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AAE7D,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEd,cAAc,EACd,KAAK,EACN,MAAM,SAAS,CAAA;AAMhB,KAAK,eAAe,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AACnF,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;AAevD,KAAK,YAAY,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAA;AAEhD,KAAK,aAAa,CAAC,KAAK,SAAS,YAAY,IAAI;IAC/C,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAC9C,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAC9C,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAC9C,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;CAC/C,CAAA;AAED,KAAK,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE1D,KAAK,iBAAiB,CAAC,KAAK,SAAS,YAAY,EAAE,SAAS,SAAS,gBAAgB,IAAI;KACtF,GAAG,IAAI,SAAS,GAAG,MAAM,SAAS,GAAG,GAAG,SAAS,MAAM,SAAS,GAC7D,SAAS,CAAC,GAAG,CAAC,GACd,GAAG,SAAS,MAAM,aAAa,CAAC,GAAG,CAAC,GAClC,aAAa,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GACzB,KAAK;CACZ,CAAA;AAED,wBAAgB,SAAS,CAAC,SAAS,SAAS,gBAAgB,EAC1D,SAAS,EAAE,SAAS,GACnB,SAAS,CAAA;AACZ,wBAAgB,SAAS,CAAC,KAAK,SAAS,YAAY,EAAE,WAAW,SAAS,KAAK,EAC7E,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,GACvB,iBAAiB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AAC/B,wBAAgB,SAAS,CACvB,KAAK,SAAS,YAAY,EAC1B,WAAW,SAAS,KAAK,EACzB,SAAS,SAAS,gBAAgB,EAElC,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,GACnB,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA"}
|
package/types/types.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export interface Config {
|
|
|
24
24
|
interface DefaultConfig {
|
|
25
25
|
schema: ZeroSchema;
|
|
26
26
|
authData: {};
|
|
27
|
+
serverActions: null;
|
|
27
28
|
}
|
|
28
29
|
interface FinalConfig extends Omit<DefaultConfig, keyof Config>, Config {
|
|
29
30
|
}
|
|
@@ -31,9 +32,20 @@ export type Schema = FinalConfig['schema'];
|
|
|
31
32
|
export type TableName = keyof Schema['tables'] extends string ? keyof Schema['tables'] : string;
|
|
32
33
|
export type Transaction = ZeroTransaction<Schema>;
|
|
33
34
|
export type AuthData = FinalConfig['authData'] extends Record<string, unknown> ? FinalConfig['authData'] : Record<string, unknown>;
|
|
35
|
+
export type ServerActions = FinalConfig['serverActions'] extends Record<string, unknown> ? FinalConfig['serverActions'] : Record<string, unknown>;
|
|
34
36
|
/**
|
|
35
37
|
* ➗0️⃣ END OVERRIDDEN TYPES
|
|
36
38
|
*/
|
|
39
|
+
export type MutatorContext = {
|
|
40
|
+
tx: Transaction;
|
|
41
|
+
authData: AuthData | null;
|
|
42
|
+
environment: 'server' | 'client';
|
|
43
|
+
server?: {
|
|
44
|
+
actions: ServerActions;
|
|
45
|
+
asyncTasks: Array<() => Promise<void>>;
|
|
46
|
+
};
|
|
47
|
+
can: Can;
|
|
48
|
+
};
|
|
37
49
|
export type GetZeroMutators<Models extends GenericModels> = {
|
|
38
50
|
[Key in keyof Models]: TransformMutators<GetModelMutators<Models>[Key]>;
|
|
39
51
|
};
|
|
@@ -43,28 +55,20 @@ type GetModelMutators<Models extends GenericModels> = {
|
|
|
43
55
|
export type GenericModels = {
|
|
44
56
|
[key: string]: {
|
|
45
57
|
mutate: Record<string, (ctx: MutatorContext, obj?: any) => Promise<any>>;
|
|
46
|
-
permissions
|
|
58
|
+
permissions?: Where;
|
|
47
59
|
};
|
|
48
60
|
};
|
|
49
61
|
export type TransformMutators<T> = {
|
|
50
62
|
[K in keyof T]: T[K] extends (ctx: MutatorContext, ...args: infer Args) => infer Return ? (tx: Transaction, ...args: Args) => Return extends unknown ? Promise<any> : Return : never;
|
|
51
63
|
};
|
|
52
|
-
export type
|
|
53
|
-
|
|
54
|
-
authData: AuthData | null;
|
|
55
|
-
environment: 'server' | 'client';
|
|
56
|
-
serverActions?: any;
|
|
57
|
-
asyncTasks?: Array<() => Promise<void>>;
|
|
58
|
-
can: any;
|
|
59
|
-
didCanPermissionsRun?: boolean;
|
|
60
|
-
};
|
|
64
|
+
export type Where<Table extends TableName = TableName, ReturnType = any> = (expressionBuilder: ExpressionBuilder<Schema, Table>, auth: AuthData | null) => ReturnType;
|
|
65
|
+
export type Can = <PWhere extends Where, Action extends keyof ReturnType<PWhere>>(where: PWhere, action: Action, obj: string | Record<string, unknown>) => Promise<void>;
|
|
61
66
|
export type AsyncAction = () => Promise<void>;
|
|
62
67
|
type GenericTable = TableBuilderWithColumns<any>;
|
|
63
68
|
type GetTableSchema<TS extends GenericTable> = TS extends TableBuilderWithColumns<infer S> ? S : never;
|
|
64
69
|
export type TableInsertRow<TS extends GenericTable> = NullToOptional<Row<GetTableSchema<TS>>>;
|
|
65
70
|
export type TableUpdateRow<TS extends GenericTable> = Pick<Row<GetTableSchema<TS>>, TablePrimaryKeys<TS>> & Partial<TableInsertRow<TS>>;
|
|
66
71
|
export type TablePrimaryKeys<TS extends GenericTable> = TupleToUnion<GetTableSchema<TS>['primaryKey']>;
|
|
67
|
-
export type Where<Table extends TableName = TableName, ReturnType = any> = (expressionBuilder: ExpressionBuilder<Schema, Table>, auth: AuthData | null) => ReturnType;
|
|
68
72
|
export type ZeroEvent = {
|
|
69
73
|
type: 'error';
|
|
70
74
|
message: string;
|