prisma-generator-express 1.28.0 → 1.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +244 -14
  2. package/dist/constants.d.ts +1 -0
  3. package/dist/generators/generateFastifyHandler.d.ts +4 -0
  4. package/dist/generators/generateFastifyHandler.js +78 -0
  5. package/dist/generators/generateFastifyHandler.js.map +1 -0
  6. package/dist/generators/generateOperationCore.d.ts +6 -0
  7. package/dist/generators/generateOperationCore.js +534 -0
  8. package/dist/generators/generateOperationCore.js.map +1 -0
  9. package/dist/generators/generateQueryBuilderHelper.js +85 -69
  10. package/dist/generators/generateQueryBuilderHelper.js.map +1 -1
  11. package/dist/generators/generateRouter.js +1 -25
  12. package/dist/generators/generateRouter.js.map +1 -1
  13. package/dist/generators/generateRouterFastify.d.ts +5 -0
  14. package/dist/generators/generateRouterFastify.js +512 -0
  15. package/dist/generators/generateRouterFastify.js.map +1 -0
  16. package/dist/generators/generateUnifiedDocs.d.ts +2 -1
  17. package/dist/generators/generateUnifiedDocs.js +147 -82
  18. package/dist/generators/generateUnifiedDocs.js.map +1 -1
  19. package/dist/generators/generateUnifiedHandler.d.ts +0 -1
  20. package/dist/generators/generateUnifiedHandler.js +47 -516
  21. package/dist/generators/generateUnifiedHandler.js.map +1 -1
  22. package/dist/generators/generateUnifiedScalarUI.d.ts +2 -0
  23. package/dist/generators/generateUnifiedScalarUI.js +127 -1324
  24. package/dist/generators/generateUnifiedScalarUI.js.map +1 -1
  25. package/dist/index.js +33 -8
  26. package/dist/index.js.map +1 -1
  27. package/dist/utils/copyFiles.d.ts +2 -1
  28. package/dist/utils/copyFiles.js +64 -38
  29. package/dist/utils/copyFiles.js.map +1 -1
  30. package/dist/utils/writeFileSafely.js +3 -0
  31. package/dist/utils/writeFileSafely.js.map +1 -1
  32. package/package.json +4 -1
  33. package/src/client/encodeQueryParams.ts +1 -1
  34. package/src/constants.ts +2 -0
  35. package/src/copy/createOutputValidatorMiddleware.ts +9 -12
  36. package/src/copy/docsRenderer.ts +1285 -0
  37. package/src/copy/parseQueryParams.ts +4 -8
  38. package/src/copy/routeConfig.ts +10 -4
  39. package/src/generators/generateFastifyHandler.ts +86 -0
  40. package/src/generators/generateOperationCore.ts +545 -0
  41. package/src/generators/generateQueryBuilderHelper.ts +86 -70
  42. package/src/generators/generateRouter.ts +1 -25
  43. package/src/generators/generateRouterFastify.ts +522 -0
  44. package/src/generators/generateUnifiedDocs.ts +164 -81
  45. package/src/generators/generateUnifiedHandler.ts +45 -533
  46. package/src/generators/generateUnifiedScalarUI.ts +134 -1323
  47. package/src/index.ts +45 -9
  48. package/src/utils/copyFiles.ts +79 -45
  49. package/src/utils/writeFileSafely.ts +4 -0
@@ -12,6 +12,7 @@ import { createRequire } from 'module'
12
12
  import type { ChildProcess } from 'child_process'
13
13
 
14
14
  let _process: ChildProcess | null = null
15
+ let _starting: Promise<void> | null = null
15
16
  let _stopping = false
16
17
  let _cleanupRegistered = false
17
18
 
@@ -43,90 +44,105 @@ function findCliPath(): string | null {
43
44
  }
44
45
 
45
46
  export function startQueryBuilder(options: QueryBuilderOptions = {}): void {
46
- if (_process) return
47
+ if (_process || _starting) return
47
48
 
48
- const env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
49
-
50
- if (env.NODE_ENV === 'production') return
51
-
52
- const cliPath = findCliPath()
53
- if (!cliPath) {
54
- console.warn('[query-builder] prisma-query-builder-ui not found. Install: npm install prisma-query-builder-ui')
55
- return
56
- }
49
+ _starting = doStart(options)
50
+ _starting.finally(() => { _starting = null })
51
+ }
57
52
 
58
- const port = options.port || 5173
59
- const host = options.host || 'localhost'
60
- const schemaPath = options.schemaPath || ${schemaPath}
61
- const databaseUrl = options.databaseUrl || env.DATABASE_URL || ''
53
+ function doStart(options: QueryBuilderOptions): Promise<void> {
54
+ return new Promise<void>((resolvePromise) => {
55
+ const env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
62
56
 
63
- if (!existsSync(schemaPath)) {
64
- console.error('[query-builder] Schema file not found: ' + schemaPath)
65
- return
66
- }
57
+ if (env.NODE_ENV === 'production') {
58
+ resolvePromise()
59
+ return
60
+ }
67
61
 
68
- let schemaContent: string
69
- try {
70
- schemaContent = readFileSync(schemaPath, 'utf-8')
71
- } catch (err) {
72
- console.error('[query-builder] Failed to read schema:', err)
73
- return
74
- }
62
+ const cliPath = findCliPath()
63
+ if (!cliPath) {
64
+ console.warn('[query-builder] prisma-query-builder-ui not found. Install: npm install prisma-query-builder-ui')
65
+ resolvePromise()
66
+ return
67
+ }
75
68
 
76
- const schemaCwd = dirname(resolve(schemaPath))
77
-
78
- _process = spawn(process.execPath, [cliPath], {
79
- stdio: 'inherit',
80
- env: {
81
- ...env,
82
- PORT: String(port),
83
- HOST: host,
84
- PRISMA_QUERY_BUILDER_MODE: 'embedded',
85
- DISABLE_PERSISTENCE: 'true',
86
- PRISMA_QUERY_BUILDER_SCHEMA_CONTENT: schemaContent,
87
- PRISMA_QUERY_BUILDER_CWD: schemaCwd,
88
- DATABASE_URL: databaseUrl,
89
- },
90
- })
69
+ const port = options.port || 5173
70
+ const host = options.host || 'localhost'
71
+ const schemaPath = options.schemaPath || ${schemaPath}
72
+ const databaseUrl = options.databaseUrl || env.DATABASE_URL || ''
91
73
 
92
- _process.on('error', (err) => {
93
- console.error('[query-builder] Failed to start:', err.message)
94
- _process = null
95
- })
74
+ if (!existsSync(schemaPath)) {
75
+ console.error('[query-builder] Schema file not found: ' + schemaPath)
76
+ resolvePromise()
77
+ return
78
+ }
96
79
 
97
- _process.on('exit', (code) => {
98
- const wasStopping = _stopping
99
- _stopping = false
100
- _process = null
101
- if (!wasStopping && code !== 0) {
102
- console.warn('[query-builder] Process exited with code ' + code)
80
+ let schemaContent: string
81
+ try {
82
+ schemaContent = readFileSync(schemaPath, 'utf-8')
83
+ } catch (err) {
84
+ console.error('[query-builder] Failed to read schema:', err)
85
+ resolvePromise()
86
+ return
103
87
  }
104
- })
105
88
 
106
- if (!_cleanupRegistered) {
107
- _cleanupRegistered = true
89
+ const schemaCwd = dirname(resolve(schemaPath))
90
+
91
+ _process = spawn(process.execPath, [cliPath], {
92
+ stdio: 'inherit',
93
+ env: {
94
+ ...env,
95
+ PORT: String(port),
96
+ HOST: host,
97
+ PRISMA_QUERY_BUILDER_MODE: 'embedded',
98
+ DISABLE_PERSISTENCE: 'true',
99
+ PRISMA_QUERY_BUILDER_SCHEMA_CONTENT: schemaContent,
100
+ PRISMA_QUERY_BUILDER_CWD: schemaCwd,
101
+ DATABASE_URL: databaseUrl,
102
+ },
103
+ })
108
104
 
109
- process.on('exit', () => {
110
- stopQueryBuilder()
105
+ _process.on('error', (err) => {
106
+ console.error('[query-builder] Failed to start:', err.message)
107
+ _process = null
108
+ resolvePromise()
111
109
  })
112
110
 
113
- const handleSigint = () => {
114
- stopQueryBuilder()
115
- process.removeListener('SIGINT', handleSigint)
116
- process.kill(process.pid, 'SIGINT')
117
- }
111
+ _process.on('exit', (code) => {
112
+ const wasStopping = _stopping
113
+ _stopping = false
114
+ _process = null
115
+ if (!wasStopping && code !== 0) {
116
+ console.warn('[query-builder] Process exited with code ' + code)
117
+ }
118
+ })
118
119
 
119
- const handleSigterm = () => {
120
- stopQueryBuilder()
121
- process.removeListener('SIGTERM', handleSigterm)
122
- process.kill(process.pid, 'SIGTERM')
123
- }
120
+ if (!_cleanupRegistered) {
121
+ _cleanupRegistered = true
124
122
 
125
- process.on('SIGINT', handleSigint)
126
- process.on('SIGTERM', handleSigterm)
127
- }
123
+ process.on('exit', () => {
124
+ stopQueryBuilder()
125
+ })
128
126
 
129
- console.log('[query-builder] Starting on http://' + host + ':' + port)
127
+ const handleSigint = () => {
128
+ stopQueryBuilder()
129
+ process.removeListener('SIGINT', handleSigint)
130
+ process.kill(process.pid, 'SIGINT')
131
+ }
132
+
133
+ const handleSigterm = () => {
134
+ stopQueryBuilder()
135
+ process.removeListener('SIGTERM', handleSigterm)
136
+ process.kill(process.pid, 'SIGTERM')
137
+ }
138
+
139
+ process.on('SIGINT', handleSigint)
140
+ process.on('SIGTERM', handleSigterm)
141
+ }
142
+
143
+ console.log('[query-builder] Starting on http://' + host + ':' + port)
144
+ resolvePromise()
145
+ })
130
146
  }
131
147
 
132
148
  export function stopQueryBuilder(): void {
@@ -135,4 +151,4 @@ export function stopQueryBuilder(): void {
135
151
  _process.kill()
136
152
  }
137
153
  `
138
- }
154
+ }
@@ -61,6 +61,7 @@ import {
61
61
  import type { RouteConfig } from '../routeConfig.js'
62
62
  import { parseQueryParams } from '../parseQueryParams.js'
63
63
  import { buildModelOpenApi } from '../buildModelOpenApi.js'
64
+ import { transformResult } from '../operationRuntime.js'
64
65
 
65
66
  const _env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
66
67
 
@@ -82,31 +83,6 @@ function normalizePrefix(p: string): string {
82
83
  return result
83
84
  }
84
85
 
85
- function transformResult(value: unknown): unknown {
86
- if (value === null || value === undefined) return value
87
- if (typeof value === 'bigint') return value.toString()
88
- if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) {
89
- return value.toString('base64')
90
- }
91
- if (value instanceof Uint8Array) {
92
- let binary = ''
93
- for (let i = 0; i < value.length; i++) binary += String.fromCharCode(value[i])
94
- return btoa(binary)
95
- }
96
- if (value instanceof Date) return value
97
- if (Array.isArray(value)) return value.map(transformResult)
98
- if (typeof value === 'object') {
99
- const proto = Object.getPrototypeOf(value)
100
- if (proto !== Object.prototype && proto !== null) return value
101
- const out: Record<string, unknown> = {}
102
- for (const [k, v] of Object.entries(value as Record<string, unknown>)) {
103
- out[k] = transformResult(v)
104
- }
105
- return out
106
- }
107
- return value
108
- }
109
-
110
86
  function isQueryBuilderEnabled(config: RouteConfig): boolean {
111
87
  if (config.queryBuilder === false) return false
112
88
  if (typeof config.queryBuilder === 'object' && config.queryBuilder.enabled === false) return false