@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.
Files changed (50) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +202 -0
  3. package/CLAUDE.md +46 -1
  4. package/dist/access/engine.d.ts +6 -5
  5. package/dist/access/engine.d.ts.map +1 -1
  6. package/dist/access/engine.js +17 -0
  7. package/dist/access/engine.js.map +1 -1
  8. package/dist/access/engine.test.d.ts +2 -0
  9. package/dist/access/engine.test.d.ts.map +1 -0
  10. package/dist/access/engine.test.js +125 -0
  11. package/dist/access/engine.test.js.map +1 -0
  12. package/dist/access/types.d.ts +39 -9
  13. package/dist/access/types.d.ts.map +1 -1
  14. package/dist/config/index.d.ts +38 -18
  15. package/dist/config/index.d.ts.map +1 -1
  16. package/dist/config/index.js +34 -14
  17. package/dist/config/index.js.map +1 -1
  18. package/dist/config/plugin-engine.d.ts.map +1 -1
  19. package/dist/config/plugin-engine.js +6 -0
  20. package/dist/config/plugin-engine.js.map +1 -1
  21. package/dist/config/types.d.ts +128 -21
  22. package/dist/config/types.d.ts.map +1 -1
  23. package/dist/context/index.d.ts +5 -3
  24. package/dist/context/index.d.ts.map +1 -1
  25. package/dist/context/index.js +127 -14
  26. package/dist/context/index.js.map +1 -1
  27. package/dist/fields/index.d.ts.map +1 -1
  28. package/dist/fields/index.js +9 -8
  29. package/dist/fields/index.js.map +1 -1
  30. package/dist/hooks/index.d.ts +28 -12
  31. package/dist/hooks/index.d.ts.map +1 -1
  32. package/dist/hooks/index.js +16 -0
  33. package/dist/hooks/index.js.map +1 -1
  34. package/package.json +3 -4
  35. package/src/access/engine.test.ts +145 -0
  36. package/src/access/engine.ts +25 -6
  37. package/src/access/types.ts +38 -8
  38. package/src/config/index.ts +46 -19
  39. package/src/config/plugin-engine.ts +7 -0
  40. package/src/config/types.ts +149 -18
  41. package/src/context/index.ts +163 -17
  42. package/src/fields/index.ts +8 -7
  43. package/src/hooks/index.ts +63 -20
  44. package/tests/context.test.ts +38 -6
  45. package/tests/field-types.test.ts +728 -0
  46. package/tests/password-type-distribution.test.ts +0 -1
  47. package/tests/password-types.test.ts +0 -1
  48. package/tests/plugin-engine.test.ts +1102 -0
  49. package/tests/sudo.test.ts +0 -1
  50. package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
1
 
2
- > @opensaas/stack-core@0.1.7 build /home/runner/work/stack/stack/packages/core
2
+ > @opensaas/stack-core@0.3.0 build /home/runner/work/stack/stack/packages/core
3
3
  > tsc
4
4
 
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
@@ -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":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/access/engine.ts"],"names":[],"mappings":"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"}
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=engine.test.d.ts.map
@@ -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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"}
@@ -1,10 +1,39 @@
1
1
  /**
2
- * Session type - can be extended by users
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 type Session = {
5
- userId?: string;
34
+ export interface Session {
6
35
  [key: string]: unknown;
7
- } | null;
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 type AccessContext<TPrisma extends PrismaClientLike = PrismaClientLike> = {
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
- [key: string]: unknown;
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":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/access/types.ts"],"names":[],"mappings":"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"}