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,226 @@
|
|
|
1
|
+
import { mustGetQuery } from '@rocicorp/zero'
|
|
2
|
+
import { PushProcessor } from '@rocicorp/zero/pg'
|
|
3
|
+
import { handleQueryRequest as zeroHandleQueryRequest } from '@rocicorp/zero/server'
|
|
4
|
+
import { zeroNodePg } from '@rocicorp/zero/server/adapters/pg'
|
|
5
|
+
import { assertString, randomId } from '@take-out/helpers'
|
|
6
|
+
import { Pool } from 'pg'
|
|
7
|
+
|
|
8
|
+
import { createPermissions } from './createPermissions'
|
|
9
|
+
import { createMutators } from './helpers/createMutators'
|
|
10
|
+
import { isInZeroMutation, mutatorContext } from './helpers/mutatorContext'
|
|
11
|
+
import { setCustomQueries } from './run'
|
|
12
|
+
import { setAuthData, setSchema } from './state'
|
|
13
|
+
import { setRunner } from './zeroRunner'
|
|
14
|
+
|
|
15
|
+
import type {
|
|
16
|
+
AsyncAction,
|
|
17
|
+
AuthData,
|
|
18
|
+
GenericModels,
|
|
19
|
+
GetZeroMutators,
|
|
20
|
+
Transaction,
|
|
21
|
+
} from './types'
|
|
22
|
+
import type {
|
|
23
|
+
AnyQueryRegistry,
|
|
24
|
+
HumanReadable,
|
|
25
|
+
Query,
|
|
26
|
+
Schema as ZeroSchema,
|
|
27
|
+
} from '@rocicorp/zero'
|
|
28
|
+
import type { TransactionProviderInput } from '@rocicorp/zero/pg'
|
|
29
|
+
|
|
30
|
+
export function createZeroServer<
|
|
31
|
+
Schema extends ZeroSchema,
|
|
32
|
+
Models extends GenericModels,
|
|
33
|
+
ServerActions extends Record<string, unknown>,
|
|
34
|
+
>({
|
|
35
|
+
createServerActions,
|
|
36
|
+
database,
|
|
37
|
+
schema,
|
|
38
|
+
models,
|
|
39
|
+
queries,
|
|
40
|
+
}: {
|
|
41
|
+
/**
|
|
42
|
+
* The DB connection string, same as ZERO_UPSTREAM_DB
|
|
43
|
+
*/
|
|
44
|
+
database: string
|
|
45
|
+
schema: Schema
|
|
46
|
+
models: Models
|
|
47
|
+
createServerActions: () => ServerActions
|
|
48
|
+
queries?: AnyQueryRegistry
|
|
49
|
+
}) {
|
|
50
|
+
setSchema(schema)
|
|
51
|
+
|
|
52
|
+
const dbString = assertString(database, `createZeroServer "database"`)
|
|
53
|
+
|
|
54
|
+
const zeroDb = zeroNodePg(
|
|
55
|
+
schema,
|
|
56
|
+
new Pool({
|
|
57
|
+
connectionString: dbString,
|
|
58
|
+
// handle self-signed certificates in production
|
|
59
|
+
ssl: dbString.includes('sslmode=require')
|
|
60
|
+
? { rejectUnauthorized: false }
|
|
61
|
+
: undefined,
|
|
62
|
+
})
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
const permissions = createPermissions<Schema>({
|
|
66
|
+
environment: 'server',
|
|
67
|
+
schema,
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
const processor = new PushProcessor(zeroDb)
|
|
71
|
+
|
|
72
|
+
const handleMutationRequest = async ({
|
|
73
|
+
authData,
|
|
74
|
+
request,
|
|
75
|
+
skipAsyncTasks,
|
|
76
|
+
}: {
|
|
77
|
+
authData: AuthData | null
|
|
78
|
+
request: Request
|
|
79
|
+
skipAsyncTasks?: boolean
|
|
80
|
+
}) => {
|
|
81
|
+
// since mutations do DB work in transaction, avoid any async tasks during
|
|
82
|
+
const asyncTasks: AsyncAction[] = []
|
|
83
|
+
|
|
84
|
+
const mutators = createMutators({
|
|
85
|
+
asyncTasks,
|
|
86
|
+
can: permissions.can,
|
|
87
|
+
createServerActions,
|
|
88
|
+
environment: 'server',
|
|
89
|
+
models,
|
|
90
|
+
authData,
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
// @ts-expect-error type is ok but config in monorepo
|
|
94
|
+
const response = await processor.process(mutators, request)
|
|
95
|
+
|
|
96
|
+
// now finish
|
|
97
|
+
if (!skipAsyncTasks && asyncTasks.length) {
|
|
98
|
+
const id = randomId()
|
|
99
|
+
console.info(`[push] complete, running async tasks ${asyncTasks.length} id ${id}`)
|
|
100
|
+
Promise.all(asyncTasks.map((task) => task()))
|
|
101
|
+
.then(() => {
|
|
102
|
+
console.info(`[push] async tasks complete ${id}`)
|
|
103
|
+
})
|
|
104
|
+
.catch((err) => {
|
|
105
|
+
console.error(`[push] error: async tasks failed 😞`, err)
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
response,
|
|
111
|
+
asyncTasks,
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const handleQueryRequest = async ({
|
|
116
|
+
authData,
|
|
117
|
+
request,
|
|
118
|
+
}: {
|
|
119
|
+
authData: AuthData | null
|
|
120
|
+
request: Request
|
|
121
|
+
}) => {
|
|
122
|
+
if (!queries) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
'No queries registered with createZeroServer. ' +
|
|
125
|
+
'Pass the syncedQueries registry to createZeroServer via the queries option.'
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// set authData globally for permission checks in query functions
|
|
130
|
+
setAuthData(authData || ({} as AuthData))
|
|
131
|
+
|
|
132
|
+
const response = await zeroHandleQueryRequest(
|
|
133
|
+
(name, args) => {
|
|
134
|
+
const query = (mustGetQuery as any)(queries, name)
|
|
135
|
+
return query.fn({ args, ctx: authData })
|
|
136
|
+
},
|
|
137
|
+
schema,
|
|
138
|
+
request
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
response,
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const mutate = async (
|
|
147
|
+
run: (tx: Transaction, mutators: GetZeroMutators<Models>) => Promise<void>,
|
|
148
|
+
authData?: Pick<AuthData, 'email' | 'id'> & Partial<AuthData>
|
|
149
|
+
) => {
|
|
150
|
+
const asyncTasks: Array<() => Promise<void>> = []
|
|
151
|
+
|
|
152
|
+
const mutators = createMutators({
|
|
153
|
+
models,
|
|
154
|
+
environment: 'server',
|
|
155
|
+
asyncTasks,
|
|
156
|
+
authData: {
|
|
157
|
+
id: '',
|
|
158
|
+
email: 'admin@start.chat',
|
|
159
|
+
role: 'admin',
|
|
160
|
+
...authData,
|
|
161
|
+
},
|
|
162
|
+
createServerActions,
|
|
163
|
+
can: permissions.can,
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
await transaction(async (tx) => {
|
|
167
|
+
await run(tx, mutators)
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
await Promise.all(asyncTasks.map((t) => t()))
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async function transaction<
|
|
174
|
+
CB extends (tx: Transaction) => Promise<any>,
|
|
175
|
+
Returns extends CB extends (tx: Transaction) => Promise<infer X> ? X : never,
|
|
176
|
+
>(query: CB): Promise<Returns> {
|
|
177
|
+
try {
|
|
178
|
+
if (isInZeroMutation()) {
|
|
179
|
+
const { tx } = mutatorContext()
|
|
180
|
+
return await query(tx)
|
|
181
|
+
}
|
|
182
|
+
// @ts-expect-error type
|
|
183
|
+
const output = await zeroDb.transaction(query, dummyTransactionInput)
|
|
184
|
+
return output
|
|
185
|
+
} catch (err) {
|
|
186
|
+
console.error(`Error running transaction(): ${err}`)
|
|
187
|
+
throw err
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function query<R>(
|
|
192
|
+
cb: (q: Transaction['query']) => Query<any, Schema, R>
|
|
193
|
+
): Promise<HumanReadable<R>> {
|
|
194
|
+
return transaction(async (tx) => {
|
|
195
|
+
return cb(tx.query)
|
|
196
|
+
}) as any
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// register for global run() helper
|
|
200
|
+
if (queries) {
|
|
201
|
+
setCustomQueries(queries)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// server uses transaction-based execution
|
|
205
|
+
setRunner((queryObj) => {
|
|
206
|
+
return transaction(async (tx) => {
|
|
207
|
+
return tx.run(queryObj)
|
|
208
|
+
})
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
// This is needed temporarily and will be cleaned up in the future.
|
|
212
|
+
const dummyTransactionInput: TransactionProviderInput = {
|
|
213
|
+
clientGroupID: 'unused',
|
|
214
|
+
clientID: 'unused',
|
|
215
|
+
mutationID: 42,
|
|
216
|
+
upstreamSchema: 'unused',
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
handleMutationRequest,
|
|
221
|
+
handleQueryRequest,
|
|
222
|
+
transaction,
|
|
223
|
+
mutate,
|
|
224
|
+
query,
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { sleep } from '@take-out/helpers'
|
|
2
|
+
|
|
3
|
+
import type { Query, Row } from '@rocicorp/zero'
|
|
4
|
+
|
|
5
|
+
export async function batchQuery<Q extends Query<any, any, any>, Item extends Row<Q>>(
|
|
6
|
+
q: Q,
|
|
7
|
+
mapper: (items: Item[]) => Promise<void>,
|
|
8
|
+
{
|
|
9
|
+
chunk,
|
|
10
|
+
pause = 0,
|
|
11
|
+
stopAfter = 100_000,
|
|
12
|
+
}: {
|
|
13
|
+
chunk: number
|
|
14
|
+
pause?: number
|
|
15
|
+
stopAfter?: number
|
|
16
|
+
} = { chunk: 20 }
|
|
17
|
+
) {
|
|
18
|
+
let hasMore = true
|
|
19
|
+
let last: Item | null = null
|
|
20
|
+
let iterations = 0
|
|
21
|
+
|
|
22
|
+
while (hasMore) {
|
|
23
|
+
let query = q.limit(chunk)
|
|
24
|
+
|
|
25
|
+
if (last) {
|
|
26
|
+
query = query.start(last)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const results = await query.run({ type: 'complete' })
|
|
30
|
+
|
|
31
|
+
await mapper(results as Item[])
|
|
32
|
+
|
|
33
|
+
if (results.length < chunk) {
|
|
34
|
+
hasMore = false
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (iterations > stopAfter) {
|
|
38
|
+
console.error(`[batchQuery] ‼️ stopping batch, ran ${stopAfter} chunks`)
|
|
39
|
+
break
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (pause) {
|
|
43
|
+
await sleep(pause)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { mapObject, time } from '@take-out/helpers'
|
|
2
|
+
|
|
3
|
+
import { runWithContext } from './mutatorContext'
|
|
4
|
+
|
|
5
|
+
import { isBrowser, isServer } from '../constants'
|
|
6
|
+
import type {
|
|
7
|
+
AuthData,
|
|
8
|
+
Can,
|
|
9
|
+
GenericModels,
|
|
10
|
+
GetZeroMutators,
|
|
11
|
+
MutatorContext,
|
|
12
|
+
Transaction,
|
|
13
|
+
} from '../types'
|
|
14
|
+
|
|
15
|
+
export function createMutators<Models extends GenericModels>({
|
|
16
|
+
environment,
|
|
17
|
+
authData,
|
|
18
|
+
createServerActions,
|
|
19
|
+
asyncTasks = [],
|
|
20
|
+
can,
|
|
21
|
+
models,
|
|
22
|
+
}: {
|
|
23
|
+
environment: 'server' | 'client'
|
|
24
|
+
authData: AuthData | null
|
|
25
|
+
can: Can
|
|
26
|
+
models: Models
|
|
27
|
+
asyncTasks?: Array<() => Promise<void>>
|
|
28
|
+
createServerActions?: () => Record<string, any>
|
|
29
|
+
}): GetZeroMutators<Models> {
|
|
30
|
+
const serverActions = createServerActions?.()
|
|
31
|
+
|
|
32
|
+
const modelMutators = mapObject(models, (val) => val.mutate) as {
|
|
33
|
+
[K in keyof typeof models]: (typeof models)[K]['mutate']
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function withContext<Args extends any[]>(fn: (...args: Args) => Promise<void>) {
|
|
37
|
+
return async (tx: Transaction, ...args: Args): Promise<void> => {
|
|
38
|
+
const mutationContext: MutatorContext = {
|
|
39
|
+
tx,
|
|
40
|
+
authData,
|
|
41
|
+
environment,
|
|
42
|
+
can,
|
|
43
|
+
server:
|
|
44
|
+
environment === 'server'
|
|
45
|
+
? ({
|
|
46
|
+
actions: serverActions || {},
|
|
47
|
+
asyncTasks: asyncTasks || {},
|
|
48
|
+
} as MutatorContext['server'])
|
|
49
|
+
: undefined,
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return await runWithContext(mutationContext, () => {
|
|
53
|
+
// @ts-expect-error type shenanigan
|
|
54
|
+
// map to our mutations() helper
|
|
55
|
+
return fn(mutationContext, ...args)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function withDevelopmentLogging<Args extends any[]>(
|
|
61
|
+
name: string,
|
|
62
|
+
fn: (...args: Args) => Promise<void>
|
|
63
|
+
) {
|
|
64
|
+
if (process.env.NODE_ENV !== 'development' && !process.env.IS_TESTING) {
|
|
65
|
+
return fn
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return async (...args: Args): Promise<void> => {
|
|
69
|
+
const startTime = performance.now()
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
if (isServer) {
|
|
73
|
+
console.info(`[mutator] ${name} start`)
|
|
74
|
+
}
|
|
75
|
+
const result = await fn(...args)
|
|
76
|
+
const duration = (performance.now() - startTime).toFixed(2)
|
|
77
|
+
if (isBrowser) {
|
|
78
|
+
console.groupCollapsed(`[mutator] ${name} completed in ${duration}ms`)
|
|
79
|
+
console.info('→', args[1])
|
|
80
|
+
console.info('←', result)
|
|
81
|
+
console.trace()
|
|
82
|
+
console.groupEnd()
|
|
83
|
+
} else {
|
|
84
|
+
// TODO in prod just track
|
|
85
|
+
console.info(`[mutator] ${name} completed in ${duration}ms`)
|
|
86
|
+
}
|
|
87
|
+
return result
|
|
88
|
+
} catch (error) {
|
|
89
|
+
const duration = (performance.now() - startTime).toFixed(2)
|
|
90
|
+
console.groupCollapsed(`[mutator] ${name} failed after ${duration}ms`)
|
|
91
|
+
console.error('error:', error)
|
|
92
|
+
console.info('arguments:', JSON.stringify(args[1], null, 2))
|
|
93
|
+
console.info('stack trace:', new Error().stack)
|
|
94
|
+
console.groupEnd()
|
|
95
|
+
throw error
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function withTimeoutGuard<Args extends any[]>(
|
|
101
|
+
name: string,
|
|
102
|
+
fn: (...args: Args) => Promise<void>,
|
|
103
|
+
// don't want this too high - zero runs mutations in order and waits for the last to finish it seems
|
|
104
|
+
// so if one mutation gets stuck it will just sit there
|
|
105
|
+
timeoutMs: number = time.ms.minutes(1)
|
|
106
|
+
) {
|
|
107
|
+
return async (...args: Args): Promise<void> => {
|
|
108
|
+
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
109
|
+
setTimeout(() => {
|
|
110
|
+
reject(new Error(`[mutator] ${name} timeout after ${timeoutMs}ms`))
|
|
111
|
+
}, timeoutMs)
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
return Promise.race([fn(...args), timeoutPromise])
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function decorateMutators<T extends Record<string, Record<string, any>>>(modules: T) {
|
|
119
|
+
const result: any = {}
|
|
120
|
+
|
|
121
|
+
for (const [moduleName, moduleExports] of Object.entries(modules)) {
|
|
122
|
+
result[moduleName] = {}
|
|
123
|
+
for (const [name, exportValue] of Object.entries(moduleExports)) {
|
|
124
|
+
if (typeof exportValue === 'function') {
|
|
125
|
+
const fullName = `${moduleName}.${name}`
|
|
126
|
+
result[moduleName][name] = withDevelopmentLogging(
|
|
127
|
+
fullName,
|
|
128
|
+
withTimeoutGuard(fullName, withContext(exportValue))
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return result
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return decorateMutators(modelMutators)
|
|
138
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { globalValue } from '@take-out/helpers'
|
|
2
|
+
|
|
3
|
+
import type { MutatorContext } from '../types'
|
|
4
|
+
|
|
5
|
+
const PermissionCheckRan = globalValue(
|
|
6
|
+
`on-zero:permissions-check`,
|
|
7
|
+
() => new WeakMap<MutatorContext, boolean>()
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
export const getDidRunPermissionCheck = (ctx: MutatorContext) => {
|
|
11
|
+
return PermissionCheckRan.get(ctx)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const setDidRunPermissionCheck = (ctx: MutatorContext) => {
|
|
15
|
+
return PermissionCheckRan.set(ctx, true)
|
|
16
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ensure } from '@take-out/helpers'
|
|
2
|
+
|
|
3
|
+
import { mutatorContext } from './mutatorContext'
|
|
4
|
+
|
|
5
|
+
import type { AuthData } from '../types'
|
|
6
|
+
|
|
7
|
+
export const ensureLoggedIn = (): AuthData => {
|
|
8
|
+
const { authData } = mutatorContext()
|
|
9
|
+
ensure(authData, 'logged in')
|
|
10
|
+
return authData
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { getAuthData } from '../state'
|
|
2
|
+
import { isInZeroMutation, mutatorContext } from './mutatorContext'
|
|
3
|
+
|
|
4
|
+
import type { AuthData } from '../types'
|
|
5
|
+
|
|
6
|
+
export function getQueryOrMutatorAuthData(): AuthData | null {
|
|
7
|
+
if (isInZeroMutation()) {
|
|
8
|
+
return mutatorContext().authData as AuthData
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return getAuthData()
|
|
12
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createAsyncContext } from '@take-out/helpers'
|
|
2
|
+
|
|
3
|
+
import type { MutatorContext } from '../types'
|
|
4
|
+
|
|
5
|
+
const asyncContext = createAsyncContext<MutatorContext>()
|
|
6
|
+
|
|
7
|
+
export function mutatorContext(): MutatorContext {
|
|
8
|
+
const currentContext = asyncContext.get()
|
|
9
|
+
if (!currentContext) {
|
|
10
|
+
throw new Error('mutatorContext must be called within a mutator')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return currentContext
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function isInZeroMutation() {
|
|
17
|
+
return !!asyncContext.get()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function runWithContext<T>(
|
|
21
|
+
context: MutatorContext,
|
|
22
|
+
fn: () => T | Promise<T>
|
|
23
|
+
): Promise<T> {
|
|
24
|
+
return asyncContext.run(context, fn)
|
|
25
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { ellipsis } from '@take-out/helpers'
|
|
2
|
+
|
|
3
|
+
import type { Query } from '@rocicorp/zero'
|
|
4
|
+
|
|
5
|
+
export const prettyFormatZeroQuery = (
|
|
6
|
+
query: Query<any, any, any>,
|
|
7
|
+
mode: 'full' | 'minimal' = 'full'
|
|
8
|
+
): string => {
|
|
9
|
+
const astObject = query['_completeAst']?.()
|
|
10
|
+
|
|
11
|
+
if (!astObject) return ''
|
|
12
|
+
|
|
13
|
+
if (mode === 'minimal') {
|
|
14
|
+
return prettyFormatMinimal(astObject)
|
|
15
|
+
}
|
|
16
|
+
return prettyFormatFull(astObject)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const prettyFormatFull = (astObject: any, indent = 0): string => {
|
|
20
|
+
if (!astObject || !astObject.table) return ''
|
|
21
|
+
|
|
22
|
+
const spaces = ' '.repeat(indent)
|
|
23
|
+
let query = astObject.table
|
|
24
|
+
let hasChainedMethods = false
|
|
25
|
+
|
|
26
|
+
// Add where conditions
|
|
27
|
+
if (astObject.where) {
|
|
28
|
+
const whereClause = formatWhere(astObject.where)
|
|
29
|
+
if (hasChainedMethods) {
|
|
30
|
+
query += `\n${spaces} ${whereClause}`
|
|
31
|
+
} else {
|
|
32
|
+
query += whereClause
|
|
33
|
+
hasChainedMethods = true
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Add limit
|
|
38
|
+
if (astObject.limit) {
|
|
39
|
+
const limitClause = `.limit(${astObject.limit})`
|
|
40
|
+
if (hasChainedMethods) {
|
|
41
|
+
query += `\n${spaces} ${limitClause}`
|
|
42
|
+
} else {
|
|
43
|
+
query += limitClause
|
|
44
|
+
hasChainedMethods = true
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Add orderBy
|
|
49
|
+
if (astObject.orderBy && astObject.orderBy.length > 0) {
|
|
50
|
+
const orderClauses = astObject.orderBy
|
|
51
|
+
.map(([field, direction]: [string, string]) => `${field}, ${direction}`)
|
|
52
|
+
.join(', ')
|
|
53
|
+
const orderByClause = `.orderBy(${orderClauses})`
|
|
54
|
+
if (hasChainedMethods) {
|
|
55
|
+
query += `\n${spaces} ${orderByClause}`
|
|
56
|
+
} else {
|
|
57
|
+
query += orderByClause
|
|
58
|
+
hasChainedMethods = true
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Add related queries
|
|
63
|
+
if (astObject.related && astObject.related.length > 0) {
|
|
64
|
+
astObject.related.forEach((rel: any) => {
|
|
65
|
+
if (rel.subquery) {
|
|
66
|
+
const alias = rel.subquery.alias || rel.subquery.table
|
|
67
|
+
const subQuery = prettyFormatFull(rel.subquery, indent + 1)
|
|
68
|
+
query += `\n${spaces} .related(${alias}, q => q.${subQuery}`
|
|
69
|
+
}
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// Add closing parentheses
|
|
73
|
+
const closingParens = ')'.repeat(astObject.related.length)
|
|
74
|
+
query += `\n${spaces}${closingParens}`
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return query
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const prettyFormatMinimal = (astObject: any): string => {
|
|
81
|
+
if (!astObject || !astObject.table) return ''
|
|
82
|
+
|
|
83
|
+
let query = astObject.table
|
|
84
|
+
|
|
85
|
+
// Add where conditions only
|
|
86
|
+
if (astObject.where) {
|
|
87
|
+
query += formatWhere(astObject.where).replace('.where(', '(')
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Add sub-queries info if present
|
|
91
|
+
if (astObject.related && astObject.related.length > 0) {
|
|
92
|
+
const subQueries = collectSubQueryTables(astObject.related)
|
|
93
|
+
const count = subQueries.length
|
|
94
|
+
const tableNames = subQueries.join(', ')
|
|
95
|
+
query += ` (+${count}: ${ellipsis(tableNames, 30)})`
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return query
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const collectSubQueryTables = (related: any[]): string[] => {
|
|
102
|
+
const tables: string[] = []
|
|
103
|
+
|
|
104
|
+
related.forEach((rel: any) => {
|
|
105
|
+
if (rel.subquery) {
|
|
106
|
+
const tableName = rel.subquery.alias || rel.subquery.table
|
|
107
|
+
tables.push(tableName)
|
|
108
|
+
|
|
109
|
+
// Recursively collect nested sub-queries
|
|
110
|
+
if (rel.subquery.related && rel.subquery.related.length > 0) {
|
|
111
|
+
tables.push(...collectSubQueryTables(rel.subquery.related))
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
return tables
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const formatWhere = (where: any): string => {
|
|
120
|
+
if (!where) return ''
|
|
121
|
+
|
|
122
|
+
if (where.type === 'simple') {
|
|
123
|
+
const column = where.left?.name || where.left
|
|
124
|
+
const value = where.right?.value !== undefined ? where.right.value : where.right
|
|
125
|
+
const op = where.op || '='
|
|
126
|
+
|
|
127
|
+
// Special case: if column is "id" and op is "=" and value is a single item, show just the value
|
|
128
|
+
if (
|
|
129
|
+
column === 'id' &&
|
|
130
|
+
op === '=' &&
|
|
131
|
+
(typeof value === 'string' || typeof value === 'number')
|
|
132
|
+
) {
|
|
133
|
+
return `(${value})`
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (op === '=') {
|
|
137
|
+
return `.where(${column}, ${value})`
|
|
138
|
+
}
|
|
139
|
+
return `.where(${column}, ${op}, ${value})`
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (where.type === 'and' && where.conditions) {
|
|
143
|
+
let result = ''
|
|
144
|
+
where.conditions.forEach((condition: any, index: number) => {
|
|
145
|
+
if (index === 0) {
|
|
146
|
+
result += formatWhere(condition)
|
|
147
|
+
} else {
|
|
148
|
+
result += `.and(${formatWhere(condition).slice(1)})` // Remove the leading dot
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
return result
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (where.type === 'or' && where.conditions) {
|
|
155
|
+
let result = ''
|
|
156
|
+
where.conditions.forEach((condition: any, index: number) => {
|
|
157
|
+
if (index === 0) {
|
|
158
|
+
result += formatWhere(condition)
|
|
159
|
+
} else {
|
|
160
|
+
result += `.or(${formatWhere(condition).slice(1)})` // Remove the leading dot
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
return result
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return ''
|
|
167
|
+
}
|