on-zero 0.2.10 → 0.3.0
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/cli.cjs +0 -0
- package/dist/cjs/cli.native.js +0 -0
- package/dist/cjs/createPermissions.native.js.map +1 -1
- package/dist/cjs/createSchemaFromDrizzle.cjs +30 -0
- package/dist/cjs/createSchemaFromDrizzle.native.js +33 -0
- package/dist/cjs/createSchemaFromDrizzle.native.js.map +1 -0
- package/dist/cjs/createUseQuery.cjs +1 -1
- package/dist/cjs/createUseQuery.native.js +1 -1
- package/dist/cjs/createZeroClient.cjs +1 -1
- package/dist/cjs/createZeroClient.native.js +1 -1
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/createZeroServer.native.js.map +1 -1
- package/dist/cjs/generate.cjs +64 -12
- package/dist/cjs/generate.native.js +114 -12
- package/dist/cjs/generate.native.js.map +1 -1
- package/dist/cjs/helpers/createMutators.native.js.map +1 -1
- package/dist/cjs/index.cjs +2 -1
- package/dist/cjs/index.native.js +1 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/mutations.cjs +1 -1
- package/dist/cjs/mutations.native.js +1 -1
- package/dist/cjs/mutations.native.js.map +1 -1
- package/dist/cjs/server.native.js +1 -18
- package/dist/cjs/server.native.js.map +1 -1
- package/dist/cjs/vite-plugin.cjs +1 -1
- package/dist/cjs/vite-plugin.native.js +1 -1
- package/dist/cjs/vite-plugin.native.js.map +1 -1
- package/dist/esm/cli.mjs +0 -0
- package/dist/esm/cli.native.js +0 -0
- package/dist/esm/createPermissions.mjs.map +1 -1
- package/dist/esm/createPermissions.native.js.map +1 -1
- package/dist/esm/createSchemaFromDrizzle.mjs +5 -0
- package/dist/esm/createSchemaFromDrizzle.mjs.map +1 -0
- package/dist/esm/createSchemaFromDrizzle.native.js +5 -0
- package/dist/esm/createSchemaFromDrizzle.native.js.map +1 -0
- package/dist/esm/createUseQuery.mjs +2 -2
- package/dist/esm/createUseQuery.mjs.map +1 -1
- package/dist/esm/createUseQuery.native.js +2 -2
- package/dist/esm/createUseQuery.native.js.map +1 -1
- package/dist/esm/createZeroClient.mjs +2 -2
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +2 -2
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/createZeroServer.mjs.map +1 -1
- package/dist/esm/createZeroServer.native.js.map +1 -1
- package/dist/esm/generate.mjs +64 -13
- package/dist/esm/generate.mjs.map +1 -1
- package/dist/esm/generate.native.js +114 -13
- package/dist/esm/generate.native.js.map +1 -1
- package/dist/esm/helpers/createMutators.mjs.map +1 -1
- package/dist/esm/helpers/createMutators.native.js.map +1 -1
- package/dist/esm/index.js +19 -24
- package/dist/esm/index.js.map +1 -6
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +1 -0
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/mutations.mjs +1 -1
- package/dist/esm/mutations.mjs.map +1 -1
- package/dist/esm/mutations.native.js +1 -1
- package/dist/esm/mutations.native.js.map +1 -1
- package/dist/esm/server.native.js +1 -1
- package/dist/esm/server.native.js.map +1 -1
- package/dist/esm/vite-plugin.mjs +1 -1
- package/dist/esm/vite-plugin.mjs.map +1 -1
- package/dist/esm/vite-plugin.native.js +1 -1
- package/dist/esm/vite-plugin.native.js.map +1 -1
- package/package.json +10 -4
- package/readme.md +80 -54
- package/src/createPermissions.ts +4 -9
- package/src/createSchemaFromDrizzle.ts +3 -0
- package/src/createUseQuery.tsx +4 -4
- package/src/createZeroClient.tsx +14 -14
- package/src/createZeroServer.ts +12 -12
- package/src/generate.test.ts +32 -32
- package/src/generate.ts +208 -55
- package/src/helpers/batchQuery.ts +1 -1
- package/src/helpers/createMutators.ts +7 -6
- package/src/helpers/didRunPermissionCheck.ts +1 -1
- package/src/helpers/mutatorContext.ts +2 -2
- package/src/helpers/prettyFormatZeroQuery.ts +1 -1
- package/src/helpers/queryContext.ts +1 -1
- package/src/helpers/useZeroDebug.ts +2 -2
- package/src/index.ts +2 -0
- package/src/mutations.ts +33 -7
- package/src/queryRegistry.ts +1 -1
- package/src/resolveQuery.ts +3 -3
- package/src/run.ts +5 -5
- package/src/server.native.ts +3 -0
- package/src/serverWhere.ts +2 -2
- package/src/types.ts +4 -2
- package/src/vite-plugin.ts +2 -2
- package/src/where.ts +5 -5
- package/src/zeroRunner.ts +2 -2
- package/types/createPermissions.d.ts +1 -1
- package/types/createPermissions.d.ts.map +1 -1
- package/types/createSchemaFromDrizzle.d.ts +4 -0
- package/types/createSchemaFromDrizzle.d.ts.map +1 -0
- package/types/createUseQuery.d.ts.map +1 -1
- package/types/createZeroServer.d.ts +11 -11
- package/types/generate.d.ts +29 -0
- package/types/generate.d.ts.map +1 -1
- package/types/helpers/createMutators.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/mutations.d.ts +4 -1
- package/types/mutations.d.ts.map +1 -1
- package/types/resolveQuery.d.ts +1 -1
- package/types/resolveQuery.d.ts.map +1 -1
- package/types/server.native.d.ts +1 -0
- package/types/server.native.d.ts.map +1 -0
- package/types/types.d.ts.map +1 -1
- package/dist/cjs/cli.js +0 -42
- package/dist/cjs/cli.js.map +0 -6
- package/dist/cjs/constants.js +0 -23
- package/dist/cjs/constants.js.map +0 -6
- package/dist/cjs/createPermissions.js +0 -92
- package/dist/cjs/createPermissions.js.map +0 -6
- package/dist/cjs/createUseQuery.js +0 -35
- package/dist/cjs/createUseQuery.js.map +0 -6
- package/dist/cjs/createZeroClient.js +0 -178
- package/dist/cjs/createZeroClient.js.map +0 -6
- package/dist/cjs/createZeroServer.js +0 -189
- package/dist/cjs/createZeroServer.js.map +0 -6
- package/dist/cjs/generate.js +0 -811
- package/dist/cjs/generate.js.map +0 -6
- package/dist/cjs/generate.test.js +0 -404
- package/dist/cjs/generate.test.js.map +0 -6
- package/dist/cjs/helpers/batchQuery.js +0 -41
- package/dist/cjs/helpers/batchQuery.js.map +0 -6
- package/dist/cjs/helpers/createMutators.js +0 -118
- package/dist/cjs/helpers/createMutators.js.map +0 -6
- package/dist/cjs/helpers/didRunPermissionCheck.js +0 -26
- package/dist/cjs/helpers/didRunPermissionCheck.js.map +0 -6
- package/dist/cjs/helpers/ensureLoggedIn.js +0 -25
- package/dist/cjs/helpers/ensureLoggedIn.js.map +0 -6
- package/dist/cjs/helpers/getAuth.js +0 -31
- package/dist/cjs/helpers/getAuth.js.map +0 -6
- package/dist/cjs/helpers/mutatorContext.js +0 -44
- package/dist/cjs/helpers/mutatorContext.js.map +0 -6
- package/dist/cjs/helpers/prettyFormatZeroQuery.js +0 -92
- package/dist/cjs/helpers/prettyFormatZeroQuery.js.map +0 -6
- package/dist/cjs/helpers/queryContext.js +0 -33
- package/dist/cjs/helpers/queryContext.js.map +0 -6
- package/dist/cjs/helpers/useZeroDebug.js +0 -49
- package/dist/cjs/helpers/useZeroDebug.js.map +0 -6
- package/dist/cjs/index.js +0 -40
- package/dist/cjs/index.js.map +0 -6
- package/dist/cjs/modelRegistry.js +0 -32
- package/dist/cjs/modelRegistry.js.map +0 -6
- package/dist/cjs/mutations.js +0 -70
- package/dist/cjs/mutations.js.map +0 -6
- package/dist/cjs/queryRegistry.js +0 -32
- package/dist/cjs/queryRegistry.js.map +0 -6
- package/dist/cjs/resolveQuery.js +0 -40
- package/dist/cjs/resolveQuery.js.map +0 -6
- package/dist/cjs/run.js +0 -42
- package/dist/cjs/run.js.map +0 -6
- package/dist/cjs/server.js +0 -15
- package/dist/cjs/server.js.map +0 -6
- package/dist/cjs/serverWhere.js +0 -24
- package/dist/cjs/serverWhere.js.map +0 -6
- package/dist/cjs/serverWhere.test.js +0 -52
- package/dist/cjs/serverWhere.test.js.map +0 -6
- package/dist/cjs/state.js +0 -48
- package/dist/cjs/state.js.map +0 -6
- package/dist/cjs/types.js +0 -14
- package/dist/cjs/types.js.map +0 -6
- package/dist/cjs/usePermission.test.js +0 -29
- package/dist/cjs/usePermission.test.js.map +0 -6
- package/dist/cjs/vite-plugin.js +0 -89
- package/dist/cjs/vite-plugin.js.map +0 -6
- package/dist/cjs/where.js +0 -50
- package/dist/cjs/where.js.map +0 -6
- package/dist/cjs/zeroRunner.js +0 -35
- package/dist/cjs/zeroRunner.js.map +0 -6
- package/dist/cjs/zql.js +0 -26
- package/dist/cjs/zql.js.map +0 -6
- package/dist/esm/cli.js +0 -44
- package/dist/esm/cli.js.map +0 -6
- package/dist/esm/constants.js +0 -7
- package/dist/esm/constants.js.map +0 -6
- package/dist/esm/createPermissions.js +0 -81
- package/dist/esm/createPermissions.js.map +0 -6
- package/dist/esm/createUseQuery.js +0 -22
- package/dist/esm/createUseQuery.js.map +0 -6
- package/dist/esm/createZeroClient.js +0 -185
- package/dist/esm/createZeroClient.js.map +0 -6
- package/dist/esm/createZeroServer.js +0 -192
- package/dist/esm/createZeroServer.js.map +0 -6
- package/dist/esm/generate.js +0 -789
- package/dist/esm/generate.js.map +0 -6
- package/dist/esm/generate.test.js +0 -408
- package/dist/esm/generate.test.js.map +0 -6
- package/dist/esm/helpers/batchQuery.js +0 -25
- package/dist/esm/helpers/batchQuery.js.map +0 -6
- package/dist/esm/helpers/createMutators.js +0 -96
- package/dist/esm/helpers/createMutators.js.map +0 -6
- package/dist/esm/helpers/didRunPermissionCheck.js +0 -10
- package/dist/esm/helpers/didRunPermissionCheck.js.map +0 -6
- package/dist/esm/helpers/ensureLoggedIn.js +0 -10
- package/dist/esm/helpers/ensureLoggedIn.js.map +0 -6
- package/dist/esm/helpers/getAuth.js +0 -17
- package/dist/esm/helpers/getAuth.js.map +0 -6
- package/dist/esm/helpers/mutatorContext.js +0 -28
- package/dist/esm/helpers/mutatorContext.js.map +0 -6
- package/dist/esm/helpers/prettyFormatZeroQuery.js +0 -76
- package/dist/esm/helpers/prettyFormatZeroQuery.js.map +0 -6
- package/dist/esm/helpers/queryContext.js +0 -17
- package/dist/esm/helpers/queryContext.js.map +0 -6
- package/dist/esm/helpers/useZeroDebug.js +0 -35
- package/dist/esm/helpers/useZeroDebug.js.map +0 -6
- package/dist/esm/modelRegistry.js +0 -16
- package/dist/esm/modelRegistry.js.map +0 -6
- package/dist/esm/mutations.js +0 -56
- package/dist/esm/mutations.js.map +0 -6
- package/dist/esm/queryRegistry.js +0 -16
- package/dist/esm/queryRegistry.js.map +0 -6
- package/dist/esm/resolveQuery.js +0 -24
- package/dist/esm/resolveQuery.js.map +0 -6
- package/dist/esm/run.js +0 -27
- package/dist/esm/run.js.map +0 -6
- package/dist/esm/server.js +0 -2
- package/dist/esm/server.js.map +0 -6
- package/dist/esm/serverWhere.js +0 -8
- package/dist/esm/serverWhere.js.map +0 -6
- package/dist/esm/serverWhere.test.js +0 -55
- package/dist/esm/serverWhere.test.js.map +0 -6
- package/dist/esm/state.js +0 -33
- package/dist/esm/state.js.map +0 -6
- package/dist/esm/types.js +0 -1
- package/dist/esm/types.js.map +0 -6
- package/dist/esm/usePermission.test.js +0 -33
- package/dist/esm/usePermission.test.js.map +0 -6
- package/dist/esm/vite-plugin.js +0 -74
- package/dist/esm/vite-plugin.js.map +0 -6
- package/dist/esm/where.js +0 -36
- package/dist/esm/where.js.map +0 -6
- package/dist/esm/zeroRunner.js +0 -19
- package/dist/esm/zeroRunner.js.map +0 -6
- package/dist/esm/zql.js +0 -10
- package/dist/esm/zql.js.map +0 -6
package/readme.md
CHANGED
|
@@ -18,14 +18,14 @@ it provides a few things:
|
|
|
18
18
|
|
|
19
19
|
- **generation** - cli with watch and generate commands
|
|
20
20
|
- **queries** - convert plain TS query functions into validated synced queries
|
|
21
|
-
- **mutations** - simply create CRUD
|
|
22
|
-
- **
|
|
21
|
+
- **mutations** - simply create CRUD mutations with permissions
|
|
22
|
+
- **drizzle-zero** - derive zero schema + relationships from your drizzle schema
|
|
23
23
|
- **permissions** - `serverWhere` for simple query-based permissions
|
|
24
24
|
|
|
25
25
|
plus various hooks and helpers for react integration.
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
functions that use a global `zql` builder.
|
|
27
|
+
mutations live in `mutations/` with their permissions. queries are just
|
|
28
|
+
functions that use a global `zql` builder. schema is derived from drizzle.
|
|
29
29
|
|
|
30
30
|
## queries
|
|
31
31
|
|
|
@@ -94,31 +94,21 @@ export const channelById = (props: { channelId: string }) => {
|
|
|
94
94
|
permissions execute server-side only. on the client they automatically pass. the
|
|
95
95
|
`serverWhere()` helper automatically accesses auth data via `getAuth()` so you don't need to pass it manually.
|
|
96
96
|
|
|
97
|
-
##
|
|
97
|
+
## mutations
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
mutations co-locate permissions and mutation handlers in one file. schema is
|
|
100
|
+
derived from drizzle — no need to define it here.
|
|
100
101
|
|
|
101
102
|
```ts
|
|
102
|
-
// src/data/
|
|
103
|
-
import { number, string, table } from '@rocicorp/zero'
|
|
103
|
+
// src/data/mutations/message.ts
|
|
104
104
|
import { mutations, serverWhere } from 'on-zero'
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
.columns({
|
|
108
|
-
id: string(),
|
|
109
|
-
content: string(),
|
|
110
|
-
authorId: string(),
|
|
111
|
-
channelId: string(),
|
|
112
|
-
createdAt: number(),
|
|
113
|
-
})
|
|
114
|
-
.primaryKey('id')
|
|
115
|
-
|
|
116
|
-
export const permissions = serverWhere('message', (q, auth) => {
|
|
106
|
+
const permissions = serverWhere('message', (q, auth) => {
|
|
117
107
|
return q.cmp('authorId', auth?.id || '')
|
|
118
108
|
})
|
|
119
109
|
|
|
120
|
-
//
|
|
121
|
-
export const mutate = mutations(
|
|
110
|
+
// pass table name as string — types are inferred from schema
|
|
111
|
+
export const mutate = mutations('message', permissions, {
|
|
122
112
|
async send(ctx, props: { content: string; channelId: string }) {
|
|
123
113
|
await ctx.can(permissions, props)
|
|
124
114
|
|
|
@@ -191,11 +181,11 @@ export const myChannels = () => {
|
|
|
191
181
|
}
|
|
192
182
|
```
|
|
193
183
|
|
|
194
|
-
**for mutations:** define permissions in
|
|
184
|
+
**for mutations:** define permissions in mutation files for CRUD operations:
|
|
195
185
|
|
|
196
186
|
```ts
|
|
197
|
-
// src/data/
|
|
198
|
-
|
|
187
|
+
// src/data/mutations/message.ts
|
|
188
|
+
const permissions = serverWhere('message', (q, auth) => {
|
|
199
189
|
return q.cmp('authorId', auth?.id || '')
|
|
200
190
|
})
|
|
201
191
|
```
|
|
@@ -285,7 +275,7 @@ export const channelMessages = (props: { channelId: string }) => {
|
|
|
285
275
|
|
|
286
276
|
## generation
|
|
287
277
|
|
|
288
|
-
on-zero auto-generates glue files that wire up your
|
|
278
|
+
on-zero auto-generates glue files that wire up your mutations, queries, and types.
|
|
289
279
|
|
|
290
280
|
### vite plugin (recommended)
|
|
291
281
|
|
|
@@ -306,8 +296,8 @@ export default {
|
|
|
306
296
|
**features:**
|
|
307
297
|
|
|
308
298
|
- generates on dev server start
|
|
309
|
-
- watches for
|
|
310
|
-
- enables HMR for mutations (no page reload when editing
|
|
299
|
+
- watches for mutation/query changes and regenerates
|
|
300
|
+
- enables HMR for mutations (no page reload when editing mutation files)
|
|
311
301
|
- generates before production builds
|
|
312
302
|
|
|
313
303
|
**options:**
|
|
@@ -331,11 +321,12 @@ if you prefer CLI over the vite plugin:
|
|
|
331
321
|
|
|
332
322
|
**`on-zero generate [dir]`**
|
|
333
323
|
|
|
334
|
-
generates all files needed to connect your
|
|
324
|
+
generates all files needed to connect your mutations and queries:
|
|
335
325
|
|
|
336
|
-
- `
|
|
337
|
-
|
|
338
|
-
- `
|
|
326
|
+
- `schema.ts` - zero schema derived from drizzle via drizzle-zero (tables +
|
|
327
|
+
relationships)
|
|
328
|
+
- `models.ts` - aggregates all mutation files into a single import
|
|
329
|
+
- `types.ts` - typescript types derived from the schema
|
|
339
330
|
- `syncedQueries.ts` - generates synced query definitions with valibot
|
|
340
331
|
validators
|
|
341
332
|
- `syncedMutations.ts` - generates valibot validators for mutation args
|
|
@@ -343,8 +334,8 @@ generates all files needed to connect your models and queries:
|
|
|
343
334
|
|
|
344
335
|
**options:**
|
|
345
336
|
|
|
346
|
-
- `dir` - base directory containing `
|
|
347
|
-
`src/data`)
|
|
337
|
+
- `dir` - base directory containing `mutations/` and `queries/` folders
|
|
338
|
+
(default: `src/data`)
|
|
348
339
|
- `--watch` - watch for changes and regenerate automatically
|
|
349
340
|
- `--after` - command to run after generation completes
|
|
350
341
|
|
|
@@ -367,18 +358,13 @@ bun on-zero generate --after "bun lint:fix"
|
|
|
367
358
|
**types.ts:**
|
|
368
359
|
|
|
369
360
|
```ts
|
|
370
|
-
import type {
|
|
371
|
-
import type
|
|
361
|
+
import type { Row } from '@rocicorp/zero'
|
|
362
|
+
import type { schema } from './schema'
|
|
372
363
|
|
|
373
|
-
|
|
374
|
-
export type ChannelUpdate = TableUpdateRow<typeof schema.channel>
|
|
375
|
-
```
|
|
364
|
+
type Tables = typeof schema.tables
|
|
376
365
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
```ts
|
|
380
|
-
export { schema as channel } from '~/data/models/channel'
|
|
381
|
-
export { schema as message } from '~/data/models/message'
|
|
366
|
+
export type Channel = Row<Tables['channel']>
|
|
367
|
+
export type ChannelUpdate = Partial<Channel> & Pick<Channel, 'id'>
|
|
382
368
|
```
|
|
383
369
|
|
|
384
370
|
**syncedQueries.ts:**
|
|
@@ -408,30 +394,70 @@ export const latestMessages = syncedQuery(
|
|
|
408
394
|
|
|
409
395
|
the generator:
|
|
410
396
|
|
|
411
|
-
1. scans `
|
|
397
|
+
1. scans `mutations/` for files with `export const mutate`
|
|
412
398
|
2. scans `queries/` for exported arrow functions
|
|
413
399
|
3. parses TypeScript AST to extract parameter types
|
|
414
|
-
4. converts types to valibot schemas
|
|
400
|
+
4. converts types to valibot schemas
|
|
415
401
|
5. wraps query functions in `syncedQuery()` with validators
|
|
416
402
|
6. extracts mutation handler param types using the TS type checker (resolves
|
|
417
403
|
imports, aliases, and cross-file references)
|
|
418
|
-
7. generates `syncedMutations.ts` with valibot validators for
|
|
419
|
-
mutation args
|
|
420
|
-
8. handles special cases (void params, user → userPublic mapping)
|
|
421
|
-
9. groups query imports by source file
|
|
404
|
+
7. generates `syncedMutations.ts` with valibot validators for mutation args
|
|
422
405
|
|
|
423
|
-
|
|
424
|
-
|
|
406
|
+
when using drizzle-zero integration, `schema.ts` is generated from your drizzle
|
|
407
|
+
schema using `generateDrizzleSchemaFile()` — it produces `table()` +
|
|
408
|
+
`relationships()` + `createSchema()` calls with full type inference.
|
|
425
409
|
|
|
426
410
|
exports named `permission` are automatically skipped during query generation.
|
|
427
411
|
|
|
412
|
+
### drizzle-zero integration
|
|
413
|
+
|
|
414
|
+
on-zero can derive your zero schema (tables + relationships) from a drizzle
|
|
415
|
+
schema via [drizzle-zero](https://github.com/rocicorp/drizzle-zero). this
|
|
416
|
+
eliminates duplicate column definitions — drizzle is the single source of truth.
|
|
417
|
+
|
|
418
|
+
```ts
|
|
419
|
+
// generate-schema.ts (run at build/dev time)
|
|
420
|
+
import { drizzleZeroConfig } from 'drizzle-zero'
|
|
421
|
+
import { generateDrizzleSchemaFile } from 'on-zero'
|
|
422
|
+
import * as drizzleSchema from './database/schema'
|
|
423
|
+
import { relations } from './database/relations'
|
|
424
|
+
|
|
425
|
+
const dzSchema = drizzleZeroConfig(
|
|
426
|
+
{ ...drizzleSchema, relations },
|
|
427
|
+
{
|
|
428
|
+
tables: {
|
|
429
|
+
user: true,
|
|
430
|
+
post: true,
|
|
431
|
+
comment: true,
|
|
432
|
+
},
|
|
433
|
+
suppressDefaultsWarning: true,
|
|
434
|
+
},
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
// generates a typed schema.ts with createSchema() + relationships()
|
|
438
|
+
const output = generateDrizzleSchemaFile(dzSchema)
|
|
439
|
+
writeFileSync('src/data/generated/schema.ts', output)
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
the generated file uses zero's `table()` builder and `relationships()` function,
|
|
443
|
+
giving full type inference for zql queries including nested `.related()` calls.
|
|
444
|
+
|
|
445
|
+
mutations then reference tables by name:
|
|
446
|
+
|
|
447
|
+
```ts
|
|
448
|
+
export const mutate = mutations('post', permissions, { ... })
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
the `mutations()` string overload derives insert/update/delete types from the
|
|
452
|
+
global schema type — no need to import table builders.
|
|
453
|
+
|
|
428
454
|
## setup
|
|
429
455
|
|
|
430
456
|
client:
|
|
431
457
|
|
|
432
458
|
```tsx
|
|
433
459
|
import { createZeroClient } from 'on-zero'
|
|
434
|
-
import { schema } from '~/data/schema'
|
|
460
|
+
import { schema } from '~/data/generated/schema'
|
|
435
461
|
import { models } from '~/data/generated/models'
|
|
436
462
|
import * as groupedQueries from '~/data/generated/groupedQueries'
|
|
437
463
|
|
|
@@ -551,7 +577,7 @@ export const zeroServer = createZeroServer({
|
|
|
551
577
|
this auto-validates args before every mutation runs. for a model like:
|
|
552
578
|
|
|
553
579
|
```ts
|
|
554
|
-
export const mutate = mutations(
|
|
580
|
+
export const mutate = mutations('message', permissions, {
|
|
555
581
|
async send(ctx, props: { content: string; channelId: string }) {
|
|
556
582
|
// ...
|
|
557
583
|
},
|
|
@@ -615,7 +641,7 @@ type MutatorContext = {
|
|
|
615
641
|
use it:
|
|
616
642
|
|
|
617
643
|
```ts
|
|
618
|
-
export const mutate = mutations(
|
|
644
|
+
export const mutate = mutations('message', permissions, {
|
|
619
645
|
async archive(ctx, { messageId }) {
|
|
620
646
|
await ctx.can(permissions, messageId)
|
|
621
647
|
await ctx.tx.mutate.message.update({ id: messageId, archived: true })
|
package/src/createPermissions.ts
CHANGED
|
@@ -30,12 +30,7 @@ export function createPermissions<Schema extends ZeroSchema>({
|
|
|
30
30
|
schema: Schema
|
|
31
31
|
adminRoleMode?: AdminRoleMode
|
|
32
32
|
}) {
|
|
33
|
-
type
|
|
34
|
-
|
|
35
|
-
type PermissionsWhere<Table extends TableName = TableName> = Where<
|
|
36
|
-
Table,
|
|
37
|
-
PermissionReturn
|
|
38
|
-
>
|
|
33
|
+
type PermissionsWhere<Table extends TableName = TableName> = Where<Table>
|
|
39
34
|
|
|
40
35
|
function buildPermissionQuery<PermissionWhere extends PermissionsWhere>(
|
|
41
36
|
authData: AuthData | null,
|
|
@@ -43,7 +38,7 @@ export function createPermissions<Schema extends ZeroSchema>({
|
|
|
43
38
|
permissionWhere: PermissionWhere,
|
|
44
39
|
// TODO until i can get a working PickPrimaryKeys<'message'>
|
|
45
40
|
objOrId: Record<string, any> | string,
|
|
46
|
-
tableNameOverride?: TableName
|
|
41
|
+
tableNameOverride?: TableName,
|
|
47
42
|
) {
|
|
48
43
|
// check admin bypass for queries
|
|
49
44
|
const adminBypassQueries = adminRoleMode === 'all' || adminRoleMode === 'queries'
|
|
@@ -65,7 +60,7 @@ export function createPermissions<Schema extends ZeroSchema>({
|
|
|
65
60
|
|
|
66
61
|
const primaryKeys = tableSchema.primaryKey
|
|
67
62
|
|
|
68
|
-
let permissionReturn:
|
|
63
|
+
let permissionReturn: Condition | boolean
|
|
69
64
|
try {
|
|
70
65
|
permissionReturn = permissionWhere(eb, authData)
|
|
71
66
|
} catch (err) {
|
|
@@ -120,7 +115,7 @@ export function createPermissions<Schema extends ZeroSchema>({
|
|
|
120
115
|
authData: AuthData | null,
|
|
121
116
|
tableName: TableName,
|
|
122
117
|
where: Where,
|
|
123
|
-
obj: any // TODO until i can get a working PickPrimaryKeys<'message'>
|
|
118
|
+
obj: any, // TODO until i can get a working PickPrimaryKeys<'message'>
|
|
124
119
|
): Promise<void> {
|
|
125
120
|
// check admin bypass for mutations
|
|
126
121
|
const adminBypassMutations = adminRoleMode === 'all' || adminRoleMode === 'mutations'
|
package/src/createUseQuery.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useQuery as zeroUseQuery } from '@rocicorp/zero/react'
|
|
2
|
-
import {
|
|
2
|
+
import { useContext, useMemo, useRef, type Context } from 'react'
|
|
3
3
|
|
|
4
4
|
import { useZeroDebug } from './helpers/useZeroDebug'
|
|
5
5
|
import { resolveQuery, type PlainQueryFn } from './resolveQuery'
|
|
@@ -29,13 +29,13 @@ export type UseQueryHook<Schema extends ZeroSchema> = {
|
|
|
29
29
|
<TArg, TTable extends keyof Schema['tables'] & string, TReturn>(
|
|
30
30
|
fn: PlainQueryFn<TArg, Query<TTable, Schema, TReturn>>,
|
|
31
31
|
params: TArg,
|
|
32
|
-
options?: UseQueryOptions | boolean
|
|
32
|
+
options?: UseQueryOptions | boolean,
|
|
33
33
|
): QueryResult<TReturn>;
|
|
34
34
|
|
|
35
35
|
// overload 2: plain function with no params
|
|
36
36
|
<TTable extends keyof Schema['tables'] & string, TReturn>(
|
|
37
37
|
fn: PlainQueryFn<void, Query<TTable, Schema, TReturn>>,
|
|
38
|
-
options?: UseQueryOptions | boolean
|
|
38
|
+
options?: UseQueryOptions | boolean,
|
|
39
39
|
): QueryResult<TReturn>
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -49,7 +49,7 @@ export function createUseQuery<Schema extends ZeroSchema>({
|
|
|
49
49
|
customQueries: AnyQueryRegistry
|
|
50
50
|
}): UseQueryHook<Schema> {
|
|
51
51
|
function useQuery(...args: any[]): any {
|
|
52
|
-
const disableMode =
|
|
52
|
+
const disableMode = useContext(DisabledContext)
|
|
53
53
|
const lastRef = useRef<any>(EMPTY_RESPONSE)
|
|
54
54
|
const [fn, paramsOrOptions, optionsArg] = args
|
|
55
55
|
|
package/src/createZeroClient.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { createEmitter } from '@take-out/helpers'
|
|
|
4
4
|
import {
|
|
5
5
|
createContext,
|
|
6
6
|
memo,
|
|
7
|
-
|
|
7
|
+
useContext,
|
|
8
8
|
useEffect,
|
|
9
9
|
useMemo,
|
|
10
10
|
useRef,
|
|
@@ -81,7 +81,7 @@ export function createZeroClient<
|
|
|
81
81
|
registerQuery(fn, `${namespace}.${name}`)
|
|
82
82
|
// wrap each plain function in defineQuery
|
|
83
83
|
wrappedNamespaces[namespace][name] = defineQuery(({ args }: { args: any }) =>
|
|
84
|
-
fn(args)
|
|
84
|
+
fn(args),
|
|
85
85
|
)
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -116,7 +116,7 @@ export function createZeroClient<
|
|
|
116
116
|
eb,
|
|
117
117
|
rawPerm || ((e: any) => e.and()),
|
|
118
118
|
args.objOrId,
|
|
119
|
-
table
|
|
119
|
+
table,
|
|
120
120
|
)
|
|
121
121
|
} finally {
|
|
122
122
|
setEvaluatingPermission(false)
|
|
@@ -140,7 +140,7 @@ export function createZeroClient<
|
|
|
140
140
|
eb,
|
|
141
141
|
perm || ((e: any) => e.and()),
|
|
142
142
|
args.objOrId,
|
|
143
|
-
table
|
|
143
|
+
table,
|
|
144
144
|
)
|
|
145
145
|
})
|
|
146
146
|
.one()
|
|
@@ -172,7 +172,7 @@ export function createZeroClient<
|
|
|
172
172
|
get(_, key) {
|
|
173
173
|
if (latestZeroInstance === null) {
|
|
174
174
|
throw new Error(
|
|
175
|
-
`Zero instance not initialized. Ensure ZeroProvider is mounted before accessing 'zero'
|
|
175
|
+
`Zero instance not initialized. Ensure ZeroProvider is mounted before accessing 'zero'.`,
|
|
176
176
|
)
|
|
177
177
|
}
|
|
178
178
|
return Reflect.get(latestZeroInstance, key, latestZeroInstance)
|
|
@@ -194,9 +194,9 @@ export function createZeroClient<
|
|
|
194
194
|
table: TableName | (string & {}),
|
|
195
195
|
objOrId: string | Partial<Row<any>> | undefined,
|
|
196
196
|
enabled = typeof objOrId !== 'undefined',
|
|
197
|
-
debug = false
|
|
197
|
+
debug = false,
|
|
198
198
|
): boolean | null {
|
|
199
|
-
const disableMode =
|
|
199
|
+
const disableMode = useContext(DisabledContext)
|
|
200
200
|
const lastRef = useRef<boolean | null>(null)
|
|
201
201
|
const tableStr = table as string
|
|
202
202
|
const checkFn = permissionCheckFns[tableStr]
|
|
@@ -209,7 +209,7 @@ export function createZeroClient<
|
|
|
209
209
|
const [data, status] = useQuery(
|
|
210
210
|
checkFn as any,
|
|
211
211
|
{ objOrId: objOrId as any, _uid },
|
|
212
|
-
{ enabled: Boolean(!disableMode && enabled && objOrId && checkFn) }
|
|
212
|
+
{ enabled: Boolean(!disableMode && enabled && objOrId && checkFn) },
|
|
213
213
|
)
|
|
214
214
|
|
|
215
215
|
if (debug) {
|
|
@@ -327,7 +327,7 @@ export function createZeroClient<
|
|
|
327
327
|
}, [state, zeroEvents])
|
|
328
328
|
|
|
329
329
|
return null
|
|
330
|
-
}
|
|
330
|
+
},
|
|
331
331
|
)
|
|
332
332
|
|
|
333
333
|
// preload data for a query into cache without materializing
|
|
@@ -335,16 +335,16 @@ export function createZeroClient<
|
|
|
335
335
|
function preload<TArg, TTable extends keyof Schema['tables'] & string, TReturn>(
|
|
336
336
|
fn: PlainQueryFn<TArg, Query<TTable, Schema, TReturn>>,
|
|
337
337
|
params: TArg,
|
|
338
|
-
options?: PreloadOptions
|
|
338
|
+
options?: PreloadOptions,
|
|
339
339
|
): { cleanup: () => void; complete: Promise<void> }
|
|
340
340
|
function preload<TTable extends keyof Schema['tables'] & string, TReturn>(
|
|
341
341
|
fn: PlainQueryFn<void, Query<TTable, Schema, TReturn>>,
|
|
342
|
-
options?: PreloadOptions
|
|
342
|
+
options?: PreloadOptions,
|
|
343
343
|
): { cleanup: () => void; complete: Promise<void> }
|
|
344
344
|
function preload(
|
|
345
345
|
fnArg: any,
|
|
346
346
|
paramsOrOptions?: any,
|
|
347
|
-
optionsArg?: PreloadOptions
|
|
347
|
+
optionsArg?: PreloadOptions,
|
|
348
348
|
): { cleanup: () => void; complete: Promise<void> } {
|
|
349
349
|
const hasParams =
|
|
350
350
|
optionsArg !== undefined || (paramsOrOptions && !('ttl' in paramsOrOptions))
|
|
@@ -357,10 +357,10 @@ export function createZeroClient<
|
|
|
357
357
|
|
|
358
358
|
function getQuery<TArg, TTable extends keyof Schema['tables'] & string, TReturn>(
|
|
359
359
|
fn: PlainQueryFn<TArg, Query<TTable, Schema, TReturn>>,
|
|
360
|
-
params: TArg
|
|
360
|
+
params: TArg,
|
|
361
361
|
): ReturnType<typeof resolveQuery<Schema>>
|
|
362
362
|
function getQuery<TTable extends keyof Schema['tables'] & string, TReturn>(
|
|
363
|
-
fn: PlainQueryFn<void, Query<TTable, Schema, TReturn
|
|
363
|
+
fn: PlainQueryFn<void, Query<TTable, Schema, TReturn>>,
|
|
364
364
|
): ReturnType<typeof resolveQuery<Schema>>
|
|
365
365
|
function getQuery(fn: any, params?: any) {
|
|
366
366
|
return resolveQuery({ customQueries, fn, params })
|
package/src/createZeroServer.ts
CHANGED
|
@@ -48,7 +48,7 @@ type ServerMutate<Models extends GenericModels> = {
|
|
|
48
48
|
[Key in keyof Models]: {
|
|
49
49
|
[K in keyof Models[Key]['mutate']]: Models[Key]['mutate'][K] extends (
|
|
50
50
|
ctx: MutatorContext,
|
|
51
|
-
arg: infer Arg
|
|
51
|
+
arg: infer Arg,
|
|
52
52
|
) => any
|
|
53
53
|
? (arg: Arg, options?: MutateOptions) => Promise<void>
|
|
54
54
|
: (options?: MutateOptions) => Promise<void>
|
|
@@ -197,9 +197,9 @@ export function createZeroServer<
|
|
|
197
197
|
// now finish
|
|
198
198
|
if (!skipAsyncTasks && asyncTasks.length) {
|
|
199
199
|
Promise.all(asyncTasks.map((task) => runWithAuthScope(authData, task))).catch(
|
|
200
|
-
(err) => {
|
|
200
|
+
(err: unknown) => {
|
|
201
201
|
console.error(`[push] async tasks failed`, err)
|
|
202
|
-
}
|
|
202
|
+
},
|
|
203
203
|
)
|
|
204
204
|
}
|
|
205
205
|
|
|
@@ -219,7 +219,7 @@ export function createZeroServer<
|
|
|
219
219
|
if (!queries) {
|
|
220
220
|
throw new Error(
|
|
221
221
|
'No queries registered with createZeroServer. ' +
|
|
222
|
-
'Pass the syncedQueries registry to createZeroServer via the queries option.'
|
|
222
|
+
'Pass the syncedQueries registry to createZeroServer via the queries option.',
|
|
223
223
|
)
|
|
224
224
|
}
|
|
225
225
|
|
|
@@ -249,7 +249,7 @@ export function createZeroServer<
|
|
|
249
249
|
eb,
|
|
250
250
|
perm,
|
|
251
251
|
objOrId,
|
|
252
|
-
table
|
|
252
|
+
table,
|
|
253
253
|
)
|
|
254
254
|
})
|
|
255
255
|
.one()
|
|
@@ -267,8 +267,8 @@ export function createZeroServer<
|
|
|
267
267
|
return query.fn({ args, ctx: authData })
|
|
268
268
|
},
|
|
269
269
|
schema,
|
|
270
|
-
request
|
|
271
|
-
)
|
|
270
|
+
request,
|
|
271
|
+
),
|
|
272
272
|
)
|
|
273
273
|
|
|
274
274
|
return {
|
|
@@ -280,7 +280,7 @@ export function createZeroServer<
|
|
|
280
280
|
modelName: string,
|
|
281
281
|
mutatorName: string,
|
|
282
282
|
mutatorArg: unknown,
|
|
283
|
-
options?: MutateOptions
|
|
283
|
+
options?: MutateOptions,
|
|
284
284
|
) {
|
|
285
285
|
let authData = options?.authData
|
|
286
286
|
|
|
@@ -321,12 +321,12 @@ export function createZeroServer<
|
|
|
321
321
|
if (asyncTasks.length) {
|
|
322
322
|
const resolvedAuth = authData ?? null
|
|
323
323
|
const promise = Promise.all(
|
|
324
|
-
asyncTasks.map((t) => runWithAuthScope(resolvedAuth, t))
|
|
324
|
+
asyncTasks.map((t) => runWithAuthScope(resolvedAuth, t)),
|
|
325
325
|
)
|
|
326
326
|
if (options?.awaitEffects) {
|
|
327
327
|
await promise
|
|
328
328
|
} else {
|
|
329
|
-
promise.catch((err) => {
|
|
329
|
+
promise.catch((err: unknown) => {
|
|
330
330
|
console.error(`[mutate] async tasks failed`, err)
|
|
331
331
|
})
|
|
332
332
|
}
|
|
@@ -343,7 +343,7 @@ export function createZeroServer<
|
|
|
343
343
|
return (arg: unknown, options?: MutateOptions) =>
|
|
344
344
|
runMutate(modelName, mutatorName, arg, options)
|
|
345
345
|
},
|
|
346
|
-
}
|
|
346
|
+
},
|
|
347
347
|
)
|
|
348
348
|
},
|
|
349
349
|
})
|
|
@@ -370,7 +370,7 @@ export function createZeroServer<
|
|
|
370
370
|
|
|
371
371
|
function query<R>(
|
|
372
372
|
cb: (q: QueryBuilder) => Query<any, Schema, R>,
|
|
373
|
-
authData?: AuthData | null
|
|
373
|
+
authData?: AuthData | null,
|
|
374
374
|
): Promise<HumanReadable<R>> {
|
|
375
375
|
const run = () =>
|
|
376
376
|
transaction(async (tx) => {
|