@opensaas/stack-cli 0.5.0 → 0.6.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.
- package/README.md +76 -0
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +91 -265
- package/dist/commands/migrate.js.map +1 -1
- package/package.json +7 -2
- package/plugin/.claude-plugin/plugin.json +15 -0
- package/plugin/README.md +112 -0
- package/plugin/agents/migration-assistant.md +150 -0
- package/plugin/commands/analyze-schema.md +34 -0
- package/plugin/commands/generate-config.md +33 -0
- package/plugin/commands/validate-migration.md +34 -0
- package/plugin/skills/opensaas-migration/SKILL.md +192 -0
- package/.turbo/turbo-build.log +0 -4
- package/CHANGELOG.md +0 -462
- package/CLAUDE.md +0 -298
- package/src/commands/__snapshots__/generate.test.ts.snap +0 -413
- package/src/commands/dev.test.ts +0 -215
- package/src/commands/dev.ts +0 -48
- package/src/commands/generate.test.ts +0 -282
- package/src/commands/generate.ts +0 -182
- package/src/commands/init.ts +0 -34
- package/src/commands/mcp.ts +0 -135
- package/src/commands/migrate.ts +0 -534
- package/src/generator/__snapshots__/context.test.ts.snap +0 -361
- package/src/generator/__snapshots__/prisma.test.ts.snap +0 -174
- package/src/generator/__snapshots__/types.test.ts.snap +0 -1702
- package/src/generator/context.test.ts +0 -139
- package/src/generator/context.ts +0 -227
- package/src/generator/index.ts +0 -7
- package/src/generator/lists.test.ts +0 -335
- package/src/generator/lists.ts +0 -140
- package/src/generator/plugin-types.ts +0 -147
- package/src/generator/prisma-config.ts +0 -46
- package/src/generator/prisma-extensions.ts +0 -159
- package/src/generator/prisma.test.ts +0 -211
- package/src/generator/prisma.ts +0 -161
- package/src/generator/types.test.ts +0 -268
- package/src/generator/types.ts +0 -537
- package/src/index.ts +0 -46
- package/src/mcp/lib/documentation-provider.ts +0 -710
- package/src/mcp/lib/features/catalog.ts +0 -301
- package/src/mcp/lib/generators/feature-generator.ts +0 -598
- package/src/mcp/lib/types.ts +0 -89
- package/src/mcp/lib/wizards/migration-wizard.ts +0 -584
- package/src/mcp/lib/wizards/wizard-engine.ts +0 -427
- package/src/mcp/server/index.ts +0 -361
- package/src/mcp/server/stack-mcp-server.ts +0 -544
- package/src/migration/generators/migration-generator.ts +0 -675
- package/src/migration/introspectors/index.ts +0 -12
- package/src/migration/introspectors/keystone-introspector.ts +0 -296
- package/src/migration/introspectors/nextjs-introspector.ts +0 -209
- package/src/migration/introspectors/prisma-introspector.ts +0 -233
- package/src/migration/types.ts +0 -92
- package/tests/introspectors/keystone-introspector.test.ts +0 -255
- package/tests/introspectors/nextjs-introspector.test.ts +0 -302
- package/tests/introspectors/prisma-introspector.test.ts +0 -268
- package/tests/migration-generator.test.ts +0 -592
- package/tests/migration-wizard.test.ts +0 -442
- package/tsconfig.json +0 -13
- package/tsconfig.tsbuildinfo +0 -1
- 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
|
-
`;
|