@opensaas/stack-core 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.
- package/.turbo/turbo-build.log +4 -0
- package/README.md +447 -0
- package/dist/access/engine.d.ts +73 -0
- package/dist/access/engine.d.ts.map +1 -0
- package/dist/access/engine.js +244 -0
- package/dist/access/engine.js.map +1 -0
- package/dist/access/field-transforms.d.ts +47 -0
- package/dist/access/field-transforms.d.ts.map +1 -0
- package/dist/access/field-transforms.js +2 -0
- package/dist/access/field-transforms.js.map +1 -0
- package/dist/access/index.d.ts +3 -0
- package/dist/access/index.d.ts.map +1 -0
- package/dist/access/index.js +2 -0
- package/dist/access/index.js.map +1 -0
- package/dist/access/types.d.ts +83 -0
- package/dist/access/types.d.ts.map +1 -0
- package/dist/access/types.js +2 -0
- package/dist/access/types.js.map +1 -0
- package/dist/config/index.d.ts +39 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +38 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +413 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/context/index.d.ts +31 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +524 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/nested-operations.d.ts +10 -0
- package/dist/context/nested-operations.d.ts.map +1 -0
- package/dist/context/nested-operations.js +261 -0
- package/dist/context/nested-operations.js.map +1 -0
- package/dist/fields/index.d.ts +78 -0
- package/dist/fields/index.d.ts.map +1 -0
- package/dist/fields/index.js +381 -0
- package/dist/fields/index.js.map +1 -0
- package/dist/hooks/index.d.ts +58 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +79 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/case-utils.d.ts +49 -0
- package/dist/lib/case-utils.d.ts.map +1 -0
- package/dist/lib/case-utils.js +68 -0
- package/dist/lib/case-utils.js.map +1 -0
- package/dist/lib/case-utils.test.d.ts +2 -0
- package/dist/lib/case-utils.test.d.ts.map +1 -0
- package/dist/lib/case-utils.test.js +101 -0
- package/dist/lib/case-utils.test.js.map +1 -0
- package/dist/utils/password.d.ts +81 -0
- package/dist/utils/password.d.ts.map +1 -0
- package/dist/utils/password.js +132 -0
- package/dist/utils/password.js.map +1 -0
- package/dist/validation/schema.d.ts +17 -0
- package/dist/validation/schema.d.ts.map +1 -0
- package/dist/validation/schema.js +42 -0
- package/dist/validation/schema.js.map +1 -0
- package/dist/validation/schema.test.d.ts +2 -0
- package/dist/validation/schema.test.d.ts.map +1 -0
- package/dist/validation/schema.test.js +143 -0
- package/dist/validation/schema.test.js.map +1 -0
- package/docs/type-distribution-fix.md +136 -0
- package/package.json +48 -0
- package/src/access/engine.ts +360 -0
- package/src/access/field-transforms.ts +99 -0
- package/src/access/index.ts +20 -0
- package/src/access/types.ts +103 -0
- package/src/config/index.ts +71 -0
- package/src/config/types.ts +478 -0
- package/src/context/index.ts +814 -0
- package/src/context/nested-operations.ts +412 -0
- package/src/fields/index.ts +438 -0
- package/src/hooks/index.ts +132 -0
- package/src/index.ts +62 -0
- package/src/lib/case-utils.test.ts +127 -0
- package/src/lib/case-utils.ts +74 -0
- package/src/utils/password.ts +147 -0
- package/src/validation/schema.test.ts +171 -0
- package/src/validation/schema.ts +59 -0
- package/tests/access-relationships.test.ts +613 -0
- package/tests/access.test.ts +499 -0
- package/tests/config.test.ts +195 -0
- package/tests/context.test.ts +248 -0
- package/tests/hooks.test.ts +417 -0
- package/tests/password-type-distribution.test.ts +155 -0
- package/tests/password-types.test.ts +147 -0
- package/tests/password.test.ts +249 -0
- package/tsconfig.json +12 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/vitest.config.ts +27 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import type { AccessControl, FieldAccess } from '../access/types.js';
|
|
2
|
+
import type { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* Field configuration types
|
|
5
|
+
*/
|
|
6
|
+
export type FieldType = 'text' | 'integer' | 'checkbox' | 'timestamp' | 'password' | 'select' | 'relationship' | string;
|
|
7
|
+
/**
|
|
8
|
+
* Field-level hooks for data transformation and side effects
|
|
9
|
+
* Allows field types to define custom behavior during operations
|
|
10
|
+
*
|
|
11
|
+
* @template TInput - Type of the input value (what goes into the database)
|
|
12
|
+
* @template TOutput - Type of the output value (what comes out of the database)
|
|
13
|
+
* @template TItem - Type of the parent item/record
|
|
14
|
+
*/
|
|
15
|
+
export type FieldHooks<TInput = any, TOutput = TInput, TItem = any> = {
|
|
16
|
+
/**
|
|
17
|
+
* Transform field value before database write
|
|
18
|
+
* Called during create/update operations after list-level resolveInput but before validation
|
|
19
|
+
* This is where you should transform input data (e.g., hash passwords, normalize values)
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* resolveInput: async ({ inputValue, operation }) => {
|
|
24
|
+
* if (typeof inputValue === 'string' && !isHashedPassword(inputValue)) {
|
|
25
|
+
* return await hashPassword(inputValue)
|
|
26
|
+
* }
|
|
27
|
+
* return inputValue
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
resolveInput?: (args: {
|
|
32
|
+
operation: 'create' | 'update';
|
|
33
|
+
inputValue: TInput | undefined;
|
|
34
|
+
item?: TItem;
|
|
35
|
+
listKey: string;
|
|
36
|
+
fieldName: string;
|
|
37
|
+
context: import('../access/types.js').AccessContext;
|
|
38
|
+
}) => Promise<TInput | undefined> | TInput | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Perform side effects before database write
|
|
41
|
+
* Called during create/update/delete operations after validation and access control
|
|
42
|
+
* This should ONLY contain side effects (logging, notifications, etc.), not data transformation
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* beforeOperation: async ({ resolvedValue, operation, item }) => {
|
|
47
|
+
* console.log(`About to ${operation} field with value:`, resolvedValue)
|
|
48
|
+
* await sendAuditLog({ operation, item })
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
beforeOperation?: (args: {
|
|
53
|
+
operation: 'create' | 'update' | 'delete';
|
|
54
|
+
resolvedValue: TInput | undefined;
|
|
55
|
+
item?: TItem;
|
|
56
|
+
listKey: string;
|
|
57
|
+
fieldName: string;
|
|
58
|
+
context: import('../access/types.js').AccessContext;
|
|
59
|
+
}) => Promise<void> | void;
|
|
60
|
+
/**
|
|
61
|
+
* Perform side effects after database operation
|
|
62
|
+
* Called after any database operation (create/update/delete/query)
|
|
63
|
+
* This should ONLY contain side effects (logging, cache invalidation, etc.), not data transformation
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* afterOperation: async ({ operation, value, item }) => {
|
|
68
|
+
* await invalidateCache({ listKey, itemId: item.id })
|
|
69
|
+
* await sendWebhook({ operation, item })
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
afterOperation?: (args: {
|
|
74
|
+
operation: 'create' | 'update' | 'delete';
|
|
75
|
+
value: TInput | undefined;
|
|
76
|
+
item: TItem;
|
|
77
|
+
listKey: string;
|
|
78
|
+
fieldName: string;
|
|
79
|
+
context: import('../access/types.js').AccessContext;
|
|
80
|
+
} | {
|
|
81
|
+
operation: 'query';
|
|
82
|
+
value: TOutput | undefined;
|
|
83
|
+
item: TItem;
|
|
84
|
+
listKey: string;
|
|
85
|
+
fieldName: string;
|
|
86
|
+
context: import('../access/types.js').AccessContext;
|
|
87
|
+
}) => Promise<void> | void;
|
|
88
|
+
/**
|
|
89
|
+
* Transform field value after database read
|
|
90
|
+
* Called when returning results from query operations
|
|
91
|
+
* This is where you should transform output data (e.g., wrap passwords, format values)
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* resolveOutput: ({ value }) => {
|
|
96
|
+
* if (typeof value === 'string' && value.length > 0) {
|
|
97
|
+
* return new HashedPassword(value)
|
|
98
|
+
* }
|
|
99
|
+
* return value
|
|
100
|
+
* }
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
resolveOutput?: (args: {
|
|
104
|
+
operation: 'query';
|
|
105
|
+
value: TInput | undefined;
|
|
106
|
+
item: TItem;
|
|
107
|
+
listKey: string;
|
|
108
|
+
fieldName: string;
|
|
109
|
+
context: import('../access/types.js').AccessContext;
|
|
110
|
+
}) => TOutput | undefined;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Configuration for patching Prisma-generated types
|
|
114
|
+
* Allows fields to transform their types in query results
|
|
115
|
+
*/
|
|
116
|
+
export type TypePatchConfig = {
|
|
117
|
+
/**
|
|
118
|
+
* The TypeScript type to use in Prisma result types (e.g., Payload scalars)
|
|
119
|
+
* This is an import statement like: "import('@opensaas/stack-core').HashedPassword"
|
|
120
|
+
*/
|
|
121
|
+
resultType: string;
|
|
122
|
+
/**
|
|
123
|
+
* Optional: Where to apply the patch
|
|
124
|
+
* - 'scalars-only': Only patch in Payload scalars (default, safest)
|
|
125
|
+
* - 'all': Patch everywhere the field appears (including inputs)
|
|
126
|
+
*/
|
|
127
|
+
patchScope?: 'scalars-only' | 'all';
|
|
128
|
+
};
|
|
129
|
+
export type BaseFieldConfig<TInput = any, TOutput = TInput> = {
|
|
130
|
+
type: string;
|
|
131
|
+
access?: FieldAccess;
|
|
132
|
+
defaultValue?: unknown;
|
|
133
|
+
hooks?: FieldHooks<TInput, TOutput, any>;
|
|
134
|
+
/**
|
|
135
|
+
* Type patching configuration for Prisma-generated types
|
|
136
|
+
* When specified, the generator will patch Prisma's types to use
|
|
137
|
+
* the specified type in query results instead of the original type
|
|
138
|
+
*/
|
|
139
|
+
typePatch?: TypePatchConfig;
|
|
140
|
+
ui?: {
|
|
141
|
+
/**
|
|
142
|
+
* Custom React component to render this field
|
|
143
|
+
* Overrides the default component for this field type
|
|
144
|
+
* Uses `any` to accept any React component type without overly complex generics
|
|
145
|
+
*/
|
|
146
|
+
component?: any;
|
|
147
|
+
/**
|
|
148
|
+
* Custom field type name to use from the global registry
|
|
149
|
+
* e.g., "color" to use a globally registered ColorPickerField
|
|
150
|
+
*/
|
|
151
|
+
fieldType?: string;
|
|
152
|
+
/**
|
|
153
|
+
* Transform field value before sending to client (browser)
|
|
154
|
+
* Useful for sensitive fields (e.g., passwords) or complex data structures
|
|
155
|
+
* that shouldn't be serialized in their raw form
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* // Password field: send only whether it's set, not the hash
|
|
160
|
+
* valueForClientSerialization: ({ value }) => ({ isSet: !!value })
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
valueForClientSerialization?: (args: {
|
|
164
|
+
value: unknown;
|
|
165
|
+
}) => unknown;
|
|
166
|
+
/**
|
|
167
|
+
* Additional UI-specific configuration
|
|
168
|
+
*/
|
|
169
|
+
[key: string]: unknown;
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Generate Zod schema for this field
|
|
173
|
+
* @param fieldName - The name of the field (for error messages)
|
|
174
|
+
* @param operation - Whether this is a create or update operation
|
|
175
|
+
*/
|
|
176
|
+
getZodSchema?: (fieldName: string, operation: 'create' | 'update') => z.ZodTypeAny;
|
|
177
|
+
/**
|
|
178
|
+
* Get Prisma type and modifiers for schema generation
|
|
179
|
+
* @param fieldName - The name of the field (for generating modifiers)
|
|
180
|
+
* @returns Prisma type string and optional modifiers
|
|
181
|
+
*/
|
|
182
|
+
getPrismaType?: (fieldName: string) => {
|
|
183
|
+
type: string;
|
|
184
|
+
modifiers?: string;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Get TypeScript type information for type generation
|
|
188
|
+
* @returns TypeScript type string and optionality
|
|
189
|
+
*/
|
|
190
|
+
getTypeScriptType?: () => {
|
|
191
|
+
type: string;
|
|
192
|
+
optional: boolean;
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
export type TextField = BaseFieldConfig<string, string> & {
|
|
196
|
+
type: 'text';
|
|
197
|
+
validation?: {
|
|
198
|
+
isRequired?: boolean;
|
|
199
|
+
length?: {
|
|
200
|
+
min?: number;
|
|
201
|
+
max?: number;
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
isIndexed?: boolean | 'unique';
|
|
205
|
+
ui?: {
|
|
206
|
+
displayMode?: 'input' | 'textarea';
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
export type IntegerField = BaseFieldConfig<number, number> & {
|
|
210
|
+
type: 'integer';
|
|
211
|
+
validation?: {
|
|
212
|
+
isRequired?: boolean;
|
|
213
|
+
min?: number;
|
|
214
|
+
max?: number;
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
export type CheckboxField = BaseFieldConfig<boolean, boolean> & {
|
|
218
|
+
type: 'checkbox';
|
|
219
|
+
};
|
|
220
|
+
export type TimestampField = BaseFieldConfig<Date, Date> & {
|
|
221
|
+
type: 'timestamp';
|
|
222
|
+
defaultValue?: {
|
|
223
|
+
kind: 'now';
|
|
224
|
+
} | Date;
|
|
225
|
+
};
|
|
226
|
+
export type PasswordField = BaseFieldConfig<string, import('../utils/password.js').HashedPassword> & {
|
|
227
|
+
type: 'password';
|
|
228
|
+
validation?: {
|
|
229
|
+
isRequired?: boolean;
|
|
230
|
+
};
|
|
231
|
+
};
|
|
232
|
+
export type SelectField = BaseFieldConfig<string, string> & {
|
|
233
|
+
type: 'select';
|
|
234
|
+
options: Array<{
|
|
235
|
+
label: string;
|
|
236
|
+
value: string;
|
|
237
|
+
}>;
|
|
238
|
+
validation?: {
|
|
239
|
+
isRequired?: boolean;
|
|
240
|
+
};
|
|
241
|
+
ui?: {
|
|
242
|
+
displayMode?: 'select' | 'segmented-control' | 'radio';
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
export type RelationshipField = BaseFieldConfig<string | string[], string | string[]> & {
|
|
246
|
+
type: 'relationship';
|
|
247
|
+
ref: string;
|
|
248
|
+
many?: boolean;
|
|
249
|
+
ui?: {
|
|
250
|
+
displayMode?: 'select' | 'cards';
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
export type FieldConfig = TextField | IntegerField | CheckboxField | TimestampField | PasswordField | SelectField | RelationshipField | BaseFieldConfig;
|
|
254
|
+
/**
|
|
255
|
+
* List configuration types
|
|
256
|
+
*/
|
|
257
|
+
/**
|
|
258
|
+
* Utility type to inject item type into a single field config
|
|
259
|
+
* Extracts TInput and TOutput from BaseFieldConfig<TInput, TOutput> and reconstructs with new hooks type
|
|
260
|
+
*/
|
|
261
|
+
type WithItemType<TField extends FieldConfig, TItem> = TField extends BaseFieldConfig<infer TInput, infer TOutput> ? Omit<TField, 'hooks'> & {
|
|
262
|
+
hooks?: FieldHooks<TInput, TOutput, TItem>;
|
|
263
|
+
} : TField;
|
|
264
|
+
/**
|
|
265
|
+
* Utility type to transform all fields in a record to inject item type
|
|
266
|
+
* Maps over each field and applies WithItemType transformation
|
|
267
|
+
*/
|
|
268
|
+
export type FieldsWithItemType<TFields extends Record<string, FieldConfig>, TItem = any> = {
|
|
269
|
+
[K in keyof TFields]: WithItemType<TFields[K], TItem>;
|
|
270
|
+
};
|
|
271
|
+
export type OperationAccess<T = any> = {
|
|
272
|
+
query?: AccessControl<T>;
|
|
273
|
+
create?: AccessControl<T>;
|
|
274
|
+
update?: AccessControl<T>;
|
|
275
|
+
delete?: AccessControl<T>;
|
|
276
|
+
};
|
|
277
|
+
export type HookArgs<T = Record<string, unknown>> = {
|
|
278
|
+
operation: 'create' | 'update' | 'delete';
|
|
279
|
+
resolvedData?: Partial<T>;
|
|
280
|
+
item?: T;
|
|
281
|
+
context: import('../access/types.js').AccessContext;
|
|
282
|
+
};
|
|
283
|
+
export type Hooks<T = Record<string, unknown>> = {
|
|
284
|
+
resolveInput?: (args: HookArgs<T> & {
|
|
285
|
+
operation: 'create' | 'update';
|
|
286
|
+
}) => Promise<Partial<T>>;
|
|
287
|
+
validateInput?: (args: HookArgs<T> & {
|
|
288
|
+
operation: 'create' | 'update';
|
|
289
|
+
addValidationError: (msg: string) => void;
|
|
290
|
+
}) => Promise<void>;
|
|
291
|
+
beforeOperation?: (args: HookArgs<T>) => Promise<void>;
|
|
292
|
+
afterOperation?: (args: HookArgs<T>) => Promise<void>;
|
|
293
|
+
};
|
|
294
|
+
export type ListConfig<T = any> = {
|
|
295
|
+
fields: FieldsWithItemType<Record<string, FieldConfig>, T>;
|
|
296
|
+
access?: {
|
|
297
|
+
operation?: OperationAccess<T>;
|
|
298
|
+
};
|
|
299
|
+
hooks?: Hooks<T>;
|
|
300
|
+
};
|
|
301
|
+
/**
|
|
302
|
+
* Database configuration
|
|
303
|
+
*/
|
|
304
|
+
export type DatabaseConfig = {
|
|
305
|
+
provider: 'postgresql' | 'mysql' | 'sqlite';
|
|
306
|
+
url: string;
|
|
307
|
+
/**
|
|
308
|
+
* Optional factory function to create a custom Prisma client instance
|
|
309
|
+
* Receives the PrismaClient class and returns a configured instance
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
* ```typescript
|
|
313
|
+
* import { PrismaNeon } from '@prisma/adapter-neon'
|
|
314
|
+
* import { neonConfig } from '@neondatabase/serverless'
|
|
315
|
+
* import ws from 'ws'
|
|
316
|
+
*
|
|
317
|
+
* prismaClientConstructor: (PrismaClient) => {
|
|
318
|
+
* neonConfig.webSocketConstructor = ws
|
|
319
|
+
* const adapter = new PrismaNeon({
|
|
320
|
+
* connectionString: process.env.DATABASE_URL
|
|
321
|
+
* })
|
|
322
|
+
* return new PrismaClient({ adapter })
|
|
323
|
+
* }
|
|
324
|
+
* ```
|
|
325
|
+
*/
|
|
326
|
+
prismaClientConstructor?: (PrismaClientClass: any) => any;
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* Session configuration
|
|
330
|
+
*/
|
|
331
|
+
export type SessionConfig = {
|
|
332
|
+
getSession: () => Promise<any>;
|
|
333
|
+
};
|
|
334
|
+
/**
|
|
335
|
+
* Theme preset options
|
|
336
|
+
*/
|
|
337
|
+
export type ThemePreset = 'modern' | 'classic' | 'neon';
|
|
338
|
+
/**
|
|
339
|
+
* Custom theme colors (HSL values without hsl() wrapper)
|
|
340
|
+
* Format: "220 20% 97%" (hue saturation lightness)
|
|
341
|
+
*/
|
|
342
|
+
export type ThemeColors = {
|
|
343
|
+
background?: string;
|
|
344
|
+
foreground?: string;
|
|
345
|
+
card?: string;
|
|
346
|
+
cardForeground?: string;
|
|
347
|
+
popover?: string;
|
|
348
|
+
popoverForeground?: string;
|
|
349
|
+
primary?: string;
|
|
350
|
+
primaryForeground?: string;
|
|
351
|
+
secondary?: string;
|
|
352
|
+
secondaryForeground?: string;
|
|
353
|
+
muted?: string;
|
|
354
|
+
mutedForeground?: string;
|
|
355
|
+
accent?: string;
|
|
356
|
+
accentForeground?: string;
|
|
357
|
+
destructive?: string;
|
|
358
|
+
destructiveForeground?: string;
|
|
359
|
+
border?: string;
|
|
360
|
+
input?: string;
|
|
361
|
+
ring?: string;
|
|
362
|
+
gradientFrom?: string;
|
|
363
|
+
gradientTo?: string;
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
|
+
* Theme configuration
|
|
367
|
+
*/
|
|
368
|
+
export type ThemeConfig = {
|
|
369
|
+
/**
|
|
370
|
+
* Preset theme to use
|
|
371
|
+
* @default "modern"
|
|
372
|
+
*/
|
|
373
|
+
preset?: ThemePreset;
|
|
374
|
+
/**
|
|
375
|
+
* Custom color overrides for light mode
|
|
376
|
+
*/
|
|
377
|
+
colors?: ThemeColors;
|
|
378
|
+
/**
|
|
379
|
+
* Custom color overrides for dark mode
|
|
380
|
+
*/
|
|
381
|
+
darkColors?: ThemeColors;
|
|
382
|
+
/**
|
|
383
|
+
* Border radius in rem
|
|
384
|
+
* @default 0.75
|
|
385
|
+
*/
|
|
386
|
+
radius?: number;
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
* UI configuration
|
|
390
|
+
*/
|
|
391
|
+
export type UIConfig = {
|
|
392
|
+
basePath?: string;
|
|
393
|
+
/**
|
|
394
|
+
* Theme configuration for the admin UI
|
|
395
|
+
*/
|
|
396
|
+
theme?: ThemeConfig;
|
|
397
|
+
};
|
|
398
|
+
/**
|
|
399
|
+
* Main configuration type
|
|
400
|
+
*/
|
|
401
|
+
export type OpenSaasConfig = {
|
|
402
|
+
db: DatabaseConfig;
|
|
403
|
+
lists: Record<string, ListConfig>;
|
|
404
|
+
session?: SessionConfig;
|
|
405
|
+
ui?: UIConfig;
|
|
406
|
+
/**
|
|
407
|
+
* Path where OpenSaas generates files (context, types, patched Prisma client)
|
|
408
|
+
* @default ".opensaas"
|
|
409
|
+
*/
|
|
410
|
+
opensaasPath?: string;
|
|
411
|
+
};
|
|
412
|
+
export {};
|
|
413
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { OpenSaasConfig } from '../config/types.js';
|
|
2
|
+
import type { Session, AccessControlledDB } from '../access/index.js';
|
|
3
|
+
import type { PrismaClientLike } from '../access/types.js';
|
|
4
|
+
export type ServerActionProps = {
|
|
5
|
+
listKey: string;
|
|
6
|
+
action: 'create';
|
|
7
|
+
data: Record<string, unknown>;
|
|
8
|
+
} | {
|
|
9
|
+
listKey: string;
|
|
10
|
+
action: 'update';
|
|
11
|
+
id: string;
|
|
12
|
+
data: Record<string, unknown>;
|
|
13
|
+
} | {
|
|
14
|
+
listKey: string;
|
|
15
|
+
action: 'delete';
|
|
16
|
+
id: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Create an access-controlled context
|
|
20
|
+
*
|
|
21
|
+
* @param config - OpenSaas configuration
|
|
22
|
+
* @param prisma - Your Prisma client instance (pass as generic for type safety)
|
|
23
|
+
* @param session - Current session object (or null if not authenticated)
|
|
24
|
+
*/
|
|
25
|
+
export declare function getContext<TConfig extends OpenSaasConfig, TPrisma extends PrismaClientLike = PrismaClientLike>(config: TConfig, prisma: TPrisma, session: Session): {
|
|
26
|
+
db: AccessControlledDB<TPrisma>;
|
|
27
|
+
session: Session;
|
|
28
|
+
prisma: TPrisma;
|
|
29
|
+
serverAction: (props: ServerActionProps) => Promise<unknown>;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,oBAAoB,CAAA;AACpE,OAAO,KAAK,EAAE,OAAO,EAAiB,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAkBpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAmJ1D,MAAM,MAAM,iBAAiB,GACzB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACpE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAChF;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AACrD;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,OAAO,SAAS,cAAc,EAC9B,OAAO,SAAS,gBAAgB,GAAG,gBAAgB,EAEnD,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,OAAO,GACf;IACD,EAAE,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAA;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;IACf,YAAY,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC7D,CAyDA"}
|