@opensaas/stack-cli 0.1.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 (51) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/README.md +328 -0
  3. package/bin/opensaas.js +3 -0
  4. package/dist/commands/dev.d.ts +2 -0
  5. package/dist/commands/dev.d.ts.map +1 -0
  6. package/dist/commands/dev.js +40 -0
  7. package/dist/commands/dev.js.map +1 -0
  8. package/dist/commands/generate.d.ts +2 -0
  9. package/dist/commands/generate.d.ts.map +1 -0
  10. package/dist/commands/generate.js +90 -0
  11. package/dist/commands/generate.js.map +1 -0
  12. package/dist/commands/init.d.ts +2 -0
  13. package/dist/commands/init.d.ts.map +1 -0
  14. package/dist/commands/init.js +343 -0
  15. package/dist/commands/init.js.map +1 -0
  16. package/dist/generator/context.d.ts +13 -0
  17. package/dist/generator/context.d.ts.map +1 -0
  18. package/dist/generator/context.js +69 -0
  19. package/dist/generator/context.js.map +1 -0
  20. package/dist/generator/index.d.ts +5 -0
  21. package/dist/generator/index.d.ts.map +1 -0
  22. package/dist/generator/index.js +5 -0
  23. package/dist/generator/index.js.map +1 -0
  24. package/dist/generator/prisma.d.ts +10 -0
  25. package/dist/generator/prisma.d.ts.map +1 -0
  26. package/dist/generator/prisma.js +129 -0
  27. package/dist/generator/prisma.js.map +1 -0
  28. package/dist/generator/type-patcher.d.ts +13 -0
  29. package/dist/generator/type-patcher.d.ts.map +1 -0
  30. package/dist/generator/type-patcher.js +68 -0
  31. package/dist/generator/type-patcher.js.map +1 -0
  32. package/dist/generator/types.d.ts +10 -0
  33. package/dist/generator/types.d.ts.map +1 -0
  34. package/dist/generator/types.js +225 -0
  35. package/dist/generator/types.js.map +1 -0
  36. package/dist/index.d.ts +3 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +28 -0
  39. package/dist/index.js.map +1 -0
  40. package/package.json +48 -0
  41. package/src/commands/dev.ts +48 -0
  42. package/src/commands/generate.ts +103 -0
  43. package/src/commands/init.ts +367 -0
  44. package/src/generator/context.ts +75 -0
  45. package/src/generator/index.ts +4 -0
  46. package/src/generator/prisma.ts +157 -0
  47. package/src/generator/type-patcher.ts +93 -0
  48. package/src/generator/types.ts +263 -0
  49. package/src/index.ts +34 -0
  50. package/tsconfig.json +13 -0
  51. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,343 @@
1
+ import * as path from 'path';
2
+ import * as fs from 'fs';
3
+ import chalk from 'chalk';
4
+ import ora from 'ora';
5
+ import prompts from 'prompts';
6
+ export async function initCommand(projectName) {
7
+ console.log(chalk.bold.cyan('\n🚀 Create OpenSaas Project\n'));
8
+ // Prompt for project name if not provided
9
+ if (!projectName) {
10
+ const response = await prompts({
11
+ type: 'text',
12
+ name: 'name',
13
+ message: 'Project name:',
14
+ initial: 'my-opensaas-app',
15
+ validate: (value) => {
16
+ if (!value)
17
+ return 'Project name is required';
18
+ if (!/^[a-z0-9-]+$/.test(value)) {
19
+ return 'Project name must contain only lowercase letters, numbers, and hyphens';
20
+ }
21
+ return true;
22
+ },
23
+ });
24
+ if (!response.name) {
25
+ console.log(chalk.yellow('\n❌ Cancelled'));
26
+ process.exit(0);
27
+ }
28
+ projectName = response.name;
29
+ }
30
+ // Type guard to ensure projectName is defined
31
+ if (!projectName) {
32
+ console.error(chalk.red('\n❌ Project name is required'));
33
+ process.exit(1);
34
+ }
35
+ const projectPath = path.join(process.cwd(), projectName);
36
+ // Check if directory already exists
37
+ if (fs.existsSync(projectPath)) {
38
+ console.error(chalk.red(`\n❌ Directory "${projectName}" already exists`));
39
+ process.exit(1);
40
+ }
41
+ const spinner = ora('Creating project structure...').start();
42
+ try {
43
+ // Create project directory
44
+ fs.mkdirSync(projectPath, { recursive: true });
45
+ // Create basic structure
46
+ fs.mkdirSync(path.join(projectPath, 'app'), { recursive: true });
47
+ fs.mkdirSync(path.join(projectPath, 'lib'), { recursive: true });
48
+ fs.mkdirSync(path.join(projectPath, 'prisma'), { recursive: true });
49
+ spinner.text = 'Writing configuration files...';
50
+ // Create package.json
51
+ const packageJson = {
52
+ name: projectName,
53
+ version: '0.1.0',
54
+ private: true,
55
+ scripts: {
56
+ dev: 'next dev',
57
+ build: 'next build',
58
+ start: 'next start',
59
+ generate: 'opensaas generate',
60
+ 'db:push': 'prisma db push',
61
+ 'db:studio': 'prisma studio',
62
+ },
63
+ dependencies: {
64
+ '@opensaas/stack-core': '^0.1.0',
65
+ '@prisma/client': '^5.7.1',
66
+ next: '^14.0.4',
67
+ react: '^18.2.0',
68
+ 'react-dom': '^18.2.0',
69
+ },
70
+ devDependencies: {
71
+ '@opensaas/stack-cli': '^0.1.0',
72
+ '@types/node': '^20.10.0',
73
+ '@types/react': '^18.2.45',
74
+ '@types/react-dom': '^18.2.18',
75
+ prisma: '^5.7.1',
76
+ tsx: '^4.7.0',
77
+ typescript: '^5.3.3',
78
+ },
79
+ };
80
+ fs.writeFileSync(path.join(projectPath, 'package.json'), JSON.stringify(packageJson, null, 2));
81
+ // Create tsconfig.json
82
+ const tsConfig = {
83
+ compilerOptions: {
84
+ target: 'ES2022',
85
+ lib: ['dom', 'dom.iterable', 'esnext'],
86
+ allowJs: true,
87
+ skipLibCheck: true,
88
+ strict: true,
89
+ noEmit: true,
90
+ esModuleInterop: true,
91
+ module: 'esnext',
92
+ moduleResolution: 'bundler',
93
+ resolveJsonModule: true,
94
+ isolatedModules: true,
95
+ jsx: 'preserve',
96
+ incremental: true,
97
+ plugins: [{ name: 'next' }],
98
+ paths: {
99
+ '@/*': ['./*'],
100
+ },
101
+ },
102
+ include: ['next-env.d.ts', '**/*.ts', '**/*.tsx', '.next/types/**/*.ts'],
103
+ exclude: ['node_modules'],
104
+ };
105
+ fs.writeFileSync(path.join(projectPath, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
106
+ // Create next.config.js
107
+ const nextConfig = `/** @type {import('next').NextConfig} */
108
+ const nextConfig = {
109
+ experimental: {
110
+ serverComponentsExternalPackages: ['@prisma/client', '@opensaas/stack-core'],
111
+ },
112
+ }
113
+
114
+ module.exports = nextConfig
115
+ `;
116
+ fs.writeFileSync(path.join(projectPath, 'next.config.js'), nextConfig);
117
+ // Create .env
118
+ const env = `DATABASE_URL="file:./dev.db"
119
+ `;
120
+ fs.writeFileSync(path.join(projectPath, '.env'), env);
121
+ // Create .gitignore
122
+ const gitignore = `# Dependencies
123
+ node_modules
124
+ .pnp
125
+ .pnp.js
126
+
127
+ # Testing
128
+ coverage
129
+
130
+ # Next.js
131
+ .next
132
+ out
133
+
134
+ # Production
135
+ build
136
+ dist
137
+
138
+ # Misc
139
+ .DS_Store
140
+ *.pem
141
+
142
+ # Debug
143
+ npm-debug.log*
144
+ yarn-debug.log*
145
+ yarn-error.log*
146
+
147
+ # Local env files
148
+ .env
149
+ .env.local
150
+ .env.development.local
151
+ .env.test.local
152
+ .env.production.local
153
+
154
+ # Vercel
155
+ .vercel
156
+
157
+ # TypeScript
158
+ *.tsbuildinfo
159
+
160
+ # OpenSaas generated
161
+ .opensaas
162
+
163
+ # Prisma
164
+ prisma/dev.db
165
+ prisma/dev.db-journal
166
+ `;
167
+ fs.writeFileSync(path.join(projectPath, '.gitignore'), gitignore);
168
+ // Create opensaas.config.ts
169
+ const config = `import { config, list } from '@opensaas/stack-core'
170
+ import { text, relationship, password } from '@opensaas/stack-core/fields'
171
+ import type { AccessControl } from '@opensaas/stack-core'
172
+
173
+ // Access control helpers
174
+ const isSignedIn: AccessControl = ({ session }) => {
175
+ return !!session
176
+ }
177
+
178
+ export default config({
179
+ db: {
180
+ provider: 'sqlite',
181
+ url: process.env.DATABASE_URL || 'file:./dev.db',
182
+ },
183
+
184
+ lists: {
185
+ User: list({
186
+ fields: {
187
+ name: text({ validation: { isRequired: true } }),
188
+ email: text({
189
+ validation: { isRequired: true },
190
+ isIndexed: 'unique',
191
+ }),
192
+ password: password({ validation: { isRequired: true } }),
193
+ },
194
+ }),
195
+ },
196
+
197
+ session: {
198
+ getSession: async () => {
199
+ // TODO: Integrate with your auth system
200
+ return null
201
+ }
202
+ },
203
+
204
+ ui: {
205
+ basePath: '/admin',
206
+ }
207
+ })
208
+ `;
209
+ fs.writeFileSync(path.join(projectPath, 'opensaas.config.ts'), config);
210
+ // Create lib/context.ts
211
+ const contextFile = `import { PrismaClient } from '@prisma/client'
212
+ import { getContext as createContext } from '@opensaas/stack-core'
213
+ import config from '../opensaas.config'
214
+ import type { Context } from '../.opensaas/types'
215
+
216
+ // Singleton Prisma client
217
+ const globalForPrisma = globalThis as unknown as {
218
+ prisma: PrismaClient | undefined
219
+ }
220
+
221
+ export const prisma = globalForPrisma.prisma ?? new PrismaClient()
222
+
223
+ if (process.env.NODE_ENV !== 'production') {
224
+ globalForPrisma.prisma = prisma
225
+ }
226
+
227
+ /**
228
+ * Get an access-controlled context for the current session
229
+ */
230
+ export async function getContext(): Promise<Context> {
231
+ const session = config.session ? await config.session.getSession() : null
232
+ const context = await createContext<PrismaClient>(config, prisma, session)
233
+ return context as Context
234
+ }
235
+ `;
236
+ fs.writeFileSync(path.join(projectPath, 'lib', 'context.ts'), contextFile);
237
+ // Create app/page.tsx
238
+ const page = `export default function Home() {
239
+ return (
240
+ <main className="flex min-h-screen flex-col items-center justify-center p-24">
241
+ <h1 className="text-4xl font-bold mb-4">Welcome to OpenSaas</h1>
242
+ <p className="text-gray-600">Your project is ready to go!</p>
243
+
244
+ <div className="mt-8 space-y-2">
245
+ <p className="text-sm">Next steps:</p>
246
+ <ol className="text-sm text-gray-600 list-decimal list-inside space-y-1">
247
+ <li>Run <code className="bg-gray-100 px-2 py-1 rounded">npm run generate</code></li>
248
+ <li>Run <code className="bg-gray-100 px-2 py-1 rounded">npm run db:push</code></li>
249
+ <li>Edit <code className="bg-gray-100 px-2 py-1 rounded">opensaas.config.ts</code> to define your schema</li>
250
+ </ol>
251
+ </div>
252
+ </main>
253
+ )
254
+ }
255
+ `;
256
+ fs.writeFileSync(path.join(projectPath, 'app', 'page.tsx'), page);
257
+ // Create app/layout.tsx
258
+ const layout = `export const metadata = {
259
+ title: '${projectName}',
260
+ description: 'Built with OpenSaas',
261
+ }
262
+
263
+ export default function RootLayout({
264
+ children,
265
+ }: {
266
+ children: React.ReactNode
267
+ }) {
268
+ return (
269
+ <html lang="en">
270
+ <body>{children}</body>
271
+ </html>
272
+ )
273
+ }
274
+ `;
275
+ fs.writeFileSync(path.join(projectPath, 'app', 'layout.tsx'), layout);
276
+ // Create README.md
277
+ const readme = `# ${projectName}
278
+
279
+ Built with [OpenSaas Stack](https://github.com/your-org/opensaas-stack)
280
+
281
+ ## Getting Started
282
+
283
+ 1. Install dependencies:
284
+ \`\`\`bash
285
+ npm install
286
+ # or
287
+ pnpm install
288
+ \`\`\`
289
+
290
+ 2. Generate Prisma schema and types:
291
+ \`\`\`bash
292
+ npm run generate
293
+ \`\`\`
294
+
295
+ 3. Push schema to database:
296
+ \`\`\`bash
297
+ npm run db:push
298
+ \`\`\`
299
+
300
+ 4. Run the development server:
301
+ \`\`\`bash
302
+ npm run dev
303
+ \`\`\`
304
+
305
+ Open [http://localhost:3000](http://localhost:3000) to see your app.
306
+
307
+ ## Project Structure
308
+
309
+ - \`opensaas.config.ts\` - Your schema definition with access control
310
+ - \`lib/context.ts\` - Database context with access control
311
+ - \`app/\` - Next.js app router pages
312
+ - \`prisma/\` - Generated Prisma schema
313
+ - \`.opensaas/\` - Generated TypeScript types
314
+
315
+ ## Learn More
316
+
317
+ - [OpenSaas Documentation](https://github.com/your-org/opensaas-stack)
318
+ - [Next.js Documentation](https://nextjs.org/docs)
319
+ - [Prisma Documentation](https://www.prisma.io/docs)
320
+ `;
321
+ fs.writeFileSync(path.join(projectPath, 'README.md'), readme);
322
+ spinner.succeed(chalk.green('Project created successfully!'));
323
+ console.log(chalk.bold.green(`\n✨ Created ${projectName}\n`));
324
+ console.log(chalk.gray('Next steps:\n'));
325
+ console.log(chalk.cyan(` cd ${projectName}`));
326
+ console.log(chalk.cyan(' npm install'));
327
+ console.log(chalk.cyan(' npm run generate'));
328
+ console.log(chalk.cyan(' npm run db:push'));
329
+ console.log(chalk.cyan(' npm run dev'));
330
+ console.log();
331
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
332
+ }
333
+ catch (error) {
334
+ spinner.fail(chalk.red('Failed to create project'));
335
+ console.error(chalk.red('\n❌ Error:'), error.message);
336
+ // Cleanup on failure
337
+ if (fs.existsSync(projectPath)) {
338
+ fs.rmSync(projectPath, { recursive: true, force: true });
339
+ }
340
+ process.exit(1);
341
+ }
342
+ }
343
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { OpenSaasConfig } from '@opensaas/stack-core';
2
+ /**
3
+ * Generate context factory that abstracts Prisma client from developers
4
+ *
5
+ * Creates a simple API with getContext() and getContextWithSession(session)
6
+ * that internally handles Prisma singleton and config imports.
7
+ */
8
+ export declare function generateContext(config: OpenSaasConfig): string;
9
+ /**
10
+ * Write context factory to file
11
+ */
12
+ export declare function writeContext(config: OpenSaasConfig, outputPath: string): void;
13
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/generator/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAI1D;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAiD9D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAU7E"}
@@ -0,0 +1,69 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ /**
4
+ * Generate context factory that abstracts Prisma client from developers
5
+ *
6
+ * Creates a simple API with getContext() and getContextWithSession(session)
7
+ * that internally handles Prisma singleton and config imports.
8
+ */
9
+ export function generateContext(config) {
10
+ // Check if custom Prisma client constructor is provided
11
+ const hasCustomConstructor = !!config.db.prismaClientConstructor;
12
+ // Generate the Prisma client instantiation code
13
+ const prismaInstantiation = hasCustomConstructor
14
+ ? `config.db.prismaClientConstructor!(PrismaClient)`
15
+ : `new PrismaClient()`;
16
+ return `/**
17
+ * Auto-generated context factory
18
+ *
19
+ * This module provides a simple API for creating OpenSaas contexts.
20
+ * It abstracts away Prisma client management and configuration.
21
+ *
22
+ * DO NOT EDIT - This file is automatically generated by 'pnpm generate'
23
+ */
24
+
25
+ import { getContext as getOpensaasContext } from '@opensaas/stack-core'
26
+ import { PrismaClient } from './prisma-client'
27
+ import config from '../opensaas.config'
28
+
29
+ // Internal Prisma singleton - managed automatically
30
+ const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined }
31
+ const prisma = globalForPrisma.prisma ?? ${prismaInstantiation}
32
+ if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
33
+
34
+ /**
35
+ * Get OpenSaas context with optional session
36
+ *
37
+ * @param session - Optional session object (structure defined by your application)
38
+ *
39
+ * @example
40
+ * \`\`\`typescript
41
+ * // Anonymous access
42
+ * const context = getContext()
43
+ * const posts = await context.db.post.findMany()
44
+ *
45
+ * // Authenticated access
46
+ * const context = getContext({ userId: 'user-123' })
47
+ * const myPosts = await context.db.post.findMany()
48
+ * \`\`\`
49
+ */
50
+ export function getContext(session?: { userId?: string; [key: string]: unknown } | null) {
51
+ return getOpensaasContext(config, prisma, session ?? null)
52
+ }
53
+
54
+ export const rawOpensaasContext = getContext()
55
+ `;
56
+ }
57
+ /**
58
+ * Write context factory to file
59
+ */
60
+ export function writeContext(config, outputPath) {
61
+ const content = generateContext(config);
62
+ // Ensure directory exists
63
+ const dir = path.dirname(outputPath);
64
+ if (!fs.existsSync(dir)) {
65
+ fs.mkdirSync(dir, { recursive: true });
66
+ }
67
+ fs.writeFileSync(outputPath, content, 'utf-8');
68
+ }
69
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/generator/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAAsB;IACpD,wDAAwD;IACxD,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,uBAAuB,CAAA;IAEhE,gDAAgD;IAChD,MAAM,mBAAmB,GAAG,oBAAoB;QAC9C,CAAC,CAAC,kDAAkD;QACpD,CAAC,CAAC,oBAAoB,CAAA;IAExB,OAAO;;;;;;;;;;;;;;;2CAekC,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;CAwB7D,CAAA;AACD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAsB,EAAE,UAAkB;IACrE,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,CAAA;IAEvC,0BAA0B;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACpC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACxC,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;AAChD,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { generatePrismaSchema, writePrismaSchema } from './prisma.js';
2
+ export { generateTypes, writeTypes } from './types.js';
3
+ export { patchPrismaTypes } from './type-patcher.js';
4
+ export { generateContext, writeContext } from './context.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,5 @@
1
+ export { generatePrismaSchema, writePrismaSchema } from './prisma.js';
2
+ export { generateTypes, writeTypes } from './types.js';
3
+ export { patchPrismaTypes } from './type-patcher.js';
4
+ export { generateContext, writeContext } from './context.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA"}
@@ -0,0 +1,10 @@
1
+ import type { OpenSaasConfig } from '@opensaas/stack-core';
2
+ /**
3
+ * Generate Prisma schema from OpenSaas config
4
+ */
5
+ export declare function generatePrismaSchema(config: OpenSaasConfig): string;
6
+ /**
7
+ * Write Prisma schema to file
8
+ */
9
+ export declare function writePrismaSchema(config: OpenSaasConfig, outputPath: string): void;
10
+ //# sourceMappingURL=prisma.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/generator/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAkC,MAAM,sBAAsB,CAAA;AA0D1F;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAgFnE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAUlF"}
@@ -0,0 +1,129 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ /**
4
+ * Map OpenSaas field types to Prisma field types
5
+ */
6
+ function mapFieldTypeToPrisma(fieldName, field) {
7
+ // Relationships are handled separately
8
+ if (field.type === 'relationship') {
9
+ return null;
10
+ }
11
+ // Use field's own Prisma type generator if available
12
+ if (field.getPrismaType) {
13
+ const result = field.getPrismaType(fieldName);
14
+ return result.type;
15
+ }
16
+ // Fallback for fields without generator methods
17
+ throw new Error(`Field type "${field.type}" does not implement getPrismaType method`);
18
+ }
19
+ /**
20
+ * Get field modifiers (?, @default, @unique, etc.)
21
+ */
22
+ function getFieldModifiers(fieldName, field) {
23
+ // Handle relationships separately
24
+ if (field.type === 'relationship') {
25
+ const relField = field;
26
+ if (relField.many) {
27
+ return '[]';
28
+ }
29
+ else {
30
+ return '?';
31
+ }
32
+ }
33
+ // Use field's own Prisma type generator if available
34
+ if (field.getPrismaType) {
35
+ const result = field.getPrismaType(fieldName);
36
+ return result.modifiers || '';
37
+ }
38
+ // Fallback for fields without generator methods
39
+ return '';
40
+ }
41
+ /**
42
+ * Parse relationship ref to get target list and field
43
+ */
44
+ function parseRelationshipRef(ref) {
45
+ const [list, field] = ref.split('.');
46
+ if (!list || !field) {
47
+ throw new Error(`Invalid relationship ref: ${ref}`);
48
+ }
49
+ return { list, field };
50
+ }
51
+ /**
52
+ * Generate Prisma schema from OpenSaas config
53
+ */
54
+ export function generatePrismaSchema(config) {
55
+ const lines = [];
56
+ const opensaasPath = config.opensaasPath || '.opensaas';
57
+ // Generator and datasource
58
+ lines.push('generator client {');
59
+ lines.push(' provider = "prisma-client-js"');
60
+ lines.push(` output = "../${opensaasPath}/prisma-client"`);
61
+ lines.push('}');
62
+ lines.push('');
63
+ lines.push('datasource db {');
64
+ lines.push(` provider = "${config.db.provider}"`);
65
+ lines.push(' url = env("DATABASE_URL")');
66
+ lines.push('}');
67
+ lines.push('');
68
+ // Generate models for each list
69
+ for (const [listName, listConfig] of Object.entries(config.lists)) {
70
+ lines.push(`model ${listName} {`);
71
+ // Always add id field
72
+ lines.push(' id String @id @default(cuid())');
73
+ // Track relationship fields for later processing
74
+ const relationshipFields = [];
75
+ // Add regular fields
76
+ for (const [fieldName, fieldConfig] of Object.entries(listConfig.fields)) {
77
+ if (fieldConfig.type === 'relationship') {
78
+ relationshipFields.push({
79
+ name: fieldName,
80
+ field: fieldConfig,
81
+ });
82
+ continue;
83
+ }
84
+ const prismaType = mapFieldTypeToPrisma(fieldName, fieldConfig);
85
+ if (!prismaType)
86
+ continue; // Skip if no type returned
87
+ const modifiers = getFieldModifiers(fieldName, fieldConfig);
88
+ // Format with proper spacing
89
+ const paddedName = fieldName.padEnd(12);
90
+ lines.push(` ${paddedName} ${prismaType}${modifiers}`);
91
+ }
92
+ // Add relationship fields
93
+ for (const { name: fieldName, field: relField } of relationshipFields) {
94
+ const { list: targetList } = parseRelationshipRef(relField.ref);
95
+ const _modifiers = getFieldModifiers(fieldName, relField);
96
+ const paddedName = fieldName.padEnd(12);
97
+ if (relField.many) {
98
+ // One-to-many relationship
99
+ lines.push(` ${paddedName} ${targetList}[]`);
100
+ }
101
+ else {
102
+ // Many-to-one relationship (add foreign key field)
103
+ const foreignKeyField = `${fieldName}Id`;
104
+ const fkPaddedName = foreignKeyField.padEnd(12);
105
+ lines.push(` ${fkPaddedName} String?`);
106
+ lines.push(` ${paddedName} ${targetList}? @relation(fields: [${foreignKeyField}], references: [id])`);
107
+ }
108
+ }
109
+ // Always add timestamps
110
+ lines.push(' createdAt DateTime @default(now())');
111
+ lines.push(' updatedAt DateTime @updatedAt');
112
+ lines.push('}');
113
+ lines.push('');
114
+ }
115
+ return lines.join('\n');
116
+ }
117
+ /**
118
+ * Write Prisma schema to file
119
+ */
120
+ export function writePrismaSchema(config, outputPath) {
121
+ const schema = generatePrismaSchema(config);
122
+ // Ensure directory exists
123
+ const dir = path.dirname(outputPath);
124
+ if (!fs.existsSync(dir)) {
125
+ fs.mkdirSync(dir, { recursive: true });
126
+ }
127
+ fs.writeFileSync(outputPath, schema, 'utf-8');
128
+ }
129
+ //# sourceMappingURL=prisma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/generator/prisma.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B;;GAEG;AACH,SAAS,oBAAoB,CAAC,SAAiB,EAAE,KAAkB;IACjE,uCAAuC;IACvC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QAClC,OAAO,IAAI,CAAA;IACb,CAAC;IAED,qDAAqD;IACrD,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;QAC7C,OAAO,MAAM,CAAC,IAAI,CAAA;IACpB,CAAC;IAED,gDAAgD;IAChD,MAAM,IAAI,KAAK,CAAC,eAAe,KAAK,CAAC,IAAI,2CAA2C,CAAC,CAAA;AACvF,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,SAAiB,EAAE,KAAkB;IAC9D,kCAAkC;IAClC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,KAA0B,CAAA;QAC3C,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAClB,OAAO,IAAI,CAAA;QACb,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,CAAA;QACZ,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;QAC7C,OAAO,MAAM,CAAC,SAAS,IAAI,EAAE,CAAA;IAC/B,CAAC;IAED,gDAAgD;IAChD,OAAO,EAAE,CAAA;AACX,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,GAAW;IACvC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACpC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAA;IACrD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,WAAW,CAAA;IAEvD,2BAA2B;IAC3B,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;IAChC,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAA;IAC7C,KAAK,CAAC,IAAI,CAAC,oBAAoB,YAAY,iBAAiB,CAAC,CAAA;IAC7D,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACd,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAC7B,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,EAAE,CAAC,QAAQ,GAAG,CAAC,CAAA;IAClD,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAA;IAC9C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAEd,gCAAgC;IAChC,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAClE,KAAK,CAAC,IAAI,CAAC,SAAS,QAAQ,IAAI,CAAC,CAAA;QAEjC,sBAAsB;QACtB,KAAK,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;QAEvD,iDAAiD;QACjD,MAAM,kBAAkB,GAGnB,EAAE,CAAA;QAEP,qBAAqB;QACrB,KAAK,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACzE,IAAI,WAAW,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBACxC,kBAAkB,CAAC,IAAI,CAAC;oBACtB,IAAI,EAAE,SAAS;oBACf,KAAK,EAAE,WAAgC;iBACxC,CAAC,CAAA;gBACF,SAAQ;YACV,CAAC;YAED,MAAM,UAAU,GAAG,oBAAoB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;YAC/D,IAAI,CAAC,UAAU;gBAAE,SAAQ,CAAC,2BAA2B;YAErD,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;YAE3D,6BAA6B;YAC7B,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACvC,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,IAAI,UAAU,GAAG,SAAS,EAAE,CAAC,CAAA;QACzD,CAAC;QAED,0BAA0B;QAC1B,KAAK,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,kBAAkB,EAAE,CAAC;YACtE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,oBAAoB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;YAC/D,MAAM,UAAU,GAAG,iBAAiB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;YACzD,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YAEvC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAClB,2BAA2B;gBAC3B,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,IAAI,UAAU,IAAI,CAAC,CAAA;YAC/C,CAAC;iBAAM,CAAC;gBACN,mDAAmD;gBACnD,MAAM,eAAe,GAAG,GAAG,SAAS,IAAI,CAAA;gBACxC,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;gBAE/C,KAAK,CAAC,IAAI,CAAC,KAAK,YAAY,UAAU,CAAC,CAAA;gBACvC,KAAK,CAAC,IAAI,CACR,KAAK,UAAU,IAAI,UAAU,yBAAyB,eAAe,sBAAsB,CAC5F,CAAA;YACH,CAAC;QACH,CAAC;QAED,wBAAwB;QACxB,KAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAA;QAClD,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAA;QAE7C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACf,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAsB,EAAE,UAAkB;IAC1E,MAAM,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAA;IAE3C,0BAA0B;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IACpC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACxC,CAAC;IAED,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;AAC/C,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { OpenSaasConfig } from '@opensaas/stack-core';
2
+ /**
3
+ * Patches Prisma's generated types based on field-level type patch configurations
4
+ *
5
+ * This reads Prisma's generated index.d.ts and replaces field types according to
6
+ * the `typePatch` configuration on each field. Fields can specify custom result types
7
+ * that will replace the original Prisma types in query results.
8
+ *
9
+ * The patched types are written to `.opensaas/prisma-client.d.ts` so users can
10
+ * import from there to get the transformed types.
11
+ */
12
+ export declare function patchPrismaTypes(config: OpenSaasConfig, projectRoot: string): void;
13
+ //# sourceMappingURL=type-patcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-patcher.d.ts","sourceRoot":"","sources":["../../src/generator/type-patcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAI1D;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CA8ElF"}