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
package/src/cli.ts
ADDED
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs'
|
|
3
|
+
import { basename, resolve } from 'node:path'
|
|
4
|
+
|
|
5
|
+
import { ModelToValibot } from '@sinclair/typebox-codegen/model'
|
|
6
|
+
import { TypeScriptToModel } from '@sinclair/typebox-codegen/typescript'
|
|
7
|
+
import { defineCommand, runMain } from 'citty'
|
|
8
|
+
import * as ts from 'typescript'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Write file only if the content has changed.
|
|
12
|
+
* This prevents unnecessary rebuilds from file watchers.
|
|
13
|
+
*/
|
|
14
|
+
function writeFileIfChanged(filePath: string, content: string): boolean {
|
|
15
|
+
try {
|
|
16
|
+
if (existsSync(filePath)) {
|
|
17
|
+
const existingContent = readFileSync(filePath, 'utf-8')
|
|
18
|
+
if (existingContent === content) {
|
|
19
|
+
return false // no change
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
} catch {
|
|
23
|
+
// if we can't read the file, proceed with writing
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
writeFileSync(filePath, content, 'utf-8')
|
|
27
|
+
return true // file was written
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const generateQueries = defineCommand({
|
|
31
|
+
meta: {
|
|
32
|
+
name: 'generate-queries',
|
|
33
|
+
description: 'Generate server-side query validators from TypeScript query functions',
|
|
34
|
+
},
|
|
35
|
+
args: {
|
|
36
|
+
dir: {
|
|
37
|
+
type: 'positional',
|
|
38
|
+
description: 'Directory containing query files',
|
|
39
|
+
required: false,
|
|
40
|
+
default: '.',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
async run({ args }) {
|
|
44
|
+
const dir = resolve(args.dir)
|
|
45
|
+
|
|
46
|
+
const { readdirSync } = await import('node:fs')
|
|
47
|
+
|
|
48
|
+
const files = readdirSync(dir).filter((f) => f.endsWith('.ts'))
|
|
49
|
+
|
|
50
|
+
const allQueries: Array<{ name: string; params: string; valibotCode: string }> = []
|
|
51
|
+
|
|
52
|
+
// process files in parallel
|
|
53
|
+
const results = await Promise.all(
|
|
54
|
+
files.map(async (file) => {
|
|
55
|
+
const filePath = resolve(dir, file)
|
|
56
|
+
const queries: typeof allQueries = []
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
const content = readFileSync(filePath, 'utf-8')
|
|
60
|
+
|
|
61
|
+
const sourceFile = ts.createSourceFile(
|
|
62
|
+
filePath,
|
|
63
|
+
content,
|
|
64
|
+
ts.ScriptTarget.Latest,
|
|
65
|
+
true
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
69
|
+
if (ts.isVariableStatement(node)) {
|
|
70
|
+
const exportModifier = node.modifiers?.find(
|
|
71
|
+
(m) => m.kind === ts.SyntaxKind.ExportKeyword
|
|
72
|
+
)
|
|
73
|
+
if (!exportModifier) return
|
|
74
|
+
|
|
75
|
+
const declaration = node.declarationList.declarations[0]
|
|
76
|
+
if (!declaration || !ts.isVariableDeclaration(declaration)) return
|
|
77
|
+
|
|
78
|
+
const name = declaration.name.getText(sourceFile)
|
|
79
|
+
|
|
80
|
+
if (
|
|
81
|
+
declaration.initializer &&
|
|
82
|
+
ts.isArrowFunction(declaration.initializer)
|
|
83
|
+
) {
|
|
84
|
+
const params = declaration.initializer.parameters
|
|
85
|
+
let paramType = 'void'
|
|
86
|
+
|
|
87
|
+
if (params.length > 0) {
|
|
88
|
+
const param = params[0]!
|
|
89
|
+
paramType = param.type?.getText(sourceFile) || 'unknown'
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
const typeString = `type QueryParams = ${paramType}`
|
|
94
|
+
const model = TypeScriptToModel.Generate(typeString)
|
|
95
|
+
const valibotCode = ModelToValibot.Generate(model)
|
|
96
|
+
|
|
97
|
+
queries.push({ name, params: paramType, valibotCode })
|
|
98
|
+
} catch (err) {
|
|
99
|
+
console.error(`✗ ${name}: ${err}`)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
} catch (err) {
|
|
105
|
+
console.error(`Error processing ${file}:`, err)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return queries
|
|
109
|
+
})
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
allQueries.push(...results.flat())
|
|
113
|
+
console.info(`✓ ${allQueries.length} query validators`)
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
const generate = defineCommand({
|
|
118
|
+
meta: {
|
|
119
|
+
name: 'generate',
|
|
120
|
+
description: 'Generate models, types, tables, and query validators',
|
|
121
|
+
},
|
|
122
|
+
args: {
|
|
123
|
+
dir: {
|
|
124
|
+
type: 'positional',
|
|
125
|
+
description: 'Base directory (defaults to src/data)',
|
|
126
|
+
required: false,
|
|
127
|
+
default: 'src/data',
|
|
128
|
+
},
|
|
129
|
+
watch: {
|
|
130
|
+
type: 'boolean',
|
|
131
|
+
description: 'Watch for changes and regenerate',
|
|
132
|
+
required: false,
|
|
133
|
+
default: false,
|
|
134
|
+
},
|
|
135
|
+
after: {
|
|
136
|
+
type: 'string',
|
|
137
|
+
description: 'Command to run after generation completes',
|
|
138
|
+
required: false,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
async run({ args }) {
|
|
142
|
+
const baseDir = resolve(args.dir)
|
|
143
|
+
const modelsDir = resolve(baseDir, 'models')
|
|
144
|
+
const generatedDir = resolve(baseDir, 'generated')
|
|
145
|
+
const queriesDir = resolve(baseDir, 'queries')
|
|
146
|
+
|
|
147
|
+
const runGenerate = async (options?: { silent?: boolean }) => {
|
|
148
|
+
const silent = options?.silent ?? false
|
|
149
|
+
// ensure generated dir exists
|
|
150
|
+
if (!existsSync(generatedDir)) {
|
|
151
|
+
mkdirSync(generatedDir, { recursive: true })
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// read all model files and check for schemas in parallel
|
|
155
|
+
const allModelFiles = readdirSync(modelsDir)
|
|
156
|
+
.filter((f) => f.endsWith('.ts'))
|
|
157
|
+
.sort()
|
|
158
|
+
|
|
159
|
+
const schemaChecks = await Promise.all(
|
|
160
|
+
allModelFiles.map(async (f) => ({
|
|
161
|
+
file: f,
|
|
162
|
+
hasSchema: readFileSync(resolve(modelsDir, f), 'utf-8').includes(
|
|
163
|
+
'export const schema = table('
|
|
164
|
+
),
|
|
165
|
+
}))
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
const filesWithSchema = schemaChecks.filter((c) => c.hasSchema).map((c) => c.file)
|
|
169
|
+
|
|
170
|
+
// generate all files in parallel
|
|
171
|
+
const [modelsOutput, typesOutput, tablesOutput, readmeOutput] = await Promise.all([
|
|
172
|
+
Promise.resolve(generateModelsFile(allModelFiles)),
|
|
173
|
+
Promise.resolve(generateTypesFile(filesWithSchema)),
|
|
174
|
+
Promise.resolve(generateTablesFile(filesWithSchema)),
|
|
175
|
+
Promise.resolve(generateReadmeFile()),
|
|
176
|
+
])
|
|
177
|
+
|
|
178
|
+
// write all generated files in parallel
|
|
179
|
+
const writeResults = await Promise.all([
|
|
180
|
+
Promise.resolve(
|
|
181
|
+
writeFileIfChanged(resolve(generatedDir, 'models.ts'), modelsOutput)
|
|
182
|
+
),
|
|
183
|
+
Promise.resolve(
|
|
184
|
+
writeFileIfChanged(resolve(generatedDir, 'types.ts'), typesOutput)
|
|
185
|
+
),
|
|
186
|
+
Promise.resolve(
|
|
187
|
+
writeFileIfChanged(resolve(generatedDir, 'tables.ts'), tablesOutput)
|
|
188
|
+
),
|
|
189
|
+
Promise.resolve(
|
|
190
|
+
writeFileIfChanged(resolve(generatedDir, 'README.md'), readmeOutput)
|
|
191
|
+
),
|
|
192
|
+
])
|
|
193
|
+
|
|
194
|
+
const filesChanged = writeResults.filter(Boolean).length
|
|
195
|
+
if (filesChanged > 0 && !silent) {
|
|
196
|
+
console.info(` 📝 Updated ${filesChanged} file(s)`)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// generate synced queries
|
|
200
|
+
if (existsSync(queriesDir)) {
|
|
201
|
+
const queryFiles = readdirSync(queriesDir).filter((f) => f.endsWith('.ts'))
|
|
202
|
+
|
|
203
|
+
// process query files in parallel
|
|
204
|
+
const queryResults = await Promise.all(
|
|
205
|
+
queryFiles.map(async (file) => {
|
|
206
|
+
const filePath = resolve(queriesDir, file)
|
|
207
|
+
const fileBaseName = basename(file, '.ts')
|
|
208
|
+
const queries: Array<{
|
|
209
|
+
name: string
|
|
210
|
+
params: string
|
|
211
|
+
valibotCode: string
|
|
212
|
+
sourceFile: string
|
|
213
|
+
}> = []
|
|
214
|
+
|
|
215
|
+
try {
|
|
216
|
+
const content = readFileSync(filePath, 'utf-8')
|
|
217
|
+
|
|
218
|
+
const sourceFile = ts.createSourceFile(
|
|
219
|
+
filePath,
|
|
220
|
+
content,
|
|
221
|
+
ts.ScriptTarget.Latest,
|
|
222
|
+
true
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
226
|
+
if (ts.isVariableStatement(node)) {
|
|
227
|
+
const exportModifier = node.modifiers?.find(
|
|
228
|
+
(m) => m.kind === ts.SyntaxKind.ExportKeyword
|
|
229
|
+
)
|
|
230
|
+
if (!exportModifier) return
|
|
231
|
+
|
|
232
|
+
const declaration = node.declarationList.declarations[0]
|
|
233
|
+
if (!declaration || !ts.isVariableDeclaration(declaration)) return
|
|
234
|
+
|
|
235
|
+
const name = declaration.name.getText(sourceFile)
|
|
236
|
+
|
|
237
|
+
// skip 'permission' exports
|
|
238
|
+
if (name === 'permission') return
|
|
239
|
+
|
|
240
|
+
if (
|
|
241
|
+
declaration.initializer &&
|
|
242
|
+
ts.isArrowFunction(declaration.initializer)
|
|
243
|
+
) {
|
|
244
|
+
const params = declaration.initializer.parameters
|
|
245
|
+
let paramType = 'void'
|
|
246
|
+
|
|
247
|
+
if (params.length > 0) {
|
|
248
|
+
const param = params[0]!
|
|
249
|
+
paramType = param.type?.getText(sourceFile) || 'unknown'
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
const typeString = `type QueryParams = ${paramType}`
|
|
254
|
+
const model = TypeScriptToModel.Generate(typeString)
|
|
255
|
+
const valibotCode = ModelToValibot.Generate(model)
|
|
256
|
+
|
|
257
|
+
queries.push({
|
|
258
|
+
name,
|
|
259
|
+
params: paramType,
|
|
260
|
+
valibotCode,
|
|
261
|
+
sourceFile: fileBaseName,
|
|
262
|
+
})
|
|
263
|
+
} catch (err) {
|
|
264
|
+
console.error(`✗ ${name}: ${err}`)
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
})
|
|
269
|
+
} catch (err) {
|
|
270
|
+
console.error(`Error processing ${file}:`, err)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return queries
|
|
274
|
+
})
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
const allQueries = queryResults.flat()
|
|
278
|
+
const groupedQueriesOutput = generateGroupedQueriesFile(allQueries)
|
|
279
|
+
const syncedQueriesOutput = generateSyncedQueriesFile(allQueries)
|
|
280
|
+
|
|
281
|
+
const groupedChanged = writeFileIfChanged(
|
|
282
|
+
resolve(generatedDir, 'groupedQueries.ts'),
|
|
283
|
+
groupedQueriesOutput
|
|
284
|
+
)
|
|
285
|
+
const syncedChanged = writeFileIfChanged(
|
|
286
|
+
resolve(generatedDir, 'syncedQueries.ts'),
|
|
287
|
+
syncedQueriesOutput
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
const queryFilesChanged = (groupedChanged ? 1 : 0) + (syncedChanged ? 1 : 0)
|
|
291
|
+
const totalFilesChanged = filesChanged + queryFilesChanged
|
|
292
|
+
|
|
293
|
+
if (totalFilesChanged > 0 && !silent) {
|
|
294
|
+
if (groupedChanged) {
|
|
295
|
+
console.info(` 📝 Updated groupedQueries.ts`)
|
|
296
|
+
}
|
|
297
|
+
if (syncedChanged) {
|
|
298
|
+
console.info(` 📝 Updated syncedQueries.ts`)
|
|
299
|
+
}
|
|
300
|
+
console.info(
|
|
301
|
+
`✓ ${allModelFiles.length} models (${filesWithSchema.length} schemas), ${allQueries.length} queries`
|
|
302
|
+
)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// run after command only if files changed and not silent
|
|
306
|
+
if (totalFilesChanged > 0 && !silent && args.after) {
|
|
307
|
+
try {
|
|
308
|
+
const { execSync } = await import('node:child_process')
|
|
309
|
+
execSync(args.after, { stdio: 'inherit' })
|
|
310
|
+
} catch (err) {
|
|
311
|
+
console.error(`Error running after command: ${err}`)
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
} else {
|
|
315
|
+
if (filesChanged > 0 && !silent) {
|
|
316
|
+
console.info(
|
|
317
|
+
`✓ ${allModelFiles.length} models (${filesWithSchema.length} schemas)`
|
|
318
|
+
)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// run after command only if files changed and not silent
|
|
322
|
+
if (filesChanged > 0 && !silent && args.after) {
|
|
323
|
+
try {
|
|
324
|
+
const { execSync } = await import('node:child_process')
|
|
325
|
+
execSync(args.after, { stdio: 'inherit' })
|
|
326
|
+
} catch (err) {
|
|
327
|
+
console.error(`Error running after command: ${err}`)
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// run once (silent in watch mode for clean startup)
|
|
334
|
+
await runGenerate({ silent: args.watch })
|
|
335
|
+
|
|
336
|
+
// watch mode
|
|
337
|
+
if (args.watch) {
|
|
338
|
+
console.info('👀 watching...\n')
|
|
339
|
+
const chokidar = await import('chokidar')
|
|
340
|
+
|
|
341
|
+
let debounceTimer: ReturnType<typeof setTimeout> | null = null
|
|
342
|
+
|
|
343
|
+
const debouncedRegenerate = (path: string, event: string) => {
|
|
344
|
+
if (debounceTimer) {
|
|
345
|
+
clearTimeout(debounceTimer)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
console.info(`\n${event} ${path}`)
|
|
349
|
+
|
|
350
|
+
debounceTimer = setTimeout(() => {
|
|
351
|
+
runGenerate()
|
|
352
|
+
}, 1000)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const watcher = chokidar.watch([modelsDir, queriesDir], {
|
|
356
|
+
persistent: true,
|
|
357
|
+
ignoreInitial: true,
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
watcher.on('change', (path) => debouncedRegenerate(path, '📝'))
|
|
361
|
+
watcher.on('add', (path) => debouncedRegenerate(path, '➕'))
|
|
362
|
+
watcher.on('unlink', (path) => debouncedRegenerate(path, '🗑️ '))
|
|
363
|
+
|
|
364
|
+
// keep process alive
|
|
365
|
+
await new Promise(() => {})
|
|
366
|
+
}
|
|
367
|
+
},
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
function generateModelsFile(modelFiles: string[]) {
|
|
371
|
+
const modelNames = modelFiles.map((f) => basename(f, '.ts')).sort()
|
|
372
|
+
|
|
373
|
+
// special case: user.ts should be imported as userPublic
|
|
374
|
+
const getImportName = (name: string) => (name === 'user' ? 'userPublic' : name)
|
|
375
|
+
|
|
376
|
+
// generate imports (sorted)
|
|
377
|
+
const imports = modelNames
|
|
378
|
+
.map((name) => {
|
|
379
|
+
const importName = getImportName(name)
|
|
380
|
+
return `import * as ${importName} from '../models/${name}'`
|
|
381
|
+
})
|
|
382
|
+
.join('\n')
|
|
383
|
+
|
|
384
|
+
// generate models object (sorted by import name)
|
|
385
|
+
const sortedByImportName = [...modelNames].sort((a, b) =>
|
|
386
|
+
getImportName(a).localeCompare(getImportName(b))
|
|
387
|
+
)
|
|
388
|
+
const modelsObj = `export const models = {\n${sortedByImportName.map((name) => ` ${getImportName(name)},`).join('\n')}\n}`
|
|
389
|
+
|
|
390
|
+
return `// auto-generated by: on-zero generate\n${imports}\n\n${modelsObj}\n`
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function generateTypesFile(modelFiles: string[]) {
|
|
394
|
+
const modelNames = modelFiles.map((f) => basename(f, '.ts')).sort()
|
|
395
|
+
|
|
396
|
+
// special case: user.ts should reference userPublic in schema
|
|
397
|
+
const getSchemaName = (name: string) => (name === 'user' ? 'userPublic' : name)
|
|
398
|
+
|
|
399
|
+
// generate type exports using TableInsertRow and TableUpdateRow (sorted)
|
|
400
|
+
const typeExports = modelNames
|
|
401
|
+
.map((name) => {
|
|
402
|
+
const pascalName = name.charAt(0).toUpperCase() + name.slice(1)
|
|
403
|
+
const schemaName = getSchemaName(name)
|
|
404
|
+
return `export type ${pascalName} = TableInsertRow<typeof schema.${schemaName}>\nexport type ${pascalName}Update = TableUpdateRow<typeof schema.${schemaName}>`
|
|
405
|
+
})
|
|
406
|
+
.join('\n\n')
|
|
407
|
+
|
|
408
|
+
return `import type { TableInsertRow, TableUpdateRow } from 'on-zero'\nimport type * as schema from './tables'\n\n${typeExports}\n`
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function generateTablesFile(modelFiles: string[]) {
|
|
412
|
+
const modelNames = modelFiles.map((f) => basename(f, '.ts')).sort()
|
|
413
|
+
|
|
414
|
+
// special case: user.ts should be exported as userPublic
|
|
415
|
+
const getExportName = (name: string) => (name === 'user' ? 'userPublic' : name)
|
|
416
|
+
|
|
417
|
+
// generate schema exports (sorted)
|
|
418
|
+
const exports = modelNames
|
|
419
|
+
.map((name) => `export { schema as ${getExportName(name)} } from '../models/${name}'`)
|
|
420
|
+
.join('\n')
|
|
421
|
+
|
|
422
|
+
return `// auto-generated by: on-zero generate\n// this is separate from models as otherwise you end up with circular types :/\n\n${exports}\n`
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function generateGroupedQueriesFile(
|
|
426
|
+
queries: Array<{
|
|
427
|
+
name: string
|
|
428
|
+
params: string
|
|
429
|
+
valibotCode: string
|
|
430
|
+
sourceFile: string
|
|
431
|
+
}>
|
|
432
|
+
) {
|
|
433
|
+
// get unique source files sorted
|
|
434
|
+
const sortedFiles = [...new Set(queries.map((q) => q.sourceFile))].sort()
|
|
435
|
+
|
|
436
|
+
// generate re-exports
|
|
437
|
+
const exports = sortedFiles
|
|
438
|
+
.map((file) => `export * as ${file} from '../queries/${file}'`)
|
|
439
|
+
.join('\n')
|
|
440
|
+
|
|
441
|
+
return `/**
|
|
442
|
+
* auto-generated by: on-zero generate
|
|
443
|
+
*
|
|
444
|
+
* grouped query re-exports for minification-safe query identity.
|
|
445
|
+
* this file re-exports all query modules - while this breaks tree-shaking,
|
|
446
|
+
* queries are typically small and few in number even in larger apps.
|
|
447
|
+
*/
|
|
448
|
+
${exports}
|
|
449
|
+
`
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function generateSyncedQueriesFile(
|
|
453
|
+
queries: Array<{
|
|
454
|
+
name: string
|
|
455
|
+
params: string
|
|
456
|
+
valibotCode: string
|
|
457
|
+
sourceFile: string
|
|
458
|
+
}>
|
|
459
|
+
) {
|
|
460
|
+
// group queries by source file
|
|
461
|
+
const queryByFile = new Map<string, typeof queries>()
|
|
462
|
+
for (const q of queries) {
|
|
463
|
+
if (!queryByFile.has(q.sourceFile)) {
|
|
464
|
+
queryByFile.set(q.sourceFile, [])
|
|
465
|
+
}
|
|
466
|
+
queryByFile.get(q.sourceFile)!.push(q)
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// sort file names for consistent output
|
|
470
|
+
const sortedFiles = Array.from(queryByFile.keys()).sort()
|
|
471
|
+
|
|
472
|
+
const imports = `// auto-generated by: on-zero generate
|
|
473
|
+
// server-side query definitions with validators
|
|
474
|
+
import { defineQuery, defineQueries } from '@rocicorp/zero'
|
|
475
|
+
import * as v from 'valibot'
|
|
476
|
+
import * as Queries from './groupedQueries'
|
|
477
|
+
`
|
|
478
|
+
|
|
479
|
+
// generate grouped definitions by namespace
|
|
480
|
+
const namespaceDefs = sortedFiles
|
|
481
|
+
.map((file) => {
|
|
482
|
+
const fileQueries = queryByFile
|
|
483
|
+
.get(file)!
|
|
484
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
485
|
+
|
|
486
|
+
const queryDefs = fileQueries
|
|
487
|
+
.map((q) => {
|
|
488
|
+
// extract validator schema
|
|
489
|
+
const lines = q.valibotCode.split('\n').filter((l) => l.trim())
|
|
490
|
+
const schemaLineIndex = lines.findIndex((l) =>
|
|
491
|
+
l.startsWith('export const QueryParams')
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
let validatorDef = ''
|
|
495
|
+
if (schemaLineIndex !== -1) {
|
|
496
|
+
const schemaLines: string[] = []
|
|
497
|
+
let openBraces = 0
|
|
498
|
+
let started = false
|
|
499
|
+
|
|
500
|
+
for (let i = schemaLineIndex; i < lines.length; i++) {
|
|
501
|
+
const line = lines[i]!
|
|
502
|
+
const cleaned = started
|
|
503
|
+
? line
|
|
504
|
+
: line.replace('export const QueryParams = ', '')
|
|
505
|
+
schemaLines.push(cleaned)
|
|
506
|
+
started = true
|
|
507
|
+
|
|
508
|
+
openBraces += (cleaned.match(/\{/g) || []).length
|
|
509
|
+
openBraces -= (cleaned.match(/\}/g) || []).length
|
|
510
|
+
openBraces += (cleaned.match(/\(/g) || []).length
|
|
511
|
+
openBraces -= (cleaned.match(/\)/g) || []).length
|
|
512
|
+
|
|
513
|
+
if (openBraces === 0 && schemaLines.length > 0) {
|
|
514
|
+
break
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
validatorDef = schemaLines.join('\n')
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// for void queries, use the no-validator overload
|
|
521
|
+
if (q.params === 'void' || !validatorDef) {
|
|
522
|
+
return ` ${q.name}: defineQuery(() => Queries.${file}.${q.name}()),`
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// indent the validator for proper formatting
|
|
526
|
+
const indentedValidator = validatorDef
|
|
527
|
+
.split('\n')
|
|
528
|
+
.map((line, i) => (i === 0 ? line : ` ${line}`))
|
|
529
|
+
.join('\n')
|
|
530
|
+
|
|
531
|
+
// defineQuery with validator and args
|
|
532
|
+
return ` ${q.name}: defineQuery(
|
|
533
|
+
${indentedValidator},
|
|
534
|
+
({ args }) => Queries.${file}.${q.name}(args)
|
|
535
|
+
),`
|
|
536
|
+
})
|
|
537
|
+
.join('\n')
|
|
538
|
+
|
|
539
|
+
return `const ${file} = {\n${queryDefs}\n}`
|
|
540
|
+
})
|
|
541
|
+
.join('\n\n')
|
|
542
|
+
|
|
543
|
+
// build the defineQueries call with all namespaces
|
|
544
|
+
const queriesObject = sortedFiles.map((file) => ` ${file},`).join('\n')
|
|
545
|
+
|
|
546
|
+
return `${imports}
|
|
547
|
+
${namespaceDefs}
|
|
548
|
+
|
|
549
|
+
export const queries = defineQueries({
|
|
550
|
+
${queriesObject}
|
|
551
|
+
})
|
|
552
|
+
`
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
function generateReadmeFile() {
|
|
556
|
+
return `# generated
|
|
557
|
+
|
|
558
|
+
this folder is auto-generated by on-zero. do not edit files here directly.
|
|
559
|
+
|
|
560
|
+
## what's generated
|
|
561
|
+
|
|
562
|
+
- \`models.ts\` - exports all models from ../models
|
|
563
|
+
- \`types.ts\` - typescript types derived from table schemas
|
|
564
|
+
- \`tables.ts\` - exports table schemas for type inference
|
|
565
|
+
- \`groupedQueries.ts\` - namespaced query re-exports for client setup
|
|
566
|
+
- \`syncedQueries.ts\` - namespaced syncedQuery wrappers for server setup
|
|
567
|
+
|
|
568
|
+
## usage guidelines
|
|
569
|
+
|
|
570
|
+
**do not import generated files outside of the data folder.**
|
|
571
|
+
|
|
572
|
+
### queries
|
|
573
|
+
|
|
574
|
+
write your queries as plain functions in \`../queries/\` and import them directly:
|
|
575
|
+
|
|
576
|
+
\`\`\`ts
|
|
577
|
+
// ✅ good - import from queries
|
|
578
|
+
import { channelMessages } from '~/data/queries/message'
|
|
579
|
+
\`\`\`
|
|
580
|
+
|
|
581
|
+
the generated query files are only used internally by zero client/server setup.
|
|
582
|
+
|
|
583
|
+
### types
|
|
584
|
+
|
|
585
|
+
you can import types from this folder, but prefer re-exporting from \`../types.ts\`:
|
|
586
|
+
|
|
587
|
+
\`\`\`ts
|
|
588
|
+
// ❌ okay but not preferred
|
|
589
|
+
import type { Message } from '~/data/generated/types'
|
|
590
|
+
|
|
591
|
+
// ✅ better - re-export from types.ts
|
|
592
|
+
import type { Message } from '~/data/types'
|
|
593
|
+
\`\`\`
|
|
594
|
+
|
|
595
|
+
## regeneration
|
|
596
|
+
|
|
597
|
+
files are regenerated when you run:
|
|
598
|
+
|
|
599
|
+
\`\`\`bash
|
|
600
|
+
bun on-zero generate
|
|
601
|
+
\`\`\`
|
|
602
|
+
|
|
603
|
+
or in watch mode:
|
|
604
|
+
|
|
605
|
+
\`\`\`bash
|
|
606
|
+
bun on-zero generate --watch
|
|
607
|
+
\`\`\`
|
|
608
|
+
|
|
609
|
+
## more info
|
|
610
|
+
|
|
611
|
+
see the [on-zero readme](./node_modules/on-zero/README.md) for full documentation.
|
|
612
|
+
`
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
const main = defineCommand({
|
|
616
|
+
meta: {
|
|
617
|
+
name: 'on-zero',
|
|
618
|
+
description: 'on-zero CLI tools',
|
|
619
|
+
},
|
|
620
|
+
subCommands: {
|
|
621
|
+
generate: generate,
|
|
622
|
+
'generate-queries': generateQueries,
|
|
623
|
+
},
|
|
624
|
+
})
|
|
625
|
+
|
|
626
|
+
runMain(main)
|
package/src/constants.ts
ADDED