on-zero 0.0.1
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/LICENSE +21 -0
- package/cli.cjs +3 -0
- package/dist/cjs/cli.cjs +405 -0
- package/dist/cjs/cli.js +397 -0
- package/dist/cjs/cli.js.map +6 -0
- package/dist/cjs/cli.native.js +505 -0
- package/dist/cjs/cli.native.js.map +1 -0
- package/dist/cjs/constants.cjs +28 -0
- package/dist/cjs/constants.js +22 -0
- package/dist/cjs/constants.js.map +6 -0
- package/dist/cjs/constants.native.js +31 -0
- package/dist/cjs/constants.native.js.map +1 -0
- package/dist/cjs/createPermissions.cjs +82 -0
- package/dist/cjs/createPermissions.js +77 -0
- package/dist/cjs/createPermissions.js.map +6 -0
- package/dist/cjs/createPermissions.native.js +107 -0
- package/dist/cjs/createPermissions.native.js.map +1 -0
- package/dist/cjs/createUseQuery.cjs +59 -0
- package/dist/cjs/createUseQuery.js +34 -0
- package/dist/cjs/createUseQuery.js.map +6 -0
- package/dist/cjs/createUseQuery.native.js +70 -0
- package/dist/cjs/createUseQuery.native.js.map +1 -0
- package/dist/cjs/createZeroClient.cjs +162 -0
- package/dist/cjs/createZeroClient.js +126 -0
- package/dist/cjs/createZeroClient.js.map +6 -0
- package/dist/cjs/createZeroClient.native.js +214 -0
- package/dist/cjs/createZeroClient.native.js.map +1 -0
- package/dist/cjs/createZeroServer.cjs +148 -0
- package/dist/cjs/createZeroServer.js +126 -0
- package/dist/cjs/createZeroServer.js.map +6 -0
- package/dist/cjs/createZeroServer.native.js +170 -0
- package/dist/cjs/createZeroServer.native.js.map +1 -0
- package/dist/cjs/helpers/batchQuery.cjs +49 -0
- package/dist/cjs/helpers/batchQuery.js +38 -0
- package/dist/cjs/helpers/batchQuery.js.map +6 -0
- package/dist/cjs/helpers/batchQuery.native.js +49 -0
- package/dist/cjs/helpers/batchQuery.native.js.map +1 -0
- package/dist/cjs/helpers/createMutators.cjs +90 -0
- package/dist/cjs/helpers/createMutators.js +85 -0
- package/dist/cjs/helpers/createMutators.js.map +6 -0
- package/dist/cjs/helpers/createMutators.native.js +132 -0
- package/dist/cjs/helpers/createMutators.native.js.map +1 -0
- package/dist/cjs/helpers/didRunPermissionCheck.cjs +30 -0
- package/dist/cjs/helpers/didRunPermissionCheck.js +26 -0
- package/dist/cjs/helpers/didRunPermissionCheck.js.map +6 -0
- package/dist/cjs/helpers/didRunPermissionCheck.native.js +39 -0
- package/dist/cjs/helpers/didRunPermissionCheck.native.js.map +1 -0
- package/dist/cjs/helpers/ensureLoggedIn.cjs +33 -0
- package/dist/cjs/helpers/ensureLoggedIn.js +25 -0
- package/dist/cjs/helpers/ensureLoggedIn.js.map +6 -0
- package/dist/cjs/helpers/ensureLoggedIn.native.js +36 -0
- package/dist/cjs/helpers/ensureLoggedIn.native.js.map +1 -0
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.cjs +30 -0
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.js +24 -0
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.js.map +6 -0
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.native.js +33 -0
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.native.js.map +1 -0
- package/dist/cjs/helpers/mutatorContext.cjs +40 -0
- package/dist/cjs/helpers/mutatorContext.js +36 -0
- package/dist/cjs/helpers/mutatorContext.js.map +6 -0
- package/dist/cjs/helpers/mutatorContext.native.js +43 -0
- package/dist/cjs/helpers/mutatorContext.native.js.map +1 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.cjs +107 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.js +92 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.js.map +6 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.native.js +119 -0
- package/dist/cjs/helpers/prettyFormatZeroQuery.native.js.map +1 -0
- package/dist/cjs/helpers/useZeroDebug.cjs +68 -0
- package/dist/cjs/helpers/useZeroDebug.js +49 -0
- package/dist/cjs/helpers/useZeroDebug.js.map +6 -0
- package/dist/cjs/helpers/useZeroDebug.native.js +81 -0
- package/dist/cjs/helpers/useZeroDebug.native.js.map +1 -0
- package/dist/cjs/index.cjs +42 -0
- package/dist/cjs/index.js +35 -0
- package/dist/cjs/index.js.map +6 -0
- package/dist/cjs/index.native.js +45 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/cjs/mutations.cjs +51 -0
- package/dist/cjs/mutations.js +44 -0
- package/dist/cjs/mutations.js.map +6 -0
- package/dist/cjs/mutations.native.js +56 -0
- package/dist/cjs/mutations.native.js.map +1 -0
- package/dist/cjs/queryRegistry.cjs +33 -0
- package/dist/cjs/queryRegistry.js +28 -0
- package/dist/cjs/queryRegistry.js.map +6 -0
- package/dist/cjs/queryRegistry.native.js +36 -0
- package/dist/cjs/queryRegistry.native.js.map +1 -0
- package/dist/cjs/resolveQuery.cjs +41 -0
- package/dist/cjs/resolveQuery.js +40 -0
- package/dist/cjs/resolveQuery.js.map +6 -0
- package/dist/cjs/resolveQuery.native.js +46 -0
- package/dist/cjs/resolveQuery.native.js.map +1 -0
- package/dist/cjs/run.cjs +48 -0
- package/dist/cjs/run.js +37 -0
- package/dist/cjs/run.js.map +6 -0
- package/dist/cjs/run.native.js +52 -0
- package/dist/cjs/run.native.js.map +1 -0
- package/dist/cjs/server.cjs +18 -0
- package/dist/cjs/server.js +15 -0
- package/dist/cjs/server.js.map +6 -0
- package/dist/cjs/server.native.js +21 -0
- package/dist/cjs/server.native.js.map +1 -0
- package/dist/cjs/serverWhere.cjs +29 -0
- package/dist/cjs/serverWhere.js +24 -0
- package/dist/cjs/serverWhere.js.map +6 -0
- package/dist/cjs/serverWhere.native.js +32 -0
- package/dist/cjs/serverWhere.native.js.map +1 -0
- package/dist/cjs/state.cjs +49 -0
- package/dist/cjs/state.js +37 -0
- package/dist/cjs/state.js.map +6 -0
- package/dist/cjs/state.native.js +54 -0
- package/dist/cjs/state.native.js.map +1 -0
- package/dist/cjs/types.cjs +16 -0
- package/dist/cjs/types.js +14 -0
- package/dist/cjs/types.js.map +6 -0
- package/dist/cjs/types.native.js +19 -0
- package/dist/cjs/types.native.js.map +1 -0
- package/dist/cjs/where.cjs +41 -0
- package/dist/cjs/where.js +35 -0
- package/dist/cjs/where.js.map +6 -0
- package/dist/cjs/where.native.js +46 -0
- package/dist/cjs/where.native.js.map +1 -0
- package/dist/cjs/zeroRunner.cjs +34 -0
- package/dist/cjs/zeroRunner.js +32 -0
- package/dist/cjs/zeroRunner.js.map +6 -0
- package/dist/cjs/zeroRunner.native.js +37 -0
- package/dist/cjs/zeroRunner.native.js.map +1 -0
- package/dist/cjs/zql.cjs +31 -0
- package/dist/cjs/zql.js +26 -0
- package/dist/cjs/zql.js.map +6 -0
- package/dist/cjs/zql.native.js +35 -0
- package/dist/cjs/zql.native.js.map +1 -0
- package/dist/esm/cli.js +383 -0
- package/dist/esm/cli.js.map +6 -0
- package/dist/esm/cli.mjs +384 -0
- package/dist/esm/cli.mjs.map +1 -0
- package/dist/esm/cli.native.js +481 -0
- package/dist/esm/cli.native.js.map +1 -0
- package/dist/esm/constants.js +6 -0
- package/dist/esm/constants.js.map +6 -0
- package/dist/esm/constants.mjs +4 -0
- package/dist/esm/constants.mjs.map +1 -0
- package/dist/esm/constants.native.js +4 -0
- package/dist/esm/constants.native.js.map +1 -0
- package/dist/esm/createPermissions.js +66 -0
- package/dist/esm/createPermissions.js.map +6 -0
- package/dist/esm/createPermissions.mjs +59 -0
- package/dist/esm/createPermissions.mjs.map +1 -0
- package/dist/esm/createPermissions.native.js +81 -0
- package/dist/esm/createPermissions.native.js.map +1 -0
- package/dist/esm/createUseQuery.js +21 -0
- package/dist/esm/createUseQuery.js.map +6 -0
- package/dist/esm/createUseQuery.mjs +36 -0
- package/dist/esm/createUseQuery.mjs.map +1 -0
- package/dist/esm/createUseQuery.native.js +44 -0
- package/dist/esm/createUseQuery.native.js.map +1 -0
- package/dist/esm/createZeroClient.js +135 -0
- package/dist/esm/createZeroClient.js.map +6 -0
- package/dist/esm/createZeroClient.mjs +139 -0
- package/dist/esm/createZeroClient.mjs.map +1 -0
- package/dist/esm/createZeroClient.native.js +188 -0
- package/dist/esm/createZeroClient.native.js.map +1 -0
- package/dist/esm/createZeroServer.js +121 -0
- package/dist/esm/createZeroServer.js.map +6 -0
- package/dist/esm/createZeroServer.mjs +125 -0
- package/dist/esm/createZeroServer.mjs.map +1 -0
- package/dist/esm/createZeroServer.native.js +144 -0
- package/dist/esm/createZeroServer.native.js.map +1 -0
- package/dist/esm/helpers/batchQuery.js +22 -0
- package/dist/esm/helpers/batchQuery.js.map +6 -0
- package/dist/esm/helpers/batchQuery.mjs +26 -0
- package/dist/esm/helpers/batchQuery.mjs.map +1 -0
- package/dist/esm/helpers/batchQuery.native.js +23 -0
- package/dist/esm/helpers/batchQuery.native.js.map +1 -0
- package/dist/esm/helpers/createMutators.js +71 -0
- package/dist/esm/helpers/createMutators.js.map +6 -0
- package/dist/esm/helpers/createMutators.mjs +67 -0
- package/dist/esm/helpers/createMutators.mjs.map +1 -0
- package/dist/esm/helpers/createMutators.native.js +106 -0
- package/dist/esm/helpers/createMutators.native.js.map +1 -0
- package/dist/esm/helpers/didRunPermissionCheck.js +10 -0
- package/dist/esm/helpers/didRunPermissionCheck.js.map +6 -0
- package/dist/esm/helpers/didRunPermissionCheck.mjs +6 -0
- package/dist/esm/helpers/didRunPermissionCheck.mjs.map +1 -0
- package/dist/esm/helpers/didRunPermissionCheck.native.js +12 -0
- package/dist/esm/helpers/didRunPermissionCheck.native.js.map +1 -0
- package/dist/esm/helpers/ensureLoggedIn.js +10 -0
- package/dist/esm/helpers/ensureLoggedIn.js.map +6 -0
- package/dist/esm/helpers/ensureLoggedIn.mjs +10 -0
- package/dist/esm/helpers/ensureLoggedIn.mjs.map +1 -0
- package/dist/esm/helpers/ensureLoggedIn.native.js +10 -0
- package/dist/esm/helpers/ensureLoggedIn.native.js.map +1 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.js +9 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.js.map +6 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.mjs +7 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.mjs.map +1 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.native.js +7 -0
- package/dist/esm/helpers/getQueryOrMutatorAuthData.native.js.map +1 -0
- package/dist/esm/helpers/mutatorContext.js +20 -0
- package/dist/esm/helpers/mutatorContext.js.map +6 -0
- package/dist/esm/helpers/mutatorContext.mjs +15 -0
- package/dist/esm/helpers/mutatorContext.mjs.map +1 -0
- package/dist/esm/helpers/mutatorContext.native.js +15 -0
- package/dist/esm/helpers/mutatorContext.native.js.map +1 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.js +76 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.js.map +6 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.mjs +84 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.mjs.map +1 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.native.js +93 -0
- package/dist/esm/helpers/prettyFormatZeroQuery.native.js.map +1 -0
- package/dist/esm/helpers/useZeroDebug.js +35 -0
- package/dist/esm/helpers/useZeroDebug.js.map +6 -0
- package/dist/esm/helpers/useZeroDebug.mjs +45 -0
- package/dist/esm/helpers/useZeroDebug.mjs.map +1 -0
- package/dist/esm/helpers/useZeroDebug.native.js +55 -0
- package/dist/esm/helpers/useZeroDebug.native.js.map +1 -0
- package/dist/esm/index.js +20 -0
- package/dist/esm/index.js.map +6 -0
- package/dist/esm/index.mjs +17 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/index.native.js +17 -0
- package/dist/esm/index.native.js.map +1 -0
- package/dist/esm/mutations.js +28 -0
- package/dist/esm/mutations.js.map +6 -0
- package/dist/esm/mutations.mjs +28 -0
- package/dist/esm/mutations.mjs.map +1 -0
- package/dist/esm/mutations.native.js +30 -0
- package/dist/esm/mutations.native.js.map +1 -0
- package/dist/esm/queryRegistry.js +12 -0
- package/dist/esm/queryRegistry.js.map +6 -0
- package/dist/esm/queryRegistry.mjs +9 -0
- package/dist/esm/queryRegistry.mjs.map +1 -0
- package/dist/esm/queryRegistry.native.js +9 -0
- package/dist/esm/queryRegistry.native.js.map +1 -0
- package/dist/esm/resolveQuery.js +24 -0
- package/dist/esm/resolveQuery.js.map +6 -0
- package/dist/esm/resolveQuery.mjs +18 -0
- package/dist/esm/resolveQuery.mjs.map +1 -0
- package/dist/esm/resolveQuery.native.js +20 -0
- package/dist/esm/resolveQuery.native.js.map +1 -0
- package/dist/esm/run.js +22 -0
- package/dist/esm/run.js.map +6 -0
- package/dist/esm/run.mjs +24 -0
- package/dist/esm/run.mjs.map +1 -0
- package/dist/esm/run.native.js +25 -0
- package/dist/esm/run.native.js.map +1 -0
- package/dist/esm/server.js +2 -0
- package/dist/esm/server.js.map +6 -0
- package/dist/esm/server.mjs +2 -0
- package/dist/esm/server.mjs.map +1 -0
- package/dist/esm/server.native.js +2 -0
- package/dist/esm/server.native.js.map +1 -0
- package/dist/esm/serverWhere.js +8 -0
- package/dist/esm/serverWhere.js.map +6 -0
- package/dist/esm/serverWhere.mjs +6 -0
- package/dist/esm/serverWhere.mjs.map +1 -0
- package/dist/esm/serverWhere.native.js +6 -0
- package/dist/esm/serverWhere.native.js.map +1 -0
- package/dist/esm/state.js +21 -0
- package/dist/esm/state.js.map +6 -0
- package/dist/esm/state.mjs +22 -0
- package/dist/esm/state.mjs.map +1 -0
- package/dist/esm/state.native.js +24 -0
- package/dist/esm/state.native.js.map +1 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/types.js.map +6 -0
- package/dist/esm/types.mjs +2 -0
- package/dist/esm/types.mjs.map +1 -0
- package/dist/esm/types.native.js +2 -0
- package/dist/esm/types.native.js.map +1 -0
- package/dist/esm/where.js +20 -0
- package/dist/esm/where.js.map +6 -0
- package/dist/esm/where.mjs +17 -0
- package/dist/esm/where.mjs.map +1 -0
- package/dist/esm/where.native.js +19 -0
- package/dist/esm/where.native.js.map +1 -0
- package/dist/esm/zeroRunner.js +16 -0
- package/dist/esm/zeroRunner.js.map +6 -0
- package/dist/esm/zeroRunner.mjs +10 -0
- package/dist/esm/zeroRunner.mjs.map +1 -0
- package/dist/esm/zeroRunner.native.js +10 -0
- package/dist/esm/zeroRunner.native.js.map +1 -0
- package/dist/esm/zql.js +10 -0
- package/dist/esm/zql.js.map +6 -0
- package/dist/esm/zql.mjs +8 -0
- package/dist/esm/zql.mjs.map +1 -0
- package/dist/esm/zql.native.js +9 -0
- package/dist/esm/zql.native.js.map +1 -0
- package/package.json +98 -0
- package/readme.md +594 -0
- package/src/cli.ts +626 -0
- package/src/constants.native.ts +3 -0
- package/src/constants.ts +3 -0
- package/src/createPermissions.ts +131 -0
- package/src/createUseQuery.tsx +82 -0
- package/src/createZeroClient.tsx +301 -0
- package/src/createZeroServer.ts +226 -0
- package/src/helpers/batchQuery.ts +46 -0
- package/src/helpers/createMutators.ts +138 -0
- package/src/helpers/didRunPermissionCheck.ts +16 -0
- package/src/helpers/ensureLoggedIn.ts +11 -0
- package/src/helpers/getQueryOrMutatorAuthData.ts +12 -0
- package/src/helpers/mutatorContext.ts +25 -0
- package/src/helpers/prettyFormatZeroQuery.ts +167 -0
- package/src/helpers/useZeroDebug.ts +102 -0
- package/src/index.ts +18 -0
- package/src/mutations.ts +133 -0
- package/src/queryRegistry.ts +12 -0
- package/src/resolveQuery.ts +44 -0
- package/src/run.ts +62 -0
- package/src/server.ts +1 -0
- package/src/serverWhere.ts +21 -0
- package/src/state.ts +32 -0
- package/src/types.ts +136 -0
- package/src/where.ts +58 -0
- package/src/zeroRunner.ts +28 -0
- package/src/zql.ts +10 -0
- package/types/cli.d.ts +3 -0
- package/types/cli.d.ts.map +1 -0
- package/types/constants.d.ts +3 -0
- package/types/constants.d.ts.map +1 -0
- package/types/constants.native.d.ts +3 -0
- package/types/constants.native.d.ts.map +1 -0
- package/types/createPermissions.d.ts +10 -0
- package/types/createPermissions.d.ts.map +1 -0
- package/types/createUseQuery.d.ts +20 -0
- package/types/createUseQuery.d.ts.map +1 -0
- package/types/createZeroClient.d.ts +35 -0
- package/types/createZeroClient.d.ts.map +1 -0
- package/types/createZeroServer.d.ts +146 -0
- package/types/createZeroServer.d.ts.map +1 -0
- package/types/helpers/batchQuery.d.ts +7 -0
- package/types/helpers/batchQuery.d.ts.map +1 -0
- package/types/helpers/createMutators.d.ts +10 -0
- package/types/helpers/createMutators.d.ts.map +1 -0
- package/types/helpers/didRunPermissionCheck.d.ts +4 -0
- package/types/helpers/didRunPermissionCheck.d.ts.map +1 -0
- package/types/helpers/ensureLoggedIn.d.ts +3 -0
- package/types/helpers/ensureLoggedIn.d.ts.map +1 -0
- package/types/helpers/getQueryOrMutatorAuthData.d.ts +3 -0
- package/types/helpers/getQueryOrMutatorAuthData.d.ts.map +1 -0
- package/types/helpers/mutatorContext.d.ts +5 -0
- package/types/helpers/mutatorContext.d.ts.map +1 -0
- package/types/helpers/prettyFormatZeroQuery.d.ts +3 -0
- package/types/helpers/prettyFormatZeroQuery.d.ts.map +1 -0
- package/types/helpers/useZeroDebug.d.ts +3 -0
- package/types/helpers/useZeroDebug.d.ts.map +1 -0
- package/types/index.d.ts +17 -0
- package/types/index.d.ts.map +1 -0
- package/types/mutations.d.ts +20 -0
- package/types/mutations.d.ts.map +1 -0
- package/types/queryRegistry.d.ts +3 -0
- package/types/queryRegistry.d.ts.map +1 -0
- package/types/resolveQuery.d.ts +11 -0
- package/types/resolveQuery.d.ts.map +1 -0
- package/types/run.d.ts +7 -0
- package/types/run.d.ts.map +1 -0
- package/types/server.d.ts +2 -0
- package/types/server.d.ts.map +1 -0
- package/types/serverWhere.d.ts +5 -0
- package/types/serverWhere.d.ts.map +1 -0
- package/types/state.d.ts +8 -0
- package/types/state.d.ts.map +1 -0
- package/types/types.d.ts +78 -0
- package/types/types.d.ts.map +1 -0
- package/types/where.d.ts +6 -0
- package/types/where.d.ts.map +1 -0
- package/types/zeroRunner.d.ts +6 -0
- package/types/zeroRunner.d.ts.map +1 -0
- package/types/zql.d.ts +3 -0
- package/types/zql.d.ts.map +1 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { ensure, EnsureError } from '@take-out/helpers'
|
|
2
|
+
|
|
3
|
+
import { setDidRunPermissionCheck } from './helpers/didRunPermissionCheck'
|
|
4
|
+
import { mutatorContext } from './helpers/mutatorContext'
|
|
5
|
+
import { prettyFormatZeroQuery } from './helpers/prettyFormatZeroQuery'
|
|
6
|
+
import { getZQL } from './state'
|
|
7
|
+
import { getWhereTableName } from './where'
|
|
8
|
+
|
|
9
|
+
import type { AuthData, Can, TableName, Transaction, Where } from './types'
|
|
10
|
+
import type {
|
|
11
|
+
Condition,
|
|
12
|
+
ExpressionBuilder,
|
|
13
|
+
Query,
|
|
14
|
+
Schema as ZeroSchema,
|
|
15
|
+
} from '@rocicorp/zero'
|
|
16
|
+
|
|
17
|
+
export function createPermissions<Schema extends ZeroSchema>({
|
|
18
|
+
environment,
|
|
19
|
+
schema,
|
|
20
|
+
}: {
|
|
21
|
+
environment: 'client' | 'server'
|
|
22
|
+
schema: Schema
|
|
23
|
+
}) {
|
|
24
|
+
type PermissionReturn = Condition | boolean
|
|
25
|
+
|
|
26
|
+
type PermissionsWhere<Table extends TableName = TableName> = Where<
|
|
27
|
+
Table,
|
|
28
|
+
PermissionReturn
|
|
29
|
+
>
|
|
30
|
+
|
|
31
|
+
function buildPermissionQuery<PermissionWhere extends PermissionsWhere>(
|
|
32
|
+
authData: AuthData | null,
|
|
33
|
+
eb: ExpressionBuilder<any, any>,
|
|
34
|
+
permissionWhere: PermissionWhere,
|
|
35
|
+
// TODO until i can get a working PickPrimaryKeys<'message'>
|
|
36
|
+
objOrId: Record<string, any> | string
|
|
37
|
+
) {
|
|
38
|
+
const tableName = getWhereTableName(permissionWhere)
|
|
39
|
+
|
|
40
|
+
if (!tableName) {
|
|
41
|
+
throw new Error(`Must use PermissionWhere for buildPermissionQuery`)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const tableSchema = schema.tables[tableName]
|
|
45
|
+
|
|
46
|
+
if (!tableSchema) {
|
|
47
|
+
throw new Error(`No schema?`)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const primaryKeys = tableSchema.primaryKey
|
|
51
|
+
const permissionReturn = permissionWhere(eb, authData)
|
|
52
|
+
|
|
53
|
+
if (permissionReturn == null) {
|
|
54
|
+
throw new Error(`No permission defined for ${tableName}`)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (permissionReturn === true) {
|
|
58
|
+
return eb.cmpLit(true, '=', true)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (permissionReturn === false) {
|
|
62
|
+
return eb.cmpLit(true, '=', false)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const primaryKeyWheres: Condition[] = []
|
|
66
|
+
|
|
67
|
+
for (const key of primaryKeys) {
|
|
68
|
+
const value = typeof objOrId === 'string' ? objOrId : objOrId[key]
|
|
69
|
+
primaryKeyWheres.push(eb.cmp(key as any, value))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return eb.and(permissionReturn, ...primaryKeyWheres)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const can: Can = async (where, obj) => {
|
|
76
|
+
// on client we always allow! we only check on server (like zero does)
|
|
77
|
+
if (environment === 'server') {
|
|
78
|
+
const ctx = mutatorContext()
|
|
79
|
+
const tableName = getWhereTableName(where)
|
|
80
|
+
if (!tableName) {
|
|
81
|
+
throw new Error(`Must use where('table') style where to pass to can()`)
|
|
82
|
+
}
|
|
83
|
+
await ensurePermission(ctx.tx, ctx.authData, tableName, where, obj)
|
|
84
|
+
setDidRunPermissionCheck(ctx)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function ensurePermission(
|
|
89
|
+
tx: Transaction,
|
|
90
|
+
authData: AuthData | null,
|
|
91
|
+
tableName: TableName,
|
|
92
|
+
where: Where,
|
|
93
|
+
obj: any // TODO until i can get a working PickPrimaryKeys<'message'>
|
|
94
|
+
): Promise<void> {
|
|
95
|
+
if (authData?.role === 'admin') {
|
|
96
|
+
// admin role can do any mutation
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const zqlBuilder = getZQL() as any
|
|
101
|
+
const queryBase = zqlBuilder[tableName] as Query<any, any>
|
|
102
|
+
let query: Query<any, any, any> | null = null
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
query = queryBase
|
|
106
|
+
.where((eb) => {
|
|
107
|
+
return buildPermissionQuery(authData, eb, where, obj)
|
|
108
|
+
})
|
|
109
|
+
.one()
|
|
110
|
+
|
|
111
|
+
ensure(await tx.run(query))
|
|
112
|
+
} catch (err) {
|
|
113
|
+
const errorTitle = `${tableName} with auth id: ${authData?.id}`
|
|
114
|
+
|
|
115
|
+
if (err instanceof EnsureError) {
|
|
116
|
+
let msg = `[permission] 🚫 Not Allowed: ${errorTitle}`
|
|
117
|
+
if (process.env.NODE_ENV === 'development' && query) {
|
|
118
|
+
msg += `\n ${prettyFormatZeroQuery(query)}`
|
|
119
|
+
}
|
|
120
|
+
throw new Error(msg)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
throw new Error(`Error running permission ${errorTitle}\n${err}`)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
can,
|
|
129
|
+
buildPermissionQuery,
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { useQuery as zeroUseQuery } from '@rocicorp/zero/react'
|
|
2
|
+
import { use, useMemo, type Context } from 'react'
|
|
3
|
+
|
|
4
|
+
import { useZeroDebug } from './helpers/useZeroDebug'
|
|
5
|
+
import { resolveQuery, type PlainQueryFn } from './resolveQuery'
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
AnyQueryRegistry,
|
|
9
|
+
HumanReadable,
|
|
10
|
+
Query,
|
|
11
|
+
Schema as ZeroSchema,
|
|
12
|
+
} from '@rocicorp/zero'
|
|
13
|
+
|
|
14
|
+
export type UseQueryOptions = {
|
|
15
|
+
enabled?: boolean | undefined
|
|
16
|
+
ttl?: 'always' | 'never' | number | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type QueryResultDetails = ReturnType<typeof zeroUseQuery>[1]
|
|
20
|
+
export type QueryResult<TReturn> = readonly [HumanReadable<TReturn>, QueryResultDetails]
|
|
21
|
+
|
|
22
|
+
export type { PlainQueryFn }
|
|
23
|
+
|
|
24
|
+
export type UseQueryHook<Schema extends ZeroSchema> = {
|
|
25
|
+
// overload 1: plain function with params
|
|
26
|
+
<TArg, TTable extends keyof Schema['tables'] & string, TReturn>(
|
|
27
|
+
fn: PlainQueryFn<TArg, Query<TTable, Schema, TReturn>>,
|
|
28
|
+
params: TArg,
|
|
29
|
+
options?: UseQueryOptions | boolean
|
|
30
|
+
): QueryResult<TReturn>;
|
|
31
|
+
|
|
32
|
+
// overload 2: plain function with no params
|
|
33
|
+
<TTable extends keyof Schema['tables'] & string, TReturn>(
|
|
34
|
+
fn: PlainQueryFn<void, Query<TTable, Schema, TReturn>>,
|
|
35
|
+
options?: UseQueryOptions | boolean
|
|
36
|
+
): QueryResult<TReturn>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function createUseQuery<Schema extends ZeroSchema>({
|
|
40
|
+
DisabledContext,
|
|
41
|
+
customQueries,
|
|
42
|
+
}: {
|
|
43
|
+
DisabledContext: Context<boolean>
|
|
44
|
+
customQueries: AnyQueryRegistry
|
|
45
|
+
}): UseQueryHook<Schema> {
|
|
46
|
+
function useQuery(...args: any[]): any {
|
|
47
|
+
const disabled = use(DisabledContext)
|
|
48
|
+
const [fn, paramsOrOptions, optionsArg] = args
|
|
49
|
+
|
|
50
|
+
const { queryRequest, options } = useMemo(() => {
|
|
51
|
+
// determine if this is with params or no params
|
|
52
|
+
const hasParams =
|
|
53
|
+
optionsArg !== undefined ||
|
|
54
|
+
(paramsOrOptions &&
|
|
55
|
+
typeof paramsOrOptions === 'object' &&
|
|
56
|
+
!('enabled' in paramsOrOptions) &&
|
|
57
|
+
!('ttl' in paramsOrOptions))
|
|
58
|
+
|
|
59
|
+
const params = hasParams ? paramsOrOptions : undefined
|
|
60
|
+
const opts = hasParams ? optionsArg : paramsOrOptions
|
|
61
|
+
|
|
62
|
+
const queryRequest = resolveQuery({ customQueries, fn, params })
|
|
63
|
+
|
|
64
|
+
return { queryRequest, options: opts }
|
|
65
|
+
}, [fn, paramsOrOptions, optionsArg])
|
|
66
|
+
|
|
67
|
+
const out = zeroUseQuery(queryRequest as any, options)
|
|
68
|
+
|
|
69
|
+
if (process.env.NODE_ENV === 'development') {
|
|
70
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
71
|
+
useZeroDebug(queryRequest as any, options, out)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (disabled) {
|
|
75
|
+
return [null, { type: 'unknown' }] as never
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return out
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return useQuery as UseQueryHook<Schema>
|
|
82
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { defineQueries, defineQuery } from '@rocicorp/zero'
|
|
2
|
+
import {
|
|
3
|
+
useConnectionState,
|
|
4
|
+
useZero,
|
|
5
|
+
ZeroProvider,
|
|
6
|
+
useQuery as zeroUseQuery,
|
|
7
|
+
} from '@rocicorp/zero/react'
|
|
8
|
+
import { createEmitter, mapObject } from '@take-out/helpers'
|
|
9
|
+
import {
|
|
10
|
+
createContext,
|
|
11
|
+
memo,
|
|
12
|
+
use,
|
|
13
|
+
useEffect,
|
|
14
|
+
useMemo,
|
|
15
|
+
useRef,
|
|
16
|
+
type ReactNode,
|
|
17
|
+
} from 'react'
|
|
18
|
+
|
|
19
|
+
import { createPermissions } from './createPermissions'
|
|
20
|
+
import { createUseQuery } from './createUseQuery'
|
|
21
|
+
import { createMutators } from './helpers/createMutators'
|
|
22
|
+
import { prettyFormatZeroQuery } from './helpers/prettyFormatZeroQuery'
|
|
23
|
+
import { registerQuery } from './queryRegistry'
|
|
24
|
+
import { resolveQuery, type PlainQueryFn } from './resolveQuery'
|
|
25
|
+
import { setCustomQueries } from './run'
|
|
26
|
+
import { setAuthData, setSchema } from './state'
|
|
27
|
+
import { setRunner } from './zeroRunner'
|
|
28
|
+
|
|
29
|
+
import type { AuthData, GenericModels, GetZeroMutators, Where, ZeroEvent } from './types'
|
|
30
|
+
import type {
|
|
31
|
+
HumanReadable,
|
|
32
|
+
Query,
|
|
33
|
+
Row,
|
|
34
|
+
Schema as ZeroSchema,
|
|
35
|
+
Zero,
|
|
36
|
+
ZeroOptions,
|
|
37
|
+
} from '@rocicorp/zero'
|
|
38
|
+
|
|
39
|
+
type PreloadOptions = { ttl?: 'always' | 'never' | number | undefined }
|
|
40
|
+
|
|
41
|
+
export type GroupedQueries = Record<string, Record<string, (...args: any[]) => any>>
|
|
42
|
+
|
|
43
|
+
export function createZeroClient<
|
|
44
|
+
Schema extends ZeroSchema,
|
|
45
|
+
Models extends GenericModels,
|
|
46
|
+
>({
|
|
47
|
+
schema,
|
|
48
|
+
models,
|
|
49
|
+
groupedQueries,
|
|
50
|
+
}: {
|
|
51
|
+
schema: Schema
|
|
52
|
+
models: Models
|
|
53
|
+
groupedQueries: GroupedQueries
|
|
54
|
+
}) {
|
|
55
|
+
type ZeroMutators = GetZeroMutators<Models>
|
|
56
|
+
type ZeroInstance = Zero<Schema, ZeroMutators>
|
|
57
|
+
type TableName = keyof ZeroInstance['query']
|
|
58
|
+
|
|
59
|
+
setSchema(schema)
|
|
60
|
+
|
|
61
|
+
// build query registry from grouped queries
|
|
62
|
+
// this creates ONE shared defineQueries registry that matches the server's structure
|
|
63
|
+
const wrappedNamespaces: Record<
|
|
64
|
+
string,
|
|
65
|
+
Record<string, ReturnType<typeof defineQuery>>
|
|
66
|
+
> = {}
|
|
67
|
+
|
|
68
|
+
for (const [namespace, queries] of Object.entries(groupedQueries)) {
|
|
69
|
+
wrappedNamespaces[namespace] = {}
|
|
70
|
+
for (const [name, fn] of Object.entries(queries)) {
|
|
71
|
+
registerQuery(fn, `${namespace}.${name}`)
|
|
72
|
+
// wrap each plain function in defineQuery
|
|
73
|
+
wrappedNamespaces[namespace][name] = defineQuery(({ args }: { args: any }) =>
|
|
74
|
+
fn(args)
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// create the single shared CustomQuery registry
|
|
80
|
+
const customQueries = defineQueries(wrappedNamespaces)
|
|
81
|
+
|
|
82
|
+
// register for global run() helper
|
|
83
|
+
setCustomQueries(customQueries)
|
|
84
|
+
|
|
85
|
+
const DisabledContext = createContext(false)
|
|
86
|
+
|
|
87
|
+
const modelWritePermissions = mapObject(models, (val) => val.permissions) as Record<
|
|
88
|
+
TableName,
|
|
89
|
+
Where<any, any> | undefined
|
|
90
|
+
>
|
|
91
|
+
|
|
92
|
+
let latestZeroInstance: ZeroInstance | null = null
|
|
93
|
+
|
|
94
|
+
// Proxy allows swapping the Zero instance on login without breaking existing references.
|
|
95
|
+
// Ideally rocicorp/zero would support .setAuth() natively, but for now we swap instances.
|
|
96
|
+
const zero: ZeroInstance = new Proxy({} as never, {
|
|
97
|
+
get(_, key) {
|
|
98
|
+
if (latestZeroInstance === null) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`Zero instance not initialized. Ensure ZeroProvider is mounted before accessing 'zero'.`
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
return Reflect.get(latestZeroInstance, key, latestZeroInstance)
|
|
104
|
+
},
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
const permissionsHelpers = createPermissions<Schema>({
|
|
108
|
+
schema,
|
|
109
|
+
environment: 'client',
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
// const permissionCache = createLocalStorage<string, boolean>('permissions-cache', {
|
|
113
|
+
// storageLimit: 24,
|
|
114
|
+
// })
|
|
115
|
+
|
|
116
|
+
const zeroEvents = createEmitter<ZeroEvent | null>('zero', null)
|
|
117
|
+
|
|
118
|
+
const AuthDataContext = createContext<AuthData>({} as AuthData)
|
|
119
|
+
const useAuthData = () => use(AuthDataContext)
|
|
120
|
+
|
|
121
|
+
const useQuery = createUseQuery<Schema>({
|
|
122
|
+
DisabledContext,
|
|
123
|
+
customQueries,
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
// we don't want flickers as you move around and these queries are re-run
|
|
127
|
+
// and things generally aren't changing with permissions rapidly, so lets
|
|
128
|
+
// cache the last results and use that when first rendering, they will
|
|
129
|
+
// always update once the query resolves
|
|
130
|
+
function usePermission<K extends TableName>(
|
|
131
|
+
table: K,
|
|
132
|
+
objOrId: string | Partial<Row<any>> | undefined,
|
|
133
|
+
enabled = typeof objOrId !== 'undefined',
|
|
134
|
+
debug = false
|
|
135
|
+
): boolean | null {
|
|
136
|
+
const disabled = use(DisabledContext)
|
|
137
|
+
// const cacheVal = permissionCache.get(key) ?? permissionCache.get(keyBase)
|
|
138
|
+
const authData = useAuthData()
|
|
139
|
+
const permission = modelWritePermissions[table]
|
|
140
|
+
|
|
141
|
+
const query = (() => {
|
|
142
|
+
let baseQuery = (zero.query as any)[table].one()
|
|
143
|
+
|
|
144
|
+
if (disabled || !enabled || !permission) {
|
|
145
|
+
return baseQuery
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return baseQuery.where((eb) => {
|
|
149
|
+
return permissionsHelpers.buildPermissionQuery(
|
|
150
|
+
authData,
|
|
151
|
+
eb,
|
|
152
|
+
permission,
|
|
153
|
+
objOrId as any
|
|
154
|
+
)
|
|
155
|
+
})
|
|
156
|
+
})()
|
|
157
|
+
|
|
158
|
+
// usePermission is internal and uses inline queries directly via zeroUseQuery
|
|
159
|
+
const [data, status] = zeroUseQuery(query, {
|
|
160
|
+
enabled: Boolean(enabled && permission && authData && objOrId),
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
if (debug) {
|
|
164
|
+
console.info(
|
|
165
|
+
`usePermission()`,
|
|
166
|
+
{ data, status, authData, permission },
|
|
167
|
+
prettyFormatZeroQuery(query)
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const result = data
|
|
172
|
+
|
|
173
|
+
const allowed = Boolean(result)
|
|
174
|
+
|
|
175
|
+
if (!objOrId) {
|
|
176
|
+
return false
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return allowed
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const ProvideZero = ({
|
|
183
|
+
children,
|
|
184
|
+
authData: authDataIn,
|
|
185
|
+
disable,
|
|
186
|
+
...props
|
|
187
|
+
}: Omit<ZeroOptions<Schema, ZeroMutators>, 'schema' | 'mutators'> & {
|
|
188
|
+
children: ReactNode
|
|
189
|
+
authData?: AuthData | null
|
|
190
|
+
disable?: boolean
|
|
191
|
+
}) => {
|
|
192
|
+
const authData = (authDataIn ?? null) as AuthData
|
|
193
|
+
|
|
194
|
+
const mutators = useMemo(() => {
|
|
195
|
+
setAuthData(authData)
|
|
196
|
+
|
|
197
|
+
return createMutators({
|
|
198
|
+
models,
|
|
199
|
+
environment: 'client',
|
|
200
|
+
authData,
|
|
201
|
+
can: permissionsHelpers.can,
|
|
202
|
+
})
|
|
203
|
+
}, [authData])
|
|
204
|
+
|
|
205
|
+
// for now we re-parent
|
|
206
|
+
if (disable) {
|
|
207
|
+
return children
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return (
|
|
211
|
+
<AuthDataContext.Provider value={authData}>
|
|
212
|
+
<ZeroProvider schema={schema} kvStore="mem" mutators={mutators as any} {...props}>
|
|
213
|
+
<SetZeroInstance />
|
|
214
|
+
<ConnectionMonitor zeroEvents={zeroEvents} />
|
|
215
|
+
{children}
|
|
216
|
+
</ZeroProvider>
|
|
217
|
+
</AuthDataContext.Provider>
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const SetZeroInstance = () => {
|
|
222
|
+
const zeroInstance = useZero<Schema, ZeroMutators>()
|
|
223
|
+
|
|
224
|
+
// TODO last hack zero wants us to use useZero but its a big migration
|
|
225
|
+
// and has some downsides (global zero import leads to simpler code)
|
|
226
|
+
// they plan to support .setAuth() at some point, and so long as we refresh
|
|
227
|
+
// when we do change zero, this should be safe - that said we don't refresh
|
|
228
|
+
// the browser for now, but we also don't handle new auth keys in general
|
|
229
|
+
// we'll need to add that soon
|
|
230
|
+
if (zeroInstance !== latestZeroInstance) {
|
|
231
|
+
latestZeroInstance = zeroInstance
|
|
232
|
+
// register runner for global run() helper
|
|
233
|
+
setRunner((query, options) => zeroInstance.run(query as any, options))
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return null
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// monitors connection state and emits events (replaces onError callback removed in 0.25)
|
|
240
|
+
const ConnectionMonitor = memo(
|
|
241
|
+
({
|
|
242
|
+
zeroEvents,
|
|
243
|
+
}: {
|
|
244
|
+
zeroEvents: ReturnType<typeof createEmitter<ZeroEvent | null>>
|
|
245
|
+
}) => {
|
|
246
|
+
const state = useConnectionState()
|
|
247
|
+
const prevState = useRef(state.name)
|
|
248
|
+
|
|
249
|
+
useEffect(() => {
|
|
250
|
+
if (state.name !== prevState.current) {
|
|
251
|
+
const reason = 'reason' in state ? state.reason : ''
|
|
252
|
+
prevState.current = state.name
|
|
253
|
+
|
|
254
|
+
if (state.name === 'error' || state.name === 'needs-auth') {
|
|
255
|
+
const message = typeof reason === 'string' ? reason : state.name
|
|
256
|
+
zeroEvents.emit({
|
|
257
|
+
type: 'error',
|
|
258
|
+
message,
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}, [state, zeroEvents])
|
|
263
|
+
|
|
264
|
+
return null
|
|
265
|
+
}
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
// preload data for a query into cache without materializing
|
|
269
|
+
// uses same function signature as useQuery
|
|
270
|
+
function preload<TArg, TTable extends keyof Schema['tables'] & string, TReturn>(
|
|
271
|
+
fn: PlainQueryFn<TArg, Query<TTable, Schema, TReturn>>,
|
|
272
|
+
params: TArg,
|
|
273
|
+
options?: PreloadOptions
|
|
274
|
+
): { cleanup: () => void; complete: Promise<void> }
|
|
275
|
+
function preload<TTable extends keyof Schema['tables'] & string, TReturn>(
|
|
276
|
+
fn: PlainQueryFn<void, Query<TTable, Schema, TReturn>>,
|
|
277
|
+
options?: PreloadOptions
|
|
278
|
+
): { cleanup: () => void; complete: Promise<void> }
|
|
279
|
+
function preload(
|
|
280
|
+
fnArg: any,
|
|
281
|
+
paramsOrOptions?: any,
|
|
282
|
+
optionsArg?: PreloadOptions
|
|
283
|
+
): { cleanup: () => void; complete: Promise<void> } {
|
|
284
|
+
const hasParams =
|
|
285
|
+
optionsArg !== undefined || (paramsOrOptions && !('ttl' in paramsOrOptions))
|
|
286
|
+
const params = hasParams ? paramsOrOptions : undefined
|
|
287
|
+
const options = hasParams ? optionsArg : paramsOrOptions
|
|
288
|
+
|
|
289
|
+
const queryRequest = resolveQuery({ customQueries, fn: fnArg, params })
|
|
290
|
+
return zero.preload(queryRequest as any, options)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return {
|
|
294
|
+
zeroEvents,
|
|
295
|
+
ProvideZero,
|
|
296
|
+
useQuery,
|
|
297
|
+
usePermission,
|
|
298
|
+
zero,
|
|
299
|
+
preload,
|
|
300
|
+
}
|
|
301
|
+
}
|