@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.
Files changed (95) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/README.md +447 -0
  3. package/dist/access/engine.d.ts +73 -0
  4. package/dist/access/engine.d.ts.map +1 -0
  5. package/dist/access/engine.js +244 -0
  6. package/dist/access/engine.js.map +1 -0
  7. package/dist/access/field-transforms.d.ts +47 -0
  8. package/dist/access/field-transforms.d.ts.map +1 -0
  9. package/dist/access/field-transforms.js +2 -0
  10. package/dist/access/field-transforms.js.map +1 -0
  11. package/dist/access/index.d.ts +3 -0
  12. package/dist/access/index.d.ts.map +1 -0
  13. package/dist/access/index.js +2 -0
  14. package/dist/access/index.js.map +1 -0
  15. package/dist/access/types.d.ts +83 -0
  16. package/dist/access/types.d.ts.map +1 -0
  17. package/dist/access/types.js +2 -0
  18. package/dist/access/types.js.map +1 -0
  19. package/dist/config/index.d.ts +39 -0
  20. package/dist/config/index.d.ts.map +1 -0
  21. package/dist/config/index.js +38 -0
  22. package/dist/config/index.js.map +1 -0
  23. package/dist/config/types.d.ts +413 -0
  24. package/dist/config/types.d.ts.map +1 -0
  25. package/dist/config/types.js +2 -0
  26. package/dist/config/types.js.map +1 -0
  27. package/dist/context/index.d.ts +31 -0
  28. package/dist/context/index.d.ts.map +1 -0
  29. package/dist/context/index.js +524 -0
  30. package/dist/context/index.js.map +1 -0
  31. package/dist/context/nested-operations.d.ts +10 -0
  32. package/dist/context/nested-operations.d.ts.map +1 -0
  33. package/dist/context/nested-operations.js +261 -0
  34. package/dist/context/nested-operations.js.map +1 -0
  35. package/dist/fields/index.d.ts +78 -0
  36. package/dist/fields/index.d.ts.map +1 -0
  37. package/dist/fields/index.js +381 -0
  38. package/dist/fields/index.js.map +1 -0
  39. package/dist/hooks/index.d.ts +58 -0
  40. package/dist/hooks/index.d.ts.map +1 -0
  41. package/dist/hooks/index.js +79 -0
  42. package/dist/hooks/index.js.map +1 -0
  43. package/dist/index.d.ts +11 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +12 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/lib/case-utils.d.ts +49 -0
  48. package/dist/lib/case-utils.d.ts.map +1 -0
  49. package/dist/lib/case-utils.js +68 -0
  50. package/dist/lib/case-utils.js.map +1 -0
  51. package/dist/lib/case-utils.test.d.ts +2 -0
  52. package/dist/lib/case-utils.test.d.ts.map +1 -0
  53. package/dist/lib/case-utils.test.js +101 -0
  54. package/dist/lib/case-utils.test.js.map +1 -0
  55. package/dist/utils/password.d.ts +81 -0
  56. package/dist/utils/password.d.ts.map +1 -0
  57. package/dist/utils/password.js +132 -0
  58. package/dist/utils/password.js.map +1 -0
  59. package/dist/validation/schema.d.ts +17 -0
  60. package/dist/validation/schema.d.ts.map +1 -0
  61. package/dist/validation/schema.js +42 -0
  62. package/dist/validation/schema.js.map +1 -0
  63. package/dist/validation/schema.test.d.ts +2 -0
  64. package/dist/validation/schema.test.d.ts.map +1 -0
  65. package/dist/validation/schema.test.js +143 -0
  66. package/dist/validation/schema.test.js.map +1 -0
  67. package/docs/type-distribution-fix.md +136 -0
  68. package/package.json +48 -0
  69. package/src/access/engine.ts +360 -0
  70. package/src/access/field-transforms.ts +99 -0
  71. package/src/access/index.ts +20 -0
  72. package/src/access/types.ts +103 -0
  73. package/src/config/index.ts +71 -0
  74. package/src/config/types.ts +478 -0
  75. package/src/context/index.ts +814 -0
  76. package/src/context/nested-operations.ts +412 -0
  77. package/src/fields/index.ts +438 -0
  78. package/src/hooks/index.ts +132 -0
  79. package/src/index.ts +62 -0
  80. package/src/lib/case-utils.test.ts +127 -0
  81. package/src/lib/case-utils.ts +74 -0
  82. package/src/utils/password.ts +147 -0
  83. package/src/validation/schema.test.ts +171 -0
  84. package/src/validation/schema.ts +59 -0
  85. package/tests/access-relationships.test.ts +613 -0
  86. package/tests/access.test.ts +499 -0
  87. package/tests/config.test.ts +195 -0
  88. package/tests/context.test.ts +248 -0
  89. package/tests/hooks.test.ts +417 -0
  90. package/tests/password-type-distribution.test.ts +155 -0
  91. package/tests/password-types.test.ts +147 -0
  92. package/tests/password.test.ts +249 -0
  93. package/tsconfig.json +12 -0
  94. package/tsconfig.tsbuildinfo +1 -0
  95. 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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -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"}