@opensaas/stack-cli 0.5.0 → 0.6.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.
Files changed (54) hide show
  1. package/README.md +76 -0
  2. package/dist/commands/migrate.d.ts.map +1 -1
  3. package/dist/commands/migrate.js +94 -268
  4. package/dist/commands/migrate.js.map +1 -1
  5. package/package.json +7 -2
  6. package/.turbo/turbo-build.log +0 -4
  7. package/CHANGELOG.md +0 -462
  8. package/CLAUDE.md +0 -298
  9. package/src/commands/__snapshots__/generate.test.ts.snap +0 -413
  10. package/src/commands/dev.test.ts +0 -215
  11. package/src/commands/dev.ts +0 -48
  12. package/src/commands/generate.test.ts +0 -282
  13. package/src/commands/generate.ts +0 -182
  14. package/src/commands/init.ts +0 -34
  15. package/src/commands/mcp.ts +0 -135
  16. package/src/commands/migrate.ts +0 -534
  17. package/src/generator/__snapshots__/context.test.ts.snap +0 -361
  18. package/src/generator/__snapshots__/prisma.test.ts.snap +0 -174
  19. package/src/generator/__snapshots__/types.test.ts.snap +0 -1702
  20. package/src/generator/context.test.ts +0 -139
  21. package/src/generator/context.ts +0 -227
  22. package/src/generator/index.ts +0 -7
  23. package/src/generator/lists.test.ts +0 -335
  24. package/src/generator/lists.ts +0 -140
  25. package/src/generator/plugin-types.ts +0 -147
  26. package/src/generator/prisma-config.ts +0 -46
  27. package/src/generator/prisma-extensions.ts +0 -159
  28. package/src/generator/prisma.test.ts +0 -211
  29. package/src/generator/prisma.ts +0 -161
  30. package/src/generator/types.test.ts +0 -268
  31. package/src/generator/types.ts +0 -537
  32. package/src/index.ts +0 -46
  33. package/src/mcp/lib/documentation-provider.ts +0 -710
  34. package/src/mcp/lib/features/catalog.ts +0 -301
  35. package/src/mcp/lib/generators/feature-generator.ts +0 -598
  36. package/src/mcp/lib/types.ts +0 -89
  37. package/src/mcp/lib/wizards/migration-wizard.ts +0 -584
  38. package/src/mcp/lib/wizards/wizard-engine.ts +0 -427
  39. package/src/mcp/server/index.ts +0 -361
  40. package/src/mcp/server/stack-mcp-server.ts +0 -544
  41. package/src/migration/generators/migration-generator.ts +0 -675
  42. package/src/migration/introspectors/index.ts +0 -12
  43. package/src/migration/introspectors/keystone-introspector.ts +0 -296
  44. package/src/migration/introspectors/nextjs-introspector.ts +0 -209
  45. package/src/migration/introspectors/prisma-introspector.ts +0 -233
  46. package/src/migration/types.ts +0 -92
  47. package/tests/introspectors/keystone-introspector.test.ts +0 -255
  48. package/tests/introspectors/nextjs-introspector.test.ts +0 -302
  49. package/tests/introspectors/prisma-introspector.test.ts +0 -268
  50. package/tests/migration-generator.test.ts +0 -592
  51. package/tests/migration-wizard.test.ts +0 -442
  52. package/tsconfig.json +0 -13
  53. package/tsconfig.tsbuildinfo +0 -1
  54. package/vitest.config.ts +0 -26
package/CLAUDE.md DELETED
@@ -1,298 +0,0 @@
1
- # @opensaas/stack-cli
2
-
3
- Command-line tools for OpenSaas Stack providing code generation and development utilities.
4
-
5
- ## Purpose
6
-
7
- Converts `opensaas.config.ts` into Prisma schema and TypeScript types. Provides watch mode for automatic regeneration during development.
8
-
9
- ## Key Files & Commands
10
-
11
- ### Binary (`bin/opensaas.js`)
12
-
13
- Entry point exposing `opensaas` CLI command
14
-
15
- ### Commands (`src/commands/`)
16
-
17
- - `generate.ts` - One-time generation
18
- - `dev.ts` - Watch mode with automatic regeneration
19
- - `init.ts` - Project scaffolding (future)
20
-
21
- ### Generators (`src/generator/`)
22
-
23
- - `prisma.ts` - Generates `prisma/schema.prisma` from config
24
- - `types.ts` - Generates `.opensaas/types.ts` TypeScript types
25
- - `context.ts` - Generates `.opensaas/context.ts` context factory
26
- - `mcp.ts` - Generates MCP tools metadata
27
- - `type-patcher.ts` - Patches Prisma types for relationships
28
-
29
- ## Architecture
30
-
31
- ### Config Loading
32
-
33
- Uses `jiti` to execute TypeScript config:
34
-
35
- ```typescript
36
- const jiti = createJiti(import.meta.url)
37
- const config = jiti('./opensaas.config.ts').default
38
- ```
39
-
40
- ### Generator Pipeline
41
-
42
- 1. Load config from `opensaas.config.ts`
43
- 2. Generate Prisma schema → `prisma/schema.prisma`
44
- 3. Generate TypeScript types → `.opensaas/types.ts`
45
- 4. Generate context factory → `.opensaas/context.ts`
46
- 5. Generate MCP tools (if enabled) → `.opensaas/mcp-tools.json`
47
-
48
- ### Watch Mode
49
-
50
- Uses `chokidar` to watch `opensaas.config.ts`:
51
-
52
- ```typescript
53
- const watcher = chokidar.watch('opensaas.config.ts')
54
- watcher.on('change', () => runGenerator())
55
- ```
56
-
57
- ## CLI Usage
58
-
59
- ### Generate Command
60
-
61
- ```bash
62
- opensaas generate
63
- ```
64
-
65
- Outputs:
66
-
67
- - `✅ Prisma schema generated`
68
- - `✅ TypeScript types generated`
69
- - Next steps (run `prisma generate` and `db push`)
70
-
71
- ### Dev Command
72
-
73
- ```bash
74
- opensaas dev
75
- ```
76
-
77
- Outputs:
78
-
79
- - Initial generation
80
- - `👀 Watching opensaas.config.ts for changes...`
81
- - Auto-regenerates on file changes
82
-
83
- ## Generated Files
84
-
85
- ### Prisma Schema (`prisma/schema.prisma`)
86
-
87
- ```prisma
88
- datasource db {
89
- provider = "sqlite"
90
- }
91
-
92
- generator client {
93
- provider = "prisma-client"
94
- }
95
-
96
- model Post {
97
- id String @id @default(cuid())
98
- title String
99
- createdAt DateTime @default(now())
100
- updatedAt DateTime @updatedAt
101
- }
102
- ```
103
-
104
- **Note:** Prisma 7 no longer includes `url` in the schema. The database URL is passed to PrismaClient via adapters in the `prismaClientConstructor` function.
105
-
106
- ### Prisma CLI Config (`prisma.config.ts`)
107
-
108
- ```typescript
109
- import 'dotenv/config'
110
- import { defineConfig, env } from 'prisma/config'
111
-
112
- export default defineConfig({
113
- schema: 'prisma/schema.prisma',
114
- datasource: {
115
- url: env('DATABASE_URL'),
116
- },
117
- })
118
- ```
119
-
120
- **Purpose:** Prisma 7 requires this file at the project root for CLI commands like `prisma db push` and `prisma migrate dev` to work. This is separate from the runtime configuration.
121
-
122
- **Key points:**
123
-
124
- - Generated automatically by `opensaas generate`
125
- - Requires `dotenv` package to load `.env` files
126
- - Reads `DATABASE_URL` from environment variables
127
- - Only used by Prisma CLI commands, not by application runtime
128
-
129
- ### Types (`.opensaas/types.ts`)
130
-
131
- ```typescript
132
- export type Post = {
133
- id: string
134
- title: string
135
- createdAt: Date
136
- updatedAt: Date
137
- }
138
-
139
- export type PostCreateInput = {
140
- title: string
141
- }
142
-
143
- export type PostUpdateInput = {
144
- title?: string
145
- }
146
- ```
147
-
148
- ### Context Factory (`.opensaas/context.ts`)
149
-
150
- ```typescript
151
- import { createContext } from '@opensaas/stack-core'
152
- import { PrismaClient } from '@prisma/client'
153
- import config from '../opensaas.config'
154
-
155
- // Prisma 7 requires adapters - PrismaClient created via prismaClientConstructor
156
- const prisma = config.db.prismaClientConstructor(PrismaClient)
157
-
158
- export function getContext(session?: any) {
159
- return createContext(config, prisma, session)
160
- }
161
- ```
162
-
163
- **Note:** The actual generated context is more sophisticated with async config resolution and singleton management, but this shows the core pattern.
164
-
165
- ## Integration Points
166
-
167
- ### With @opensaas/stack-core
168
-
169
- - Imports generator functions from core
170
- - Delegates Prisma/TS generation to field methods via core
171
-
172
- ### With @opensaas/stack-auth
173
-
174
- - Context factory supports custom `prismaClientConstructor` for Better-auth session provider
175
-
176
- ### With MCP (Model Context Protocol)
177
-
178
- - Generates MCP tools metadata when MCP enabled in config
179
- - MCP functionality is now in `@opensaas/stack-core/mcp` (runtime) and `@opensaas/stack-auth/mcp` (adapter)
180
-
181
- ### With Prisma
182
-
183
- Workflow:
184
-
185
- 1. `opensaas generate` → creates `prisma/schema.prisma` and `prisma.config.ts`
186
- 2. `npx prisma generate` → creates Prisma Client
187
- 3. `npx prisma db push` → pushes schema to database (uses `prisma.config.ts` for datasource URL)
188
-
189
- ## Common Patterns
190
-
191
- ### Development Workflow
192
-
193
- ```bash
194
- # Terminal 1: Watch and regenerate
195
- opensaas dev
196
-
197
- # Terminal 2: Run Next.js
198
- pnpm next dev
199
-
200
- # Edit opensaas.config.ts - auto regenerates!
201
- ```
202
-
203
- ### Package.json Scripts
204
-
205
- ```json
206
- {
207
- "scripts": {
208
- "generate": "opensaas generate",
209
- "db:push": "prisma db push",
210
- "db:studio": "prisma studio",
211
- "dev": "opensaas dev"
212
- }
213
- }
214
- ```
215
-
216
- ### CI/CD Integration
217
-
218
- ```yaml
219
- - run: pnpm install
220
- - run: opensaas generate
221
- - run: npx prisma generate
222
- - run: pnpm test
223
- ```
224
-
225
- ### Custom Prisma Client (Required in Prisma 7)
226
-
227
- **All configs must provide `prismaClientConstructor`** with a database adapter:
228
-
229
- ```typescript
230
- // SQLite example
231
- import { PrismaBetterSQLite3 } from '@prisma/adapter-better-sqlite3'
232
- import Database from 'better-sqlite3'
233
-
234
- config({
235
- db: {
236
- provider: 'sqlite',
237
- url: process.env.DATABASE_URL || 'file:./dev.db',
238
- prismaClientConstructor: (PrismaClient) => {
239
- const db = new Database(process.env.DATABASE_URL || './dev.db')
240
- const adapter = new PrismaBetterSQLite3(db)
241
- return new PrismaClient({ adapter })
242
- },
243
- },
244
- })
245
- ```
246
-
247
- ```typescript
248
- // PostgreSQL example
249
- import { PrismaPg } from '@prisma/adapter-pg'
250
- import pg from 'pg'
251
-
252
- config({
253
- db: {
254
- provider: 'postgresql',
255
- url: process.env.DATABASE_URL,
256
- prismaClientConstructor: (PrismaClient) => {
257
- const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL })
258
- const adapter = new PrismaPg(pool)
259
- return new PrismaClient({ adapter })
260
- },
261
- },
262
- })
263
- ```
264
-
265
- Generated context always uses the constructor:
266
-
267
- ```typescript
268
- // .opensaas/context.ts
269
- const prisma = config.db.prismaClientConstructor(PrismaClient)
270
- ```
271
-
272
- ## Type Patching
273
-
274
- CLI patches Prisma types for relationship fields to handle access control:
275
-
276
- - Relationships can be `null` when access denied
277
- - Adds `| null` to relationship field types in generated types
278
-
279
- ## Error Handling
280
-
281
- Common errors:
282
-
283
- - Config not found → check file exists in CWD
284
- - TypeScript errors in config → fix syntax in `opensaas.config.ts`
285
- - Permission denied → ensure write access to `prisma/` and `.opensaas/`
286
-
287
- ## Output Styling
288
-
289
- Uses `chalk` and `ora` for colored, animated output:
290
-
291
- - ✅ Green checkmarks for success
292
- - ❌ Red X for errors
293
- - 🚀 Emoji for branding
294
- - Spinner animations during generation
295
-
296
- ## Future Commands
297
-
298
- `opensaas init` - Project scaffolding with templates (planned)
@@ -1,413 +0,0 @@
1
- // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
-
3
- exports[`Generate Command Integration > Generator Integration > should generate all files for a basic config > context 1`] = `
4
- "/**
5
- * Auto-generated context factory
6
- *
7
- * This module provides a simple API for creating OpenSaas contexts.
8
- * It abstracts away Prisma client management and configuration.
9
- *
10
- * DO NOT EDIT - This file is automatically generated by 'pnpm generate'
11
- */
12
-
13
- import { getContext as getOpensaasContext } from '@opensaas/stack-core'
14
- import type { Session as OpensaasSession, OpenSaasConfig } from '@opensaas/stack-core'
15
- import { PrismaClient } from './prisma-client/client'
16
- import type { Context } from './types'
17
- import { prismaExtensions } from './prisma-extensions'
18
- import configOrPromise from '../opensaas.config'
19
-
20
- // Resolve config if it's a Promise (when plugins are present)
21
- const configPromise = Promise.resolve(configOrPromise)
22
- let resolvedConfig: OpenSaasConfig | null = null
23
-
24
- // Internal Prisma singleton - managed automatically
25
- const globalForPrisma = globalThis as unknown as { prisma: ReturnType<typeof createExtendedPrisma> | null }
26
- let prisma: ReturnType<typeof createExtendedPrisma> | null = null
27
-
28
- /**
29
- * Create Prisma client with result extensions
30
- */
31
- function createExtendedPrisma(basePrisma: PrismaClient) {
32
- // Check if there are any extensions to apply
33
- if (Object.keys(prismaExtensions).length === 0) {
34
- return basePrisma
35
- }
36
- // Apply result extensions
37
- return basePrisma.$extends(prismaExtensions)
38
- }
39
-
40
- async function getPrisma() {
41
- if (!prisma) {
42
- if (!resolvedConfig) {
43
- resolvedConfig = await configPromise
44
- }
45
- const basePrisma = resolvedConfig.db.prismaClientConstructor!(PrismaClient)
46
- const extendedPrisma = createExtendedPrisma(basePrisma)
47
- prisma = globalForPrisma.prisma ?? extendedPrisma
48
- if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
49
- }
50
- return prisma
51
- }
52
-
53
- async function getConfig() {
54
- if (!resolvedConfig) {
55
- resolvedConfig = await configPromise
56
- }
57
- return resolvedConfig
58
- }
59
-
60
- /**
61
- * Storage utilities (not configured)
62
- */
63
- const storage = {
64
- uploadFile: async () => {
65
- throw new Error('Storage is not configured. Add storage providers to your opensaas.config.ts')
66
- },
67
- uploadImage: async () => {
68
- throw new Error('Storage is not configured. Add storage providers to your opensaas.config.ts')
69
- },
70
- deleteFile: async () => {
71
- throw new Error('Storage is not configured. Add storage providers to your opensaas.config.ts')
72
- },
73
- deleteImage: async () => {
74
- throw new Error('Storage is not configured. Add storage providers to your opensaas.config.ts')
75
- },
76
- }
77
-
78
- /**
79
- * Get OpenSaas context with optional session
80
- *
81
- * @param session - Optional session object (structure defined by your application)
82
- *
83
- * @example
84
- * \`\`\`typescript
85
- * // Anonymous access
86
- * const context = await getContext()
87
- * const posts = await context.db.post.findMany()
88
- *
89
- * // Authenticated access
90
- * const context = await getContext({ userId: 'user-123' })
91
- * const myPosts = await context.db.post.findMany()
92
- *
93
- * // With custom session type
94
- * type CustomSession = { userId: string; email: string; role: string } | null
95
- * const context = await getContext<CustomSession>({ userId: '123', email: 'user@example.com', role: 'admin' })
96
- * // context.session is now typed as CustomSession
97
- * \`\`\`
98
- */
99
- export async function getContext<TSession extends OpensaasSession = OpensaasSession>(session?: TSession): Promise<Context<TSession>> {
100
- const config = await getConfig()
101
- const prismaClient = await getPrisma()
102
- return getOpensaasContext(config, prismaClient, session ?? null, storage) as unknown as Context<TSession>
103
- }
104
-
105
- /**
106
- * Raw context for synchronous initialization (e.g., Better-auth setup)
107
- * This is only available after config is resolved, use with caution
108
- */
109
- export const rawOpensaasContext = (async () => {
110
- const config = await getConfig()
111
- const prismaClient = await getPrisma()
112
- return getOpensaasContext(config, prismaClient, null, storage) as unknown as Context
113
- })()
114
-
115
- /**
116
- * Re-export resolved config for use in admin pages and server actions
117
- * This is a promise that resolves to the config
118
- */
119
- export const config = getConfig()
120
- "
121
- `;
122
-
123
- exports[`Generate Command Integration > Generator Integration > should generate all files for a basic config > prisma-schema 1`] = `
124
- "generator client {
125
- provider = "prisma-client"
126
- output = "../.opensaas/prisma-client"
127
- }
128
-
129
- datasource db {
130
- provider = "sqlite"
131
- }
132
-
133
- model User {
134
- id String @id @default(cuid())
135
- name String
136
- email String
137
- createdAt DateTime @default(now())
138
- updatedAt DateTime @updatedAt
139
- }
140
- "
141
- `;
142
-
143
- exports[`Generate Command Integration > Generator Integration > should generate all files for a basic config > types 1`] = `
144
- "/**
145
- * Generated types from OpenSaas configuration
146
- * DO NOT EDIT - This file is automatically generated
147
- */
148
-
149
- import type { Session as OpensaasSession, StorageUtils, ServerActionProps, AccessControlledDB, AccessContext } from '@opensaas/stack-core'
150
- import type { PrismaClient, Prisma } from './prisma-client/client'
151
- import type { PluginServices } from './plugin-types'
152
-
153
- /**
154
- * Virtual fields for User - computed fields not in database
155
- * These are added to query results via resolveOutput hooks
156
- */
157
- export type UserVirtualFields = {
158
- // No virtual fields defined
159
- }
160
-
161
- /**
162
- * Transformed fields for User - fields with resultExtension transformations
163
- * These override Prisma's base types with transformed types via result extensions
164
- */
165
- export type UserTransformedFields = {
166
- // No transformed fields defined
167
- }
168
-
169
- export type UserOutput = {
170
- id: string
171
- name: string
172
- email: string
173
- createdAt: Date
174
- updatedAt: Date
175
- } & UserVirtualFields
176
-
177
- export type User = UserOutput
178
-
179
- export type UserCreateInput = {
180
- name: string
181
- email: string
182
- }
183
-
184
- export type UserUpdateInput = {
185
- name?: string
186
- email?: string
187
- }
188
-
189
- export type UserWhereInput = {
190
- id?: string
191
- AND?: Array<UserWhereInput>
192
- OR?: Array<UserWhereInput>
193
- NOT?: UserWhereInput
194
- name?: { equals?: string, not?: string }
195
- email?: { equals?: string, not?: string }
196
- }
197
-
198
- /**
199
- * Hook types for User list
200
- * Properly typed to use Prisma's generated input types
201
- */
202
- export type UserHooks = {
203
- resolveInput?: (args:
204
- | {
205
- operation: 'create'
206
- resolvedData: Prisma.UserCreateInput
207
- item: undefined
208
- context: import('@opensaas/stack-core').AccessContext
209
- }
210
- | {
211
- operation: 'update'
212
- resolvedData: Prisma.UserUpdateInput
213
- item: User
214
- context: import('@opensaas/stack-core').AccessContext
215
- }
216
- ) => Promise<Prisma.UserCreateInput | Prisma.UserUpdateInput>
217
- validateInput?: (args: {
218
- operation: 'create' | 'update'
219
- resolvedData: Prisma.UserCreateInput | Prisma.UserUpdateInput
220
- item?: User
221
- context: import('@opensaas/stack-core').AccessContext
222
- addValidationError: (msg: string) => void
223
- }) => Promise<void>
224
- beforeOperation?: (args: {
225
- operation: 'create' | 'update' | 'delete'
226
- resolvedData?: Prisma.UserCreateInput | Prisma.UserUpdateInput
227
- item?: User
228
- context: import('@opensaas/stack-core').AccessContext
229
- }) => Promise<void>
230
- afterOperation?: (args: {
231
- operation: 'create' | 'update' | 'delete'
232
- resolvedData?: Prisma.UserCreateInput | Prisma.UserUpdateInput
233
- item?: User
234
- context: import('@opensaas/stack-core').AccessContext
235
- }) => Promise<void>
236
- }
237
-
238
- /**
239
- * Custom DB type that uses Prisma's conditional types with virtual and transformed field support
240
- * Types change based on select/include - relationships only present when explicitly included
241
- * Virtual fields and transformed fields are added to the base model type
242
- */
243
- export type CustomDB = Omit<AccessControlledDB<PrismaClient>,
244
- 'user'
245
- > & {
246
- user: {
247
- findUnique: <T extends Prisma.UserFindUniqueArgs>(
248
- args: Prisma.SelectSubset<T, Prisma.UserFindUniqueArgs>
249
- ) => Promise<(Omit<Prisma.UserGetPayload<T>, keyof UserTransformedFields> & UserTransformedFields & UserVirtualFields) | null>
250
- findMany: <T extends Prisma.UserFindManyArgs>(
251
- args?: Prisma.SelectSubset<T, Prisma.UserFindManyArgs>
252
- ) => Promise<Array<Omit<Prisma.UserGetPayload<T>, keyof UserTransformedFields> & UserTransformedFields & UserVirtualFields>>
253
- create: <T extends Prisma.UserCreateArgs>(
254
- args: Prisma.SelectSubset<T, Prisma.UserCreateArgs>
255
- ) => Promise<Omit<Prisma.UserGetPayload<T>, keyof UserTransformedFields> & UserTransformedFields & UserVirtualFields>
256
- update: <T extends Prisma.UserUpdateArgs>(
257
- args: Prisma.SelectSubset<T, Prisma.UserUpdateArgs>
258
- ) => Promise<(Omit<Prisma.UserGetPayload<T>, keyof UserTransformedFields> & UserTransformedFields & UserVirtualFields) | null>
259
- delete: <T extends Prisma.UserDeleteArgs>(
260
- args: Prisma.SelectSubset<T, Prisma.UserDeleteArgs>
261
- ) => Promise<(Omit<Prisma.UserGetPayload<T>, keyof UserTransformedFields> & UserTransformedFields & UserVirtualFields) | null>
262
- count: (args?: Prisma.UserCountArgs) => Promise<number>
263
- }
264
- }
265
-
266
- /**
267
- * Context type compatible with AccessContext but with CustomDB for virtual field typing
268
- * Extends AccessContext and overrides db property to include virtual fields in output types
269
- */
270
- export type Context<TSession extends OpensaasSession = OpensaasSession> = Omit<AccessContext<PrismaClient>, 'db' | 'session'> & {
271
- db: CustomDB
272
- session: TSession
273
- serverAction: (props: ServerActionProps) => Promise<unknown>
274
- sudo: () => Context<TSession>
275
- }"
276
- `;
277
-
278
- exports[`Generate Command Integration > Generator Integration > should generate consistent output across multiple runs > consistent-output 1`] = `
279
- "generator client {
280
- provider = "prisma-client"
281
- output = "../.opensaas/prisma-client"
282
- }
283
-
284
- datasource db {
285
- provider = "sqlite"
286
- }
287
-
288
- model User {
289
- id String @id @default(cuid())
290
- name String?
291
- createdAt DateTime @default(now())
292
- updatedAt DateTime @updatedAt
293
- }
294
- "
295
- `;
296
-
297
- exports[`Generate Command Integration > Generator Integration > should handle different database providers > mysql-provider 1`] = `
298
- "generator client {
299
- provider = "prisma-client"
300
- output = "../.opensaas/prisma-client"
301
- }
302
-
303
- datasource db {
304
- provider = "mysql"
305
- }
306
- "
307
- `;
308
-
309
- exports[`Generate Command Integration > Generator Integration > should handle different database providers > postgresql-provider 1`] = `
310
- "generator client {
311
- provider = "prisma-client"
312
- output = "../.opensaas/prisma-client"
313
- }
314
-
315
- datasource db {
316
- provider = "postgresql"
317
- }
318
- "
319
- `;
320
-
321
- exports[`Generate Command Integration > Generator Integration > should handle different database providers > sqlite-provider 1`] = `
322
- "generator client {
323
- provider = "prisma-client"
324
- output = "../.opensaas/prisma-client"
325
- }
326
-
327
- datasource db {
328
- provider = "sqlite"
329
- }
330
- "
331
- `;
332
-
333
- exports[`Generate Command Integration > Generator Integration > should handle empty lists config > empty-lists-schema 1`] = `
334
- "generator client {
335
- provider = "prisma-client"
336
- output = "../.opensaas/prisma-client"
337
- }
338
-
339
- datasource db {
340
- provider = "sqlite"
341
- }
342
- "
343
- `;
344
-
345
- exports[`Generate Command Integration > Generator Integration > should handle empty lists config > empty-lists-types 1`] = `
346
- "/**
347
- * Generated types from OpenSaas configuration
348
- * DO NOT EDIT - This file is automatically generated
349
- */
350
-
351
- import type { Session as OpensaasSession, StorageUtils, ServerActionProps, AccessControlledDB, AccessContext } from '@opensaas/stack-core'
352
- import type { PrismaClient, Prisma } from './prisma-client/client'
353
- import type { PluginServices } from './plugin-types'
354
-
355
- /**
356
- * Custom DB type that uses Prisma's conditional types with virtual and transformed field support
357
- * Types change based on select/include - relationships only present when explicitly included
358
- * Virtual fields and transformed fields are added to the base model type
359
- */
360
- export type CustomDB = Omit<AccessControlledDB<PrismaClient>,
361
-
362
- > & {
363
- }
364
-
365
- /**
366
- * Context type compatible with AccessContext but with CustomDB for virtual field typing
367
- * Extends AccessContext and overrides db property to include virtual fields in output types
368
- */
369
- export type Context<TSession extends OpensaasSession = OpensaasSession> = Omit<AccessContext<PrismaClient>, 'db' | 'session'> & {
370
- db: CustomDB
371
- session: TSession
372
- serverAction: (props: ServerActionProps) => Promise<unknown>
373
- sudo: () => Context<TSession>
374
- }"
375
- `;
376
-
377
- exports[`Generate Command Integration > Generator Integration > should overwrite existing files > overwrite-after 1`] = `
378
- "generator client {
379
- provider = "prisma-client"
380
- output = "../.opensaas/prisma-client"
381
- }
382
-
383
- datasource db {
384
- provider = "sqlite"
385
- }
386
-
387
- model Post {
388
- id String @id @default(cuid())
389
- title String?
390
- createdAt DateTime @default(now())
391
- updatedAt DateTime @updatedAt
392
- }
393
- "
394
- `;
395
-
396
- exports[`Generate Command Integration > Generator Integration > should overwrite existing files > overwrite-before 1`] = `
397
- "generator client {
398
- provider = "prisma-client"
399
- output = "../.opensaas/prisma-client"
400
- }
401
-
402
- datasource db {
403
- provider = "sqlite"
404
- }
405
-
406
- model User {
407
- id String @id @default(cuid())
408
- name String?
409
- createdAt DateTime @default(now())
410
- updatedAt DateTime @updatedAt
411
- }
412
- "
413
- `;