@opensaas/stack-core 0.1.7 → 0.3.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +202 -0
- package/CLAUDE.md +46 -1
- package/dist/access/engine.d.ts +6 -5
- package/dist/access/engine.d.ts.map +1 -1
- package/dist/access/engine.js +17 -0
- package/dist/access/engine.js.map +1 -1
- package/dist/access/engine.test.d.ts +2 -0
- package/dist/access/engine.test.d.ts.map +1 -0
- package/dist/access/engine.test.js +125 -0
- package/dist/access/engine.test.js.map +1 -0
- package/dist/access/types.d.ts +39 -9
- package/dist/access/types.d.ts.map +1 -1
- package/dist/config/index.d.ts +38 -18
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +34 -14
- package/dist/config/index.js.map +1 -1
- package/dist/config/plugin-engine.d.ts.map +1 -1
- package/dist/config/plugin-engine.js +6 -0
- package/dist/config/plugin-engine.js.map +1 -1
- package/dist/config/types.d.ts +128 -21
- package/dist/config/types.d.ts.map +1 -1
- package/dist/context/index.d.ts +5 -3
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +127 -14
- package/dist/context/index.js.map +1 -1
- package/dist/fields/index.d.ts.map +1 -1
- package/dist/fields/index.js +9 -8
- package/dist/fields/index.js.map +1 -1
- package/dist/hooks/index.d.ts +28 -12
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +16 -0
- package/dist/hooks/index.js.map +1 -1
- package/package.json +3 -4
- package/src/access/engine.test.ts +145 -0
- package/src/access/engine.ts +25 -6
- package/src/access/types.ts +38 -8
- package/src/config/index.ts +46 -19
- package/src/config/plugin-engine.ts +7 -0
- package/src/config/types.ts +149 -18
- package/src/context/index.ts +163 -17
- package/src/fields/index.ts +8 -7
- package/src/hooks/index.ts +63 -20
- package/tests/context.test.ts +38 -6
- package/tests/field-types.test.ts +728 -0
- package/tests/password-type-distribution.test.ts +0 -1
- package/tests/password-types.test.ts +0 -1
- package/tests/plugin-engine.test.ts +1102 -0
- package/tests/sudo.test.ts +0 -1
- package/tsconfig.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,207 @@
|
|
|
1
1
|
# @opensaas/stack-core
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
## 0.2.0
|
|
6
|
+
|
|
7
|
+
### Minor Changes
|
|
8
|
+
|
|
9
|
+
- [#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
|
|
10
|
+
|
|
11
|
+
## Breaking Changes
|
|
12
|
+
|
|
13
|
+
### Required `prismaClientConstructor`
|
|
14
|
+
|
|
15
|
+
Prisma 7 requires database adapters. All configs must now include `prismaClientConstructor`:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { PrismaBetterSQLite3 } from '@prisma/adapter-better-sqlite3'
|
|
19
|
+
import Database from 'better-sqlite3'
|
|
20
|
+
|
|
21
|
+
export default config({
|
|
22
|
+
db: {
|
|
23
|
+
provider: 'sqlite',
|
|
24
|
+
prismaClientConstructor: (PrismaClient) => {
|
|
25
|
+
const db = new Database(process.env.DATABASE_URL || './dev.db')
|
|
26
|
+
const adapter = new PrismaBetterSQLite3(db)
|
|
27
|
+
return new PrismaClient({ adapter })
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Removed `url` from `DatabaseConfig`
|
|
34
|
+
|
|
35
|
+
The `url` field has been removed from the `DatabaseConfig` type. Database connection URLs are now passed directly to adapters in `prismaClientConstructor`:
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// ❌ Before (Prisma 6)
|
|
39
|
+
db: {
|
|
40
|
+
provider: 'sqlite',
|
|
41
|
+
url: 'file:./dev.db', // url in config
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ✅ After (Prisma 7)
|
|
45
|
+
db: {
|
|
46
|
+
provider: 'sqlite',
|
|
47
|
+
prismaClientConstructor: (PrismaClient) => {
|
|
48
|
+
const adapter = new PrismaBetterSQLite3({ url: './dev.db' }) // url in adapter
|
|
49
|
+
return new PrismaClient({ adapter })
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Generated Schema Changes
|
|
55
|
+
- Generator provider changed from `prisma-client-js` to `prisma-client`
|
|
56
|
+
- Removed `url` field from datasource block
|
|
57
|
+
- Database URL now passed via adapter in `prismaClientConstructor`
|
|
58
|
+
|
|
59
|
+
### Required Dependencies
|
|
60
|
+
|
|
61
|
+
Install the appropriate adapter for your database:
|
|
62
|
+
- **SQLite**: `@prisma/adapter-better-sqlite3` + `better-sqlite3`
|
|
63
|
+
- **PostgreSQL**: `@prisma/adapter-pg` + `pg`
|
|
64
|
+
- **MySQL**: `@prisma/adapter-mysql` + `mysql2`
|
|
65
|
+
|
|
66
|
+
## Migration Steps
|
|
67
|
+
1. Install Prisma 7 and adapter:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pnpm add @prisma/client@7 @prisma/adapter-better-sqlite3 better-sqlite3
|
|
71
|
+
pnpm add -D prisma@7
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
2. Update your `opensaas.config.ts` to include `prismaClientConstructor` (see example above)
|
|
75
|
+
3. Regenerate schema and client:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pnpm generate
|
|
79
|
+
npx prisma generate
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
4. Push schema to database:
|
|
83
|
+
```bash
|
|
84
|
+
pnpm db:push
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
See the updated documentation in CLAUDE.md for more examples including PostgreSQL and custom adapters.
|
|
88
|
+
|
|
89
|
+
- [#121](https://github.com/OpenSaasAU/stack/pull/121) [`3851a3c`](https://github.com/OpenSaasAU/stack/commit/3851a3cf72e78dc6f01a73c6fff97deca6fad043) Thanks [@borisno2](https://github.com/borisno2)! - Add strongly-typed session support via module augmentation
|
|
90
|
+
|
|
91
|
+
This change enables developers to define custom session types with full TypeScript autocomplete and type safety throughout their OpenSaas applications using the module augmentation pattern.
|
|
92
|
+
|
|
93
|
+
**Core Changes:**
|
|
94
|
+
- Converted `Session` from `type` to `interface` to enable module augmentation
|
|
95
|
+
- Updated all session references to properly handle `Session | null`
|
|
96
|
+
- Added comprehensive JSDoc documentation with module augmentation examples
|
|
97
|
+
- Updated `AccessControl`, `AccessContext`, and access control engine to support nullable sessions
|
|
98
|
+
- Added "Session Typing" section to core package documentation
|
|
99
|
+
|
|
100
|
+
**Auth Package:**
|
|
101
|
+
- Added "Session Type Safety" section to documentation
|
|
102
|
+
- Documented how Better Auth users can create session type declarations
|
|
103
|
+
- Provided step-by-step guide for matching sessionFields to TypeScript types
|
|
104
|
+
- Created `getSession()` helper pattern for transforming Better Auth sessions
|
|
105
|
+
|
|
106
|
+
**Developer Experience:**
|
|
107
|
+
|
|
108
|
+
Developers can now augment the `Session` interface to get autocomplete everywhere:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// types/session.d.ts
|
|
112
|
+
import '@opensaas/stack-core'
|
|
113
|
+
|
|
114
|
+
declare module '@opensaas/stack-core' {
|
|
115
|
+
interface Session {
|
|
116
|
+
userId?: string
|
|
117
|
+
email?: string
|
|
118
|
+
role?: 'admin' | 'user'
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
This provides autocomplete in:
|
|
124
|
+
- Access control functions
|
|
125
|
+
- Hooks (resolveInput, validateInput, etc.)
|
|
126
|
+
- Context object
|
|
127
|
+
- Server actions
|
|
128
|
+
|
|
129
|
+
**Benefits:**
|
|
130
|
+
- Zero boilerplate - module augmentation provides types everywhere automatically
|
|
131
|
+
- Full type safety for session properties
|
|
132
|
+
- Autocomplete in all contexts that use session
|
|
133
|
+
- Developer controls session shape (no assumptions about structure)
|
|
134
|
+
- Works with any auth provider (Better Auth, custom, etc.)
|
|
135
|
+
- Fully backward compatible - existing code continues to work
|
|
136
|
+
- Follows TypeScript best practices (similar to NextAuth.js pattern)
|
|
137
|
+
|
|
138
|
+
**Example:**
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// Before: No autocomplete
|
|
142
|
+
const isAdmin: AccessControl = ({ session }) => {
|
|
143
|
+
return session?.role === 'admin' // ❌ 'role' is 'unknown'
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// After: Full autocomplete and type checking
|
|
147
|
+
const isAdmin: AccessControl = ({ session }) => {
|
|
148
|
+
return session?.role === 'admin' // ✅ Autocomplete + type checking
|
|
149
|
+
// ↑ Shows: userId, email, role
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Migration:**
|
|
154
|
+
|
|
155
|
+
No migration required - this is a fully backward compatible change. Existing projects continue to work with untyped sessions. Projects can opt-in to typed sessions by creating a `types/session.d.ts` file with module augmentation.
|
|
156
|
+
|
|
157
|
+
### Patch Changes
|
|
158
|
+
|
|
159
|
+
- [#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
|
|
160
|
+
|
|
161
|
+
This change implements fully typed plugin runtime services, providing autocomplete and type safety for `context.plugins` throughout the codebase.
|
|
162
|
+
|
|
163
|
+
**Core Changes:**
|
|
164
|
+
- Extended `Plugin` type with optional `runtimeServiceTypes` metadata for type-safe code generation
|
|
165
|
+
- Converted `OpenSaasConfig` and `AccessContext` from `type` to `interface` to enable module augmentation
|
|
166
|
+
- Plugins can now declare their runtime service type information
|
|
167
|
+
|
|
168
|
+
**Auth Plugin:**
|
|
169
|
+
- Added `AuthRuntimeServices` interface defining runtime service types
|
|
170
|
+
- Exported runtime types from package
|
|
171
|
+
- Users now get full autocomplete for `context.plugins.auth.getUser()` and `context.plugins.auth.getCurrentUser()`
|
|
172
|
+
|
|
173
|
+
**RAG Plugin:**
|
|
174
|
+
- Added `RAGRuntimeServices` interface defining runtime service types
|
|
175
|
+
- Exported runtime types from package
|
|
176
|
+
- Users now get full autocomplete for `context.plugins.rag.generateEmbedding()` and `context.plugins.rag.generateEmbeddings()`
|
|
177
|
+
|
|
178
|
+
**CLI Generator:**
|
|
179
|
+
- Enhanced plugin types generator to import and use plugin runtime service types
|
|
180
|
+
- Generated `.opensaas/plugin-types.ts` now includes proper type imports
|
|
181
|
+
- `PluginServices` interface extends `Record<string, Record<string, any> | undefined>` for type compatibility
|
|
182
|
+
- Maintains backwards compatibility with plugins that don't provide type metadata
|
|
183
|
+
|
|
184
|
+
**UI Package:**
|
|
185
|
+
- Updated `AdminUI` props to accept contexts with typed plugin services
|
|
186
|
+
- Ensures compatibility between generated context types and UI components
|
|
187
|
+
|
|
188
|
+
**Benefits:**
|
|
189
|
+
- Full TypeScript autocomplete for all plugin runtime methods
|
|
190
|
+
- Compile-time type checking catches errors early
|
|
191
|
+
- Better IDE experience with hover documentation and jump-to-definition
|
|
192
|
+
- Backwards compatible - third-party plugins without type metadata continue to work
|
|
193
|
+
- Zero type errors in examples
|
|
194
|
+
|
|
195
|
+
**Example:**
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
const context = await getContext()
|
|
199
|
+
|
|
200
|
+
// Fully typed with autocomplete
|
|
201
|
+
context.plugins.auth.getUser('123') // (userId: string) => Promise<unknown>
|
|
202
|
+
context.plugins.rag.generateEmbedding('text') // (text: string, providerName?: string) => Promise<number[]>
|
|
203
|
+
```
|
|
204
|
+
|
|
3
205
|
## 0.1.7
|
|
4
206
|
|
|
5
207
|
### Patch Changes
|
package/CLAUDE.md
CHANGED
|
@@ -35,13 +35,58 @@ Built-in fields:
|
|
|
35
35
|
### Access Control (`src/access/`)
|
|
36
36
|
|
|
37
37
|
- `engine.ts` - Core execution logic (`applyAccessControl()`)
|
|
38
|
-
- `types.ts` - Type definitions (`AccessControl`, `OperationAccessControl`, etc.)
|
|
38
|
+
- `types.ts` - Type definitions (`AccessControl`, `OperationAccessControl`, `Session`, etc.)
|
|
39
39
|
|
|
40
40
|
Access control functions receive `{ session, context, item, operation }` and return:
|
|
41
41
|
|
|
42
42
|
- `boolean` - Allow/deny
|
|
43
43
|
- `Prisma filter object` - Scope access to matching records
|
|
44
44
|
|
|
45
|
+
### Session Typing (`src/access/types.ts`)
|
|
46
|
+
|
|
47
|
+
The `Session` interface can be augmented to provide type safety and autocomplete for session fields.
|
|
48
|
+
|
|
49
|
+
**Default:** Session is a permissive object: `interface Session { [key: string]: unknown }`
|
|
50
|
+
|
|
51
|
+
**Module Augmentation Pattern:**
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// types/session.d.ts (create this file in your project)
|
|
55
|
+
import '@opensaas/stack-core'
|
|
56
|
+
|
|
57
|
+
declare module '@opensaas/stack-core' {
|
|
58
|
+
interface Session {
|
|
59
|
+
userId: string
|
|
60
|
+
email: string
|
|
61
|
+
role: 'admin' | 'user'
|
|
62
|
+
organizationId?: string
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Benefits:**
|
|
68
|
+
|
|
69
|
+
- Autocomplete in access control functions
|
|
70
|
+
- Type safety when accessing session properties
|
|
71
|
+
- Single source of truth for session shape
|
|
72
|
+
- Works with any auth provider (Better Auth, custom, etc.)
|
|
73
|
+
|
|
74
|
+
**Usage after augmentation:**
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// Access control - fully typed
|
|
78
|
+
const isAdmin: AccessControl = ({ session }) => {
|
|
79
|
+
return session?.role === 'admin' // ✅ 'role' is typed as 'admin' | 'user'
|
|
80
|
+
// ↑ Autocomplete shows: userId, email, role, organizationId
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// In server actions
|
|
84
|
+
const context = await getContext(session)
|
|
85
|
+
context.session?.email // ✅ Typed as string
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**For Better Auth users:** See `@opensaas/stack-auth` documentation for examples of extracting Better Auth session types.
|
|
89
|
+
|
|
45
90
|
### Hooks (`src/hooks/`)
|
|
46
91
|
|
|
47
92
|
- `index.ts` - Hook execution logic
|
package/dist/access/engine.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare function getRelatedListConfig(relationshipRef: string, config: Op
|
|
|
25
25
|
* Execute an access control function
|
|
26
26
|
*/
|
|
27
27
|
export declare function checkAccess<T = Record<string, unknown>>(accessControl: AccessControl<T> | undefined, args: {
|
|
28
|
-
session: Session;
|
|
28
|
+
session: Session | null;
|
|
29
29
|
item?: T;
|
|
30
30
|
context: AccessContext;
|
|
31
31
|
}): Promise<boolean | PrismaFilter<T>>;
|
|
@@ -37,7 +37,7 @@ export declare function mergeFilters(userFilter: PrismaFilter | undefined, acces
|
|
|
37
37
|
* Check field-level access for a specific operation
|
|
38
38
|
*/
|
|
39
39
|
export declare function checkFieldAccess(fieldAccess: FieldAccess | undefined, operation: 'read' | 'create' | 'update', args: {
|
|
40
|
-
session: Session;
|
|
40
|
+
session: Session | null;
|
|
41
41
|
item?: Record<string, unknown>;
|
|
42
42
|
context: AccessContext & {
|
|
43
43
|
_isSudo?: boolean;
|
|
@@ -48,7 +48,7 @@ export declare function checkFieldAccess(fieldAccess: FieldAccess | undefined, o
|
|
|
48
48
|
* This allows us to filter relationships at the database level instead of in memory
|
|
49
49
|
*/
|
|
50
50
|
export declare function buildIncludeWithAccessControl(fieldConfigs: Record<string, FieldConfig>, args: {
|
|
51
|
-
session: Session;
|
|
51
|
+
session: Session | null;
|
|
52
52
|
context: AccessContext;
|
|
53
53
|
}, config: OpenSaasConfig, depth?: number): Promise<Record<string, boolean | {
|
|
54
54
|
where?: PrismaFilter;
|
|
@@ -59,7 +59,7 @@ export declare function buildIncludeWithAccessControl(fieldConfigs: Record<strin
|
|
|
59
59
|
* Recursively applies access control to nested relationships
|
|
60
60
|
*/
|
|
61
61
|
export declare function filterReadableFields<T extends Record<string, unknown>>(item: T, fieldConfigs: Record<string, FieldConfig>, args: {
|
|
62
|
-
session: Session;
|
|
62
|
+
session: Session | null;
|
|
63
63
|
context: AccessContext & {
|
|
64
64
|
_isSudo?: boolean;
|
|
65
65
|
};
|
|
@@ -69,8 +69,9 @@ export declare function filterReadableFields<T extends Record<string, unknown>>(
|
|
|
69
69
|
*/
|
|
70
70
|
export declare function filterWritableFields<T extends Record<string, unknown>>(data: T, fieldConfigs: Record<string, {
|
|
71
71
|
access?: FieldAccess;
|
|
72
|
+
type?: string;
|
|
72
73
|
}>, operation: 'create' | 'update', args: {
|
|
73
|
-
session: Session;
|
|
74
|
+
session: Session | null;
|
|
74
75
|
item?: Record<string, unknown>;
|
|
75
76
|
context: AccessContext & {
|
|
76
77
|
_isSudo?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/access/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAejF;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,cAAc,GACrB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAerD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,SAAS,EAC3C,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/access/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACrF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAejF;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,cAAc,GACrB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,GAAG,IAAI,CAerD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,aAAa,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,SAAS,EAC3C,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,IAAI,CAAC,EAAE,CAAC,CAAA;IACR,OAAO,EAAE,aAAa,CAAA;CACvB,GACA,OAAO,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAUpC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,YAAY,GAAG,SAAS,EACpC,YAAY,EAAE,OAAO,GAAG,YAAY,GACnC,YAAY,GAAG,IAAI,CAoBrB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,WAAW,GAAG,SAAS,EACpC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,EACvC,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAC/C,GACA,OAAO,CAAC,OAAO,CAAC,CAmClB;AA8BD;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACzC,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE,aAAa,CAAA;CACvB,EACD,MAAM,EAAE,cAAc,EACtB,KAAK,GAAE,MAAU;YAOuB,YAAY;cAAY,MAAM,CAAC,MAAM,2BAAe;gBAkD7F;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,IAAI,EAAE,CAAC,EACP,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACzC,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAC/C,EACD,MAAM,CAAC,EAAE,cAAc,EACvB,KAAK,GAAE,MAAU,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CA2FrB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,IAAI,EAAE,CAAC,EACP,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EACrE,SAAS,EAAE,QAAQ,GAAG,QAAQ,EAC9B,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAC/C,GACA,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAyCrB"}
|
package/dist/access/engine.js
CHANGED
|
@@ -246,12 +246,29 @@ export async function filterReadableFields(item, fieldConfigs, args, config, dep
|
|
|
246
246
|
*/
|
|
247
247
|
export async function filterWritableFields(data, fieldConfigs, operation, args) {
|
|
248
248
|
const filtered = {};
|
|
249
|
+
// Build a set of foreign key field names to exclude
|
|
250
|
+
// Foreign keys should not be in the data when using Prisma's relation syntax
|
|
251
|
+
const foreignKeyFields = new Set();
|
|
252
|
+
for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) {
|
|
253
|
+
if (fieldConfig.type === 'relationship') {
|
|
254
|
+
// For non-many relationships, Prisma creates a foreign key field named `${fieldName}Id`
|
|
255
|
+
const relConfig = fieldConfig;
|
|
256
|
+
if (!relConfig.many) {
|
|
257
|
+
foreignKeyFields.add(`${fieldName}Id`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
249
261
|
for (const [fieldName, value] of Object.entries(data)) {
|
|
250
262
|
const fieldConfig = fieldConfigs[fieldName];
|
|
251
263
|
// Skip system fields
|
|
252
264
|
if (['id', 'createdAt', 'updatedAt'].includes(fieldName)) {
|
|
253
265
|
continue;
|
|
254
266
|
}
|
|
267
|
+
// Skip foreign key fields (e.g., authorId) when their corresponding relationship field exists
|
|
268
|
+
// This prevents conflicts when using Prisma's relation syntax (e.g., author: { connect: { id } })
|
|
269
|
+
if (foreignKeyFields.has(fieldName)) {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
255
272
|
// Check field access (checkFieldAccess already handles sudo mode)
|
|
256
273
|
const canWrite = await checkFieldAccess(fieldConfig?.access, operation, {
|
|
257
274
|
...args,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/access/engine.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/access/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.test.d.ts","sourceRoot":"","sources":["../../src/access/engine.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { filterWritableFields } from './engine.js';
|
|
3
|
+
describe('filterWritableFields', () => {
|
|
4
|
+
it('should filter out foreign key fields when their corresponding relationship field exists', async () => {
|
|
5
|
+
// Setup: Define field configs with a relationship field
|
|
6
|
+
const fieldConfigs = {
|
|
7
|
+
title: {
|
|
8
|
+
type: 'text',
|
|
9
|
+
},
|
|
10
|
+
author: {
|
|
11
|
+
type: 'relationship',
|
|
12
|
+
many: false,
|
|
13
|
+
},
|
|
14
|
+
tags: {
|
|
15
|
+
type: 'relationship',
|
|
16
|
+
many: true, // Many-to-many relationships don't have foreign keys
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
// Data that includes both the foreign key (authorId) and other fields
|
|
20
|
+
const data = {
|
|
21
|
+
title: 'Test Post',
|
|
22
|
+
authorId: 'user-123', // This should be filtered out
|
|
23
|
+
tagsId: 'tag-456', // This should NOT be filtered (tags is many:true)
|
|
24
|
+
author: {
|
|
25
|
+
connect: { id: 'user-123' },
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
const filtered = await filterWritableFields(data, fieldConfigs, 'create', {
|
|
29
|
+
session: null,
|
|
30
|
+
context: {
|
|
31
|
+
session: null,
|
|
32
|
+
_isSudo: true, // Use sudo to bypass access control checks
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
// authorId should be filtered out
|
|
37
|
+
expect(filtered).not.toHaveProperty('authorId');
|
|
38
|
+
// title should remain
|
|
39
|
+
expect(filtered).toHaveProperty('title', 'Test Post');
|
|
40
|
+
// author relationship should remain
|
|
41
|
+
expect(filtered).toHaveProperty('author');
|
|
42
|
+
expect(filtered.author).toEqual({ connect: { id: 'user-123' } });
|
|
43
|
+
// tagsId should remain (tags is many:true, so no foreign key is created)
|
|
44
|
+
expect(filtered).toHaveProperty('tagsId', 'tag-456');
|
|
45
|
+
});
|
|
46
|
+
it('should filter out system fields', async () => {
|
|
47
|
+
const fieldConfigs = {
|
|
48
|
+
title: { type: 'text' },
|
|
49
|
+
};
|
|
50
|
+
const data = {
|
|
51
|
+
id: 'post-123',
|
|
52
|
+
title: 'Test',
|
|
53
|
+
createdAt: new Date(),
|
|
54
|
+
updatedAt: new Date(),
|
|
55
|
+
};
|
|
56
|
+
const filtered = await filterWritableFields(data, fieldConfigs, 'create', {
|
|
57
|
+
session: null,
|
|
58
|
+
context: {
|
|
59
|
+
session: null,
|
|
60
|
+
_isSudo: true,
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
// System fields should be filtered out
|
|
65
|
+
expect(filtered).not.toHaveProperty('id');
|
|
66
|
+
expect(filtered).not.toHaveProperty('createdAt');
|
|
67
|
+
expect(filtered).not.toHaveProperty('updatedAt');
|
|
68
|
+
// Regular fields should remain
|
|
69
|
+
expect(filtered).toHaveProperty('title', 'Test');
|
|
70
|
+
});
|
|
71
|
+
it('should handle update operation', async () => {
|
|
72
|
+
const fieldConfigs = {
|
|
73
|
+
title: { type: 'text' },
|
|
74
|
+
author: {
|
|
75
|
+
type: 'relationship',
|
|
76
|
+
many: false,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const data = {
|
|
80
|
+
title: 'Updated Title',
|
|
81
|
+
authorId: 'user-456', // Should be filtered out
|
|
82
|
+
author: {
|
|
83
|
+
connect: { id: 'user-456' },
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
const filtered = await filterWritableFields(data, fieldConfigs, 'update', {
|
|
87
|
+
session: null,
|
|
88
|
+
item: { id: 'post-123' },
|
|
89
|
+
context: {
|
|
90
|
+
session: null,
|
|
91
|
+
_isSudo: true,
|
|
92
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
expect(filtered).not.toHaveProperty('authorId');
|
|
96
|
+
expect(filtered).toHaveProperty('title', 'Updated Title');
|
|
97
|
+
expect(filtered).toHaveProperty('author');
|
|
98
|
+
});
|
|
99
|
+
it('should not filter fields that happen to end with "Id" but are not foreign keys', async () => {
|
|
100
|
+
const fieldConfigs = {
|
|
101
|
+
trackingId: { type: 'text' }, // Regular field that happens to end with "Id"
|
|
102
|
+
author: {
|
|
103
|
+
type: 'relationship',
|
|
104
|
+
many: false,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
const data = {
|
|
108
|
+
trackingId: 'track-123', // Should NOT be filtered (it's a regular field)
|
|
109
|
+
authorId: 'user-456', // SHOULD be filtered (it's a foreign key)
|
|
110
|
+
};
|
|
111
|
+
const filtered = await filterWritableFields(data, fieldConfigs, 'create', {
|
|
112
|
+
session: null,
|
|
113
|
+
context: {
|
|
114
|
+
session: null,
|
|
115
|
+
_isSudo: true,
|
|
116
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
// trackingId is a defined field, so it should remain
|
|
120
|
+
expect(filtered).toHaveProperty('trackingId', 'track-123');
|
|
121
|
+
// authorId is a foreign key for author relationship, so it should be filtered
|
|
122
|
+
expect(filtered).not.toHaveProperty('authorId');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
//# sourceMappingURL=engine.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.test.js","sourceRoot":"","sources":["../../src/access/engine.test.ts"],"names":[],"mappings":"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"}
|
package/dist/access/types.d.ts
CHANGED
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Session
|
|
2
|
+
* Session interface - can be augmented by developers to add custom fields
|
|
3
|
+
*
|
|
4
|
+
* By default, Session is a permissive object that can contain any properties.
|
|
5
|
+
* To get type safety and autocomplete, use module augmentation:
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // types/session.d.ts
|
|
10
|
+
* import '@opensaas/stack-core'
|
|
11
|
+
*
|
|
12
|
+
* declare module '@opensaas/stack-core' {
|
|
13
|
+
* interface Session {
|
|
14
|
+
* userId: string
|
|
15
|
+
* email: string
|
|
16
|
+
* role: 'admin' | 'user'
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* After augmentation, session will be fully typed everywhere:
|
|
22
|
+
* - Access control functions
|
|
23
|
+
* - Hooks (resolveInput, validateInput, etc.)
|
|
24
|
+
* - Context object
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // With augmentation, this is fully typed:
|
|
29
|
+
* const isAdmin: AccessControl = ({ session }) => {
|
|
30
|
+
* return session?.role === 'admin' // ✅ Autocomplete works
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
3
33
|
*/
|
|
4
|
-
export
|
|
5
|
-
userId?: string;
|
|
34
|
+
export interface Session {
|
|
6
35
|
[key: string]: unknown;
|
|
7
|
-
}
|
|
36
|
+
}
|
|
8
37
|
/**
|
|
9
38
|
* Generic Prisma model delegate type
|
|
10
39
|
*/
|
|
@@ -81,15 +110,16 @@ export type StorageUtils = {
|
|
|
81
110
|
};
|
|
82
111
|
/**
|
|
83
112
|
* Context type (simplified for access control)
|
|
113
|
+
* Using interface instead of type to allow module augmentation
|
|
84
114
|
*/
|
|
85
|
-
export
|
|
86
|
-
session: Session;
|
|
115
|
+
export interface AccessContext<TPrisma extends PrismaClientLike = PrismaClientLike> {
|
|
116
|
+
session: Session | null;
|
|
87
117
|
prisma: TPrisma;
|
|
88
118
|
db: AccessControlledDB<TPrisma>;
|
|
89
119
|
storage: StorageUtils;
|
|
120
|
+
plugins: Record<string, unknown>;
|
|
90
121
|
_isSudo: boolean;
|
|
91
|
-
|
|
92
|
-
};
|
|
122
|
+
}
|
|
93
123
|
/**
|
|
94
124
|
* Prisma filter type - represents a where clause
|
|
95
125
|
* Uses Partial to allow filtering by any subset of fields
|
|
@@ -102,7 +132,7 @@ export type PrismaFilter<T = Record<string, unknown>> = Partial<Record<keyof T,
|
|
|
102
132
|
* - PrismaFilter: Prisma where clause to filter results
|
|
103
133
|
*/
|
|
104
134
|
export type AccessControl<T = Record<string, unknown>> = (args: {
|
|
105
|
-
session: Session;
|
|
135
|
+
session: Session | null;
|
|
106
136
|
item?: T;
|
|
107
137
|
context: AccessContext;
|
|
108
138
|
}) => boolean | PrismaFilter<T> | Promise<boolean | PrismaFilter<T>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/access/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/access/types.ts"],"names":[],"mappings":"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"}
|