@opensaas/stack-cli 0.4.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 +9 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +299 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/lib/documentation-provider.d.ts +23 -0
- package/dist/mcp/lib/documentation-provider.d.ts.map +1 -1
- package/dist/mcp/lib/documentation-provider.js +471 -0
- package/dist/mcp/lib/documentation-provider.js.map +1 -1
- package/dist/mcp/lib/wizards/migration-wizard.d.ts +80 -0
- package/dist/mcp/lib/wizards/migration-wizard.d.ts.map +1 -0
- package/dist/mcp/lib/wizards/migration-wizard.js +499 -0
- package/dist/mcp/lib/wizards/migration-wizard.js.map +1 -0
- package/dist/mcp/server/index.d.ts.map +1 -1
- package/dist/mcp/server/index.js +103 -0
- package/dist/mcp/server/index.js.map +1 -1
- package/dist/mcp/server/stack-mcp-server.d.ts +85 -0
- package/dist/mcp/server/stack-mcp-server.d.ts.map +1 -1
- package/dist/mcp/server/stack-mcp-server.js +219 -0
- package/dist/mcp/server/stack-mcp-server.js.map +1 -1
- package/dist/migration/generators/migration-generator.d.ts +60 -0
- package/dist/migration/generators/migration-generator.d.ts.map +1 -0
- package/dist/migration/generators/migration-generator.js +510 -0
- package/dist/migration/generators/migration-generator.js.map +1 -0
- package/dist/migration/introspectors/index.d.ts +12 -0
- package/dist/migration/introspectors/index.d.ts.map +1 -0
- package/dist/migration/introspectors/index.js +10 -0
- package/dist/migration/introspectors/index.js.map +1 -0
- package/dist/migration/introspectors/keystone-introspector.d.ts +59 -0
- package/dist/migration/introspectors/keystone-introspector.d.ts.map +1 -0
- package/dist/migration/introspectors/keystone-introspector.js +229 -0
- package/dist/migration/introspectors/keystone-introspector.js.map +1 -0
- package/dist/migration/introspectors/nextjs-introspector.d.ts +59 -0
- package/dist/migration/introspectors/nextjs-introspector.d.ts.map +1 -0
- package/dist/migration/introspectors/nextjs-introspector.js +159 -0
- package/dist/migration/introspectors/nextjs-introspector.js.map +1 -0
- package/dist/migration/introspectors/prisma-introspector.d.ts +45 -0
- package/dist/migration/introspectors/prisma-introspector.d.ts.map +1 -0
- package/dist/migration/introspectors/prisma-introspector.js +190 -0
- package/dist/migration/introspectors/prisma-introspector.js.map +1 -0
- package/dist/migration/types.d.ts +86 -0
- package/dist/migration/types.d.ts.map +1 -0
- package/dist/migration/types.js +5 -0
- package/dist/migration/types.js.map +1 -0
- package/package.json +10 -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 -410
- 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/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 -42
- package/src/mcp/lib/documentation-provider.ts +0 -203
- 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/wizard-engine.ts +0 -427
- package/src/mcp/server/index.ts +0 -240
- package/src/mcp/server/stack-mcp-server.ts +0 -301
- package/tsconfig.json +0 -13
- package/tsconfig.tsbuildinfo +0 -1
- package/vitest.config.ts +0 -26
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Validate the generated opensaas.config.ts file
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Validate the generated opensaas.config.ts file.
|
|
6
|
+
|
|
7
|
+
## Instructions
|
|
8
|
+
|
|
9
|
+
1. Check if opensaas.config.ts exists in the project root
|
|
10
|
+
|
|
11
|
+
2. If it exists, verify:
|
|
12
|
+
- Syntax is valid TypeScript
|
|
13
|
+
- All imports are correct
|
|
14
|
+
- Database config is complete
|
|
15
|
+
- Lists match original schema
|
|
16
|
+
|
|
17
|
+
3. Try running:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx @opensaas/stack-cli generate
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
4. Report any errors and suggest fixes
|
|
24
|
+
|
|
25
|
+
5. If validation passes, confirm next steps:
|
|
26
|
+
- `npx prisma generate`
|
|
27
|
+
- `npx prisma db push`
|
|
28
|
+
- `pnpm dev`
|
|
29
|
+
|
|
30
|
+
## Common Issues
|
|
31
|
+
|
|
32
|
+
- Missing dependencies → suggest `pnpm add ...`
|
|
33
|
+
- Database URL not set → remind about .env file
|
|
34
|
+
- Type errors → suggest specific fixes
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: opensaas-migration
|
|
3
|
+
description: Expert knowledge for migrating projects to OpenSaaS Stack. Use when discussing migration strategies, access control patterns, or OpenSaaS Stack configuration best practices.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# OpenSaaS Stack Migration
|
|
7
|
+
|
|
8
|
+
Expert guidance for migrating existing projects to OpenSaaS Stack.
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
Use this skill when:
|
|
13
|
+
|
|
14
|
+
- Planning a migration from Prisma, KeystoneJS, or Next.js
|
|
15
|
+
- Designing access control patterns
|
|
16
|
+
- Configuring `opensaas.config.ts`
|
|
17
|
+
- Troubleshooting migration issues
|
|
18
|
+
- Explaining OpenSaaS Stack concepts
|
|
19
|
+
|
|
20
|
+
## Migration Process
|
|
21
|
+
|
|
22
|
+
### 1. Schema Analysis
|
|
23
|
+
|
|
24
|
+
**Prisma Projects:**
|
|
25
|
+
|
|
26
|
+
- Analyze existing `schema.prisma`
|
|
27
|
+
- Identify models, fields, and relationships
|
|
28
|
+
- Note any Prisma-specific features used
|
|
29
|
+
|
|
30
|
+
**KeystoneJS Projects:**
|
|
31
|
+
|
|
32
|
+
- Review list definitions
|
|
33
|
+
- Map KeystoneJS fields to OpenSaaS fields
|
|
34
|
+
- Identify access control patterns
|
|
35
|
+
|
|
36
|
+
### 2. Access Control Design
|
|
37
|
+
|
|
38
|
+
**Common Patterns:**
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// Public read, authenticated write
|
|
42
|
+
operation: {
|
|
43
|
+
query: () => true,
|
|
44
|
+
create: ({ session }) => !!session?.userId,
|
|
45
|
+
update: ({ session }) => !!session?.userId,
|
|
46
|
+
delete: ({ session }) => !!session?.userId,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Author-only access
|
|
50
|
+
operation: {
|
|
51
|
+
query: () => true,
|
|
52
|
+
update: ({ session, item }) => item.authorId === session?.userId,
|
|
53
|
+
delete: ({ session, item }) => item.authorId === session?.userId,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Admin-only
|
|
57
|
+
operation: {
|
|
58
|
+
query: ({ session }) => session?.role === 'admin',
|
|
59
|
+
create: ({ session }) => session?.role === 'admin',
|
|
60
|
+
update: ({ session }) => session?.role === 'admin',
|
|
61
|
+
delete: ({ session }) => session?.role === 'admin',
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Filter-based access
|
|
65
|
+
operation: {
|
|
66
|
+
query: ({ session }) => ({
|
|
67
|
+
where: { authorId: { equals: session?.userId } }
|
|
68
|
+
}),
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 3. Field Mapping
|
|
73
|
+
|
|
74
|
+
**Prisma to OpenSaaS:**
|
|
75
|
+
|
|
76
|
+
| Prisma Type | OpenSaaS Field |
|
|
77
|
+
| ----------- | ------------------------------ |
|
|
78
|
+
| `String` | `text()` |
|
|
79
|
+
| `Int` | `integer()` |
|
|
80
|
+
| `Boolean` | `checkbox()` |
|
|
81
|
+
| `DateTime` | `timestamp()` |
|
|
82
|
+
| `Enum` | `select({ options: [...] })` |
|
|
83
|
+
| `Relation` | `relationship({ ref: '...' })` |
|
|
84
|
+
|
|
85
|
+
**KeystoneJS to OpenSaaS:**
|
|
86
|
+
|
|
87
|
+
| KeystoneJS Field | OpenSaaS Field |
|
|
88
|
+
| ---------------- | ---------------- |
|
|
89
|
+
| `text` | `text()` |
|
|
90
|
+
| `integer` | `integer()` |
|
|
91
|
+
| `checkbox` | `checkbox()` |
|
|
92
|
+
| `timestamp` | `timestamp()` |
|
|
93
|
+
| `select` | `select()` |
|
|
94
|
+
| `relationship` | `relationship()` |
|
|
95
|
+
| `password` | `password()` |
|
|
96
|
+
|
|
97
|
+
### 4. Database Configuration
|
|
98
|
+
|
|
99
|
+
**SQLite (Development):**
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { PrismaBetterSQLite3 } from '@prisma/adapter-better-sqlite3'
|
|
103
|
+
import Database from 'better-sqlite3'
|
|
104
|
+
|
|
105
|
+
export default config({
|
|
106
|
+
db: {
|
|
107
|
+
provider: 'sqlite',
|
|
108
|
+
url: process.env.DATABASE_URL || 'file:./dev.db',
|
|
109
|
+
prismaClientConstructor: (PrismaClient) => {
|
|
110
|
+
const db = new Database(process.env.DATABASE_URL || './dev.db')
|
|
111
|
+
const adapter = new PrismaBetterSQLite3(db)
|
|
112
|
+
return new PrismaClient({ adapter })
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**PostgreSQL (Production):**
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { PrismaPg } from '@prisma/adapter-pg'
|
|
122
|
+
import pg from 'pg'
|
|
123
|
+
|
|
124
|
+
export default config({
|
|
125
|
+
db: {
|
|
126
|
+
provider: 'postgresql',
|
|
127
|
+
url: process.env.DATABASE_URL,
|
|
128
|
+
prismaClientConstructor: (PrismaClient) => {
|
|
129
|
+
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL })
|
|
130
|
+
const adapter = new PrismaPg(pool)
|
|
131
|
+
return new PrismaClient({ adapter })
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
})
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Common Migration Challenges
|
|
138
|
+
|
|
139
|
+
### Challenge: Preserving Existing Data
|
|
140
|
+
|
|
141
|
+
**Solution:**
|
|
142
|
+
|
|
143
|
+
- Use `opensaas generate` to create Prisma schema
|
|
144
|
+
- Use `prisma db push` instead of migrations for existing databases
|
|
145
|
+
- Never use `prisma migrate dev` with existing data
|
|
146
|
+
|
|
147
|
+
### Challenge: Complex Access Control
|
|
148
|
+
|
|
149
|
+
**Solution:**
|
|
150
|
+
|
|
151
|
+
- Start with simple boolean access control
|
|
152
|
+
- Iterate to filter-based access as needed
|
|
153
|
+
- Use field-level access for sensitive data
|
|
154
|
+
|
|
155
|
+
### Challenge: Custom Field Types
|
|
156
|
+
|
|
157
|
+
**Solution:**
|
|
158
|
+
|
|
159
|
+
- Create custom field builders extending `BaseFieldConfig`
|
|
160
|
+
- Implement `getZodSchema`, `getPrismaType`, `getTypeScriptType`
|
|
161
|
+
- Register UI components for admin interface
|
|
162
|
+
|
|
163
|
+
## Migration Checklist
|
|
164
|
+
|
|
165
|
+
- [ ] Analyze existing schema
|
|
166
|
+
- [ ] Design access control patterns
|
|
167
|
+
- [ ] Create `opensaas.config.ts`
|
|
168
|
+
- [ ] Configure database adapter
|
|
169
|
+
- [ ] Run `opensaas generate`
|
|
170
|
+
- [ ] Run `prisma generate`
|
|
171
|
+
- [ ] Run `prisma db push`
|
|
172
|
+
- [ ] Test access control
|
|
173
|
+
- [ ] Verify admin UI
|
|
174
|
+
- [ ] Update application code to use context
|
|
175
|
+
- [ ] Test all CRUD operations
|
|
176
|
+
- [ ] Deploy to production
|
|
177
|
+
|
|
178
|
+
## Best Practices
|
|
179
|
+
|
|
180
|
+
1. **Start Simple**: Begin with basic access control, refine later
|
|
181
|
+
2. **Test Access Control**: Verify permissions work as expected
|
|
182
|
+
3. **Use Context Everywhere**: Replace direct Prisma calls with `context.db`
|
|
183
|
+
4. **Leverage Plugins**: Use `@opensaas/stack-auth` for authentication
|
|
184
|
+
5. **Version Control**: Commit `opensaas.config.ts` to git
|
|
185
|
+
6. **Document Decisions**: Comment complex access control logic
|
|
186
|
+
|
|
187
|
+
## Resources
|
|
188
|
+
|
|
189
|
+
- [OpenSaaS Stack Documentation](https://stack.opensaas.au/)
|
|
190
|
+
- [Migration Guide](https://stack.opensaas.au/guides/migration)
|
|
191
|
+
- [Access Control Guide](https://stack.opensaas.au/core-concepts/access-control)
|
|
192
|
+
- [Field Types](https://stack.opensaas.au/core-concepts/field-types)
|
package/.turbo/turbo-build.log
DELETED
package/CHANGELOG.md
DELETED
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
# @opensaas/stack-cli
|
|
2
|
-
|
|
3
|
-
## 0.4.0
|
|
4
|
-
|
|
5
|
-
### Minor Changes
|
|
6
|
-
|
|
7
|
-
- [#170](https://github.com/OpenSaasAU/stack/pull/170) [`3c4db9d`](https://github.com/OpenSaasAU/stack/commit/3c4db9d8318fc73d291991d8bdfa4f607c3a50ea) Thanks [@list({](https://github.com/list({)! - Add support for virtual fields with proper TypeScript type generation
|
|
8
|
-
|
|
9
|
-
Virtual fields are computed fields that don't exist in the database but are added to query results at runtime. This feature enables derived or computed values to be included in your API responses with full type safety.
|
|
10
|
-
|
|
11
|
-
**New Features:**
|
|
12
|
-
- Added `virtual()` field type for defining computed fields in your schema
|
|
13
|
-
- Virtual fields are automatically excluded from database schema and input types
|
|
14
|
-
- Virtual fields appear in output types with full TypeScript autocomplete
|
|
15
|
-
- Virtual fields support `resolveOutput` hooks for custom computation logic
|
|
16
|
-
|
|
17
|
-
**Type System Improvements:**
|
|
18
|
-
- Generated Context type now properly extends AccessContext from core
|
|
19
|
-
- Separate Input and Output types (e.g., `UserOutput` includes virtual fields, `UserCreateInput` does not)
|
|
20
|
-
- UI components now accept `AccessContext<any>` for better compatibility with custom context types
|
|
21
|
-
- Type aliases provide convenience (e.g., `User = UserOutput`)
|
|
22
|
-
|
|
23
|
-
**Example Usage:**
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
import { list, text, virtual } from '@opensaas/stack-core'
|
|
27
|
-
|
|
28
|
-
export default config({
|
|
29
|
-
lists: {
|
|
30
|
-
|
|
31
|
-
fields: {
|
|
32
|
-
name: text(),
|
|
33
|
-
email: text(),
|
|
34
|
-
displayName: virtual({
|
|
35
|
-
type: 'string',
|
|
36
|
-
hooks: {
|
|
37
|
-
resolveOutput: async ({ item }) => {
|
|
38
|
-
return `${item.name} (${item.email})`
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
}),
|
|
42
|
-
},
|
|
43
|
-
}),
|
|
44
|
-
},
|
|
45
|
-
})
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
The `displayName` field will automatically appear in query results with full TypeScript support, but won't be part of create/update operations or the database schema.
|
|
49
|
-
|
|
50
|
-
### Patch Changes
|
|
51
|
-
|
|
52
|
-
- [#154](https://github.com/OpenSaasAU/stack/pull/154) [`edf1e5f`](https://github.com/OpenSaasAU/stack/commit/edf1e5fa4cfefcb7bc09bf45d4702260e6d0d3aa) Thanks [@renovate](https://github.com/apps/renovate)! - Update dependency chokidar to v5
|
|
53
|
-
|
|
54
|
-
- [#172](https://github.com/OpenSaasAU/stack/pull/172) [`929a2a9`](https://github.com/OpenSaasAU/stack/commit/929a2a9a2dfa80b1d973d259dd87828d644ea58d) Thanks [@list<Lists.User.TypeInfo>({](https://github.com/list<Lists.User.TypeInfo>({), [@list<Lists.User.TypeInfo>({](https://github.com/list<Lists.User.TypeInfo>({)! - Improve TypeScript type inference for field configs and list-level hooks by automatically passing TypeInfo from list level down
|
|
55
|
-
|
|
56
|
-
This change eliminates the need to manually specify type parameters on field builders when using features like virtual fields, and fixes a critical bug where list-level hooks weren't receiving properly typed parameters.
|
|
57
|
-
|
|
58
|
-
## Field Type Inference Improvements
|
|
59
|
-
|
|
60
|
-
Previously, users had to write `virtual<Lists.User.TypeInfo>({...})` to get proper type inference. Now TypeScript automatically infers the correct types from the list-level type parameter.
|
|
61
|
-
|
|
62
|
-
**Example:**
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
65
|
-
// Before
|
|
66
|
-
|
|
67
|
-
fields: {
|
|
68
|
-
displayName: virtual<Lists.User.TypeInfo>({
|
|
69
|
-
type: 'string',
|
|
70
|
-
hooks: {
|
|
71
|
-
resolveOutput: ({ item }) => `${item.name} (${item.email})`,
|
|
72
|
-
},
|
|
73
|
-
}),
|
|
74
|
-
},
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
// After
|
|
78
|
-
|
|
79
|
-
fields: {
|
|
80
|
-
displayName: virtual({
|
|
81
|
-
type: 'string',
|
|
82
|
-
hooks: {
|
|
83
|
-
resolveOutput: ({ item }) => `${item.name} (${item.email})`,
|
|
84
|
-
},
|
|
85
|
-
}),
|
|
86
|
-
},
|
|
87
|
-
})
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## List-Level Hooks Type Inference Fix
|
|
91
|
-
|
|
92
|
-
Fixed a critical type parameter mismatch where `Hooks<TTypeInfo>` was passing the entire TypeInfo object as the first parameter instead of properly destructuring it into three required parameters:
|
|
93
|
-
1. `TOutput` - The item type (what's stored in DB)
|
|
94
|
-
2. `TCreateInput` - Prisma create input type
|
|
95
|
-
3. `TUpdateInput` - Prisma update input type
|
|
96
|
-
|
|
97
|
-
**Impact:**
|
|
98
|
-
- `resolveInput` now receives proper Prisma input types (e.g., `PostCreateInput`, `PostUpdateInput`)
|
|
99
|
-
- `validateInput` has access to properly typed input data
|
|
100
|
-
- `beforeOperation` and `afterOperation` have correct item types
|
|
101
|
-
- All list-level hook callbacks now get full IntelliSense and type checking
|
|
102
|
-
|
|
103
|
-
**Example:**
|
|
104
|
-
|
|
105
|
-
```typescript
|
|
106
|
-
Post: list<Lists.Post.TypeInfo>({
|
|
107
|
-
fields: { title: text(), content: text() },
|
|
108
|
-
hooks: {
|
|
109
|
-
resolveInput: async ({ operation, resolvedData }) => {
|
|
110
|
-
// ✅ resolvedData is now properly typed as PostCreateInput or PostUpdateInput
|
|
111
|
-
// ✅ Full autocomplete for title, content, etc.
|
|
112
|
-
if (operation === 'create') {
|
|
113
|
-
console.log(resolvedData.title) // TypeScript knows this is string | undefined
|
|
114
|
-
}
|
|
115
|
-
return resolvedData
|
|
116
|
-
},
|
|
117
|
-
beforeOperation: async ({ operation, item }) => {
|
|
118
|
-
// ✅ item is now properly typed as Post with all fields
|
|
119
|
-
if (operation === 'update' && item) {
|
|
120
|
-
console.log(item.title) // TypeScript knows this is string
|
|
121
|
-
console.log(item.createdAt) // TypeScript knows this is Date
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
})
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
## Breaking Changes
|
|
129
|
-
- Field types now accept full `TTypeInfo extends TypeInfo` instead of just `TItem`
|
|
130
|
-
- `FieldsWithItemType` utility replaced with `FieldsWithTypeInfo`
|
|
131
|
-
- All field builders updated to use new type signature
|
|
132
|
-
- List-level hooks now receive properly typed parameters (may reveal existing type errors)
|
|
133
|
-
|
|
134
|
-
## Benefits
|
|
135
|
-
- ✨ Cleaner code without manual type parameter repetition
|
|
136
|
-
- 🎯 Better type inference in both field-level and list-level hooks
|
|
137
|
-
- 🔄 Consistent type flow from list configuration down to individual fields
|
|
138
|
-
- 🛡️ Maintained full type safety with improved DX
|
|
139
|
-
- 💡 Full IntelliSense support in all hook callbacks
|
|
140
|
-
|
|
141
|
-
- Updated dependencies [[`527b677`](https://github.com/OpenSaasAU/stack/commit/527b677ab598070185e23d163a9e99bc20f03c49), [`929a2a9`](https://github.com/OpenSaasAU/stack/commit/929a2a9a2dfa80b1d973d259dd87828d644ea58d), [`3c4db9d`](https://github.com/OpenSaasAU/stack/commit/3c4db9d8318fc73d291991d8bdfa4f607c3a50ea)]:
|
|
142
|
-
- @opensaas/stack-core@0.4.0
|
|
143
|
-
|
|
144
|
-
## 0.3.0
|
|
145
|
-
|
|
146
|
-
### Patch Changes
|
|
147
|
-
|
|
148
|
-
- Updated dependencies []:
|
|
149
|
-
- @opensaas/stack-core@0.3.0
|
|
150
|
-
|
|
151
|
-
## 0.2.0
|
|
152
|
-
|
|
153
|
-
### Minor Changes
|
|
154
|
-
|
|
155
|
-
- [#107](https://github.com/OpenSaasAU/stack/pull/107) [`f4f3966`](https://github.com/OpenSaasAU/stack/commit/f4f3966faedba07d2cf412fab826d81e30c63a6c) Thanks [@borisno2](https://github.com/borisno2)! - # Add MCP Server for AI-Assisted Development
|
|
156
|
-
|
|
157
|
-
## New Features
|
|
158
|
-
|
|
159
|
-
### CLI Package (@opensaas/stack-cli)
|
|
160
|
-
- **New `opensaas mcp` command group** for AI-assisted development:
|
|
161
|
-
- `opensaas mcp install` - Install MCP server in Claude Code
|
|
162
|
-
- `opensaas mcp uninstall` - Remove MCP server from Claude Code
|
|
163
|
-
- `opensaas mcp start` - Start MCP server directly (for debugging)
|
|
164
|
-
- **Feature-driven development tools**:
|
|
165
|
-
- Interactive feature implementation wizards (authentication, blog, comments, file-upload, semantic-search)
|
|
166
|
-
- Live documentation search from stack.opensaas.au
|
|
167
|
-
- Code generation following OpenSaaS best practices
|
|
168
|
-
- Smart feature suggestions based on your current app
|
|
169
|
-
- Config validation
|
|
170
|
-
- **MCP tools available in Claude Code**:
|
|
171
|
-
- `opensaas_implement_feature` - Start feature wizard
|
|
172
|
-
- `opensaas_feature_docs` - Search documentation
|
|
173
|
-
- `opensaas_list_features` - Browse available features
|
|
174
|
-
- `opensaas_suggest_features` - Get personalized recommendations
|
|
175
|
-
- `opensaas_validate_feature` - Validate implementations
|
|
176
|
-
|
|
177
|
-
### create-opensaas-app
|
|
178
|
-
- **Interactive MCP setup prompt** during project creation
|
|
179
|
-
- Option to enable AI development tools automatically
|
|
180
|
-
- Automatic installation of MCP server if user opts in
|
|
181
|
-
- Helpful instructions if MCP installation is declined or fails
|
|
182
|
-
|
|
183
|
-
## Installation
|
|
184
|
-
|
|
185
|
-
Enable AI development tools for an existing project:
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
npx @opensaas/stack-cli mcp install
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Or during project creation:
|
|
192
|
-
|
|
193
|
-
```bash
|
|
194
|
-
npm create opensaas-app@latest my-app
|
|
195
|
-
# When prompted: Enable AI development tools? → yes
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
## Benefits
|
|
199
|
-
- **Build apps faster**: Describe what you want to build, get complete implementations
|
|
200
|
-
- **Feature-driven development**: Work with high-level features instead of low-level config
|
|
201
|
-
- **Best practices baked in**: Generated code follows OpenSaaS Stack patterns
|
|
202
|
-
- **Live documentation**: Always up-to-date docs from the official site
|
|
203
|
-
- **Single toolkit**: All developer commands in one CLI
|
|
204
|
-
|
|
205
|
-
## Example Usage
|
|
206
|
-
|
|
207
|
-
With Claude Code installed and the MCP server enabled, you can:
|
|
208
|
-
|
|
209
|
-
```
|
|
210
|
-
You: "I want to build a food tracking app"
|
|
211
|
-
|
|
212
|
-
Claude Code uses MCP tools to:
|
|
213
|
-
1. Ask clarifying questions about requirements
|
|
214
|
-
2. Implement authentication feature (wizard)
|
|
215
|
-
3. Create custom Food and FoodLog lists
|
|
216
|
-
4. Generate complete code with UI and access control
|
|
217
|
-
5. Provide testing and deployment guidance
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
- [#132](https://github.com/OpenSaasAU/stack/pull/132) [`fcf5cb8`](https://github.com/OpenSaasAU/stack/commit/fcf5cb8bbd55d802350b8d97e342dd7f6368163b) Thanks [@borisno2](https://github.com/borisno2)! - Upgrade to Prisma 7 with database adapter support
|
|
221
|
-
|
|
222
|
-
## Breaking Changes
|
|
223
|
-
|
|
224
|
-
### Required `prismaClientConstructor`
|
|
225
|
-
|
|
226
|
-
Prisma 7 requires database adapters. All configs must now include `prismaClientConstructor`:
|
|
227
|
-
|
|
228
|
-
```typescript
|
|
229
|
-
import { PrismaBetterSQLite3 } from '@prisma/adapter-better-sqlite3'
|
|
230
|
-
import Database from 'better-sqlite3'
|
|
231
|
-
|
|
232
|
-
export default config({
|
|
233
|
-
db: {
|
|
234
|
-
provider: 'sqlite',
|
|
235
|
-
prismaClientConstructor: (PrismaClient) => {
|
|
236
|
-
const db = new Database(process.env.DATABASE_URL || './dev.db')
|
|
237
|
-
const adapter = new PrismaBetterSQLite3(db)
|
|
238
|
-
return new PrismaClient({ adapter })
|
|
239
|
-
},
|
|
240
|
-
},
|
|
241
|
-
})
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### Removed `url` from `DatabaseConfig`
|
|
245
|
-
|
|
246
|
-
The `url` field has been removed from the `DatabaseConfig` type. Database connection URLs are now passed directly to adapters in `prismaClientConstructor`:
|
|
247
|
-
|
|
248
|
-
```typescript
|
|
249
|
-
// ❌ Before (Prisma 6)
|
|
250
|
-
db: {
|
|
251
|
-
provider: 'sqlite',
|
|
252
|
-
url: 'file:./dev.db', // url in config
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// ✅ After (Prisma 7)
|
|
256
|
-
db: {
|
|
257
|
-
provider: 'sqlite',
|
|
258
|
-
prismaClientConstructor: (PrismaClient) => {
|
|
259
|
-
const adapter = new PrismaBetterSQLite3({ url: './dev.db' }) // url in adapter
|
|
260
|
-
return new PrismaClient({ adapter })
|
|
261
|
-
},
|
|
262
|
-
}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
### Generated Schema Changes
|
|
266
|
-
- Generator provider changed from `prisma-client-js` to `prisma-client`
|
|
267
|
-
- Removed `url` field from datasource block
|
|
268
|
-
- Database URL now passed via adapter in `prismaClientConstructor`
|
|
269
|
-
|
|
270
|
-
### Required Dependencies
|
|
271
|
-
|
|
272
|
-
Install the appropriate adapter for your database:
|
|
273
|
-
- **SQLite**: `@prisma/adapter-better-sqlite3` + `better-sqlite3`
|
|
274
|
-
- **PostgreSQL**: `@prisma/adapter-pg` + `pg`
|
|
275
|
-
- **MySQL**: `@prisma/adapter-mysql` + `mysql2`
|
|
276
|
-
|
|
277
|
-
## Migration Steps
|
|
278
|
-
1. Install Prisma 7 and adapter:
|
|
279
|
-
|
|
280
|
-
```bash
|
|
281
|
-
pnpm add @prisma/client@7 @prisma/adapter-better-sqlite3 better-sqlite3
|
|
282
|
-
pnpm add -D prisma@7
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
2. Update your `opensaas.config.ts` to include `prismaClientConstructor` (see example above)
|
|
286
|
-
3. Regenerate schema and client:
|
|
287
|
-
|
|
288
|
-
```bash
|
|
289
|
-
pnpm generate
|
|
290
|
-
npx prisma generate
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
4. Push schema to database:
|
|
294
|
-
```bash
|
|
295
|
-
pnpm db:push
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
See the updated documentation in CLAUDE.md for more examples including PostgreSQL and custom adapters.
|
|
299
|
-
|
|
300
|
-
### Patch Changes
|
|
301
|
-
|
|
302
|
-
- [#107](https://github.com/OpenSaasAU/stack/pull/107) [`f4f3966`](https://github.com/OpenSaasAU/stack/commit/f4f3966faedba07d2cf412fab826d81e30c63a6c) Thanks [@borisno2](https://github.com/borisno2)! - Add strict typing for plugin runtime services
|
|
303
|
-
|
|
304
|
-
This change implements fully typed plugin runtime services, providing autocomplete and type safety for `context.plugins` throughout the codebase.
|
|
305
|
-
|
|
306
|
-
**Core Changes:**
|
|
307
|
-
- Extended `Plugin` type with optional `runtimeServiceTypes` metadata for type-safe code generation
|
|
308
|
-
- Converted `OpenSaasConfig` and `AccessContext` from `type` to `interface` to enable module augmentation
|
|
309
|
-
- Plugins can now declare their runtime service type information
|
|
310
|
-
|
|
311
|
-
**Auth Plugin:**
|
|
312
|
-
- Added `AuthRuntimeServices` interface defining runtime service types
|
|
313
|
-
- Exported runtime types from package
|
|
314
|
-
- Users now get full autocomplete for `context.plugins.auth.getUser()` and `context.plugins.auth.getCurrentUser()`
|
|
315
|
-
|
|
316
|
-
**RAG Plugin:**
|
|
317
|
-
- Added `RAGRuntimeServices` interface defining runtime service types
|
|
318
|
-
- Exported runtime types from package
|
|
319
|
-
- Users now get full autocomplete for `context.plugins.rag.generateEmbedding()` and `context.plugins.rag.generateEmbeddings()`
|
|
320
|
-
|
|
321
|
-
**CLI Generator:**
|
|
322
|
-
- Enhanced plugin types generator to import and use plugin runtime service types
|
|
323
|
-
- Generated `.opensaas/plugin-types.ts` now includes proper type imports
|
|
324
|
-
- `PluginServices` interface extends `Record<string, Record<string, any> | undefined>` for type compatibility
|
|
325
|
-
- Maintains backwards compatibility with plugins that don't provide type metadata
|
|
326
|
-
|
|
327
|
-
**UI Package:**
|
|
328
|
-
- Updated `AdminUI` props to accept contexts with typed plugin services
|
|
329
|
-
- Ensures compatibility between generated context types and UI components
|
|
330
|
-
|
|
331
|
-
**Benefits:**
|
|
332
|
-
- Full TypeScript autocomplete for all plugin runtime methods
|
|
333
|
-
- Compile-time type checking catches errors early
|
|
334
|
-
- Better IDE experience with hover documentation and jump-to-definition
|
|
335
|
-
- Backwards compatible - third-party plugins without type metadata continue to work
|
|
336
|
-
- Zero type errors in examples
|
|
337
|
-
|
|
338
|
-
**Example:**
|
|
339
|
-
|
|
340
|
-
```typescript
|
|
341
|
-
const context = await getContext()
|
|
342
|
-
|
|
343
|
-
// Fully typed with autocomplete
|
|
344
|
-
context.plugins.auth.getUser('123') // (userId: string) => Promise<unknown>
|
|
345
|
-
context.plugins.rag.generateEmbedding('text') // (text: string, providerName?: string) => Promise<number[]>
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
- Updated dependencies [[`fcf5cb8`](https://github.com/OpenSaasAU/stack/commit/fcf5cb8bbd55d802350b8d97e342dd7f6368163b), [`3851a3c`](https://github.com/OpenSaasAU/stack/commit/3851a3cf72e78dc6f01a73c6fff97deca6fad043), [`f4f3966`](https://github.com/OpenSaasAU/stack/commit/f4f3966faedba07d2cf412fab826d81e30c63a6c)]:
|
|
349
|
-
- @opensaas/stack-core@0.2.0
|
|
350
|
-
|
|
351
|
-
## 0.1.7
|
|
352
|
-
|
|
353
|
-
### Patch Changes
|
|
354
|
-
|
|
355
|
-
- 372d467: Add sudo to context to bypass access control
|
|
356
|
-
- Updated dependencies [372d467]
|
|
357
|
-
- @opensaas/stack-core@0.1.7
|
|
358
|
-
|
|
359
|
-
## 0.1.6
|
|
360
|
-
|
|
361
|
-
### Patch Changes
|
|
362
|
-
|
|
363
|
-
- 39996ca: Fix missing StoredEmbedding type import in generated types. Fields can now declare TypeScript imports needed for their types via the new `getTypeScriptImports()` method. This resolves the type error where `StoredEmbedding` was referenced but not imported in the generated `.opensaas/types.ts` file.
|
|
364
|
-
- 39996ca: Add plugin mechanism
|
|
365
|
-
- Updated dependencies [39996ca]
|
|
366
|
-
- Updated dependencies [39996ca]
|
|
367
|
-
- @opensaas/stack-core@0.1.6
|
|
368
|
-
|
|
369
|
-
## 0.1.5
|
|
370
|
-
|
|
371
|
-
### Patch Changes
|
|
372
|
-
|
|
373
|
-
- 17eaafb: Update package urls
|
|
374
|
-
- Updated dependencies [17eaafb]
|
|
375
|
-
- @opensaas/stack-core@0.1.5
|
|
376
|
-
|
|
377
|
-
## 0.1.4
|
|
378
|
-
|
|
379
|
-
### Patch Changes
|
|
380
|
-
|
|
381
|
-
- d2d1720: clean up dependency
|
|
382
|
-
- Updated dependencies [d013859]
|
|
383
|
-
- @opensaas/stack-core@0.1.4
|
|
384
|
-
|
|
385
|
-
## 0.1.3
|
|
386
|
-
|
|
387
|
-
### Patch Changes
|
|
388
|
-
|
|
389
|
-
- @opensaas/stack-core@0.1.3
|
|
390
|
-
- @opensaas/stack-mcp@0.1.3
|
|
391
|
-
|
|
392
|
-
## 0.1.2
|
|
393
|
-
|
|
394
|
-
### Patch Changes
|
|
395
|
-
|
|
396
|
-
- 7bb96e6: Fix up init command to work
|
|
397
|
-
- @opensaas/stack-core@0.1.2
|
|
398
|
-
- @opensaas/stack-mcp@0.1.2
|
|
399
|
-
|
|
400
|
-
## 0.1.1
|
|
401
|
-
|
|
402
|
-
### Patch Changes
|
|
403
|
-
|
|
404
|
-
- f8ebc0e: Add base mcp server
|
|
405
|
-
- 045c071: Add field and image upload
|
|
406
|
-
- Updated dependencies [9a3fda5]
|
|
407
|
-
- Updated dependencies [f8ebc0e]
|
|
408
|
-
- Updated dependencies [045c071]
|
|
409
|
-
- @opensaas/stack-core@0.1.1
|
|
410
|
-
- @opensaas/stack-mcp@0.1.1
|