@opensaas/stack-core 0.37.0 → 0.39.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 +191 -0
- package/CLAUDE.md +42 -3
- package/dist/access/access-filter.d.ts +70 -113
- package/dist/access/access-filter.d.ts.map +1 -1
- package/dist/access/access-filter.js +183 -210
- package/dist/access/access-filter.js.map +1 -1
- package/dist/access/access-filter.test.js +148 -188
- package/dist/access/access-filter.test.js.map +1 -1
- package/dist/access/declared-dependencies.d.ts +66 -26
- package/dist/access/declared-dependencies.d.ts.map +1 -1
- package/dist/access/declared-dependencies.js +62 -17
- package/dist/access/declared-dependencies.js.map +1 -1
- package/dist/access/declared-dependencies.test.d.ts +2 -0
- package/dist/access/declared-dependencies.test.d.ts.map +1 -0
- package/dist/access/declared-dependencies.test.js +226 -0
- package/dist/access/declared-dependencies.test.js.map +1 -0
- package/dist/access/depth-limits.d.ts +8 -7
- package/dist/access/depth-limits.d.ts.map +1 -1
- package/dist/access/depth-limits.js +8 -7
- package/dist/access/depth-limits.js.map +1 -1
- package/dist/access/engine.d.ts +0 -20
- package/dist/access/engine.d.ts.map +1 -1
- package/dist/access/engine.js +0 -25
- package/dist/access/engine.js.map +1 -1
- package/dist/access/errors.d.ts +61 -8
- package/dist/access/errors.d.ts.map +1 -1
- package/dist/access/errors.js +91 -12
- package/dist/access/errors.js.map +1 -1
- package/dist/access/field-access.d.ts +39 -1
- package/dist/access/field-access.d.ts.map +1 -1
- package/dist/access/field-access.js +108 -42
- package/dist/access/field-access.js.map +1 -1
- package/dist/access/field-access.test.js +229 -2
- package/dist/access/field-access.test.js.map +1 -1
- package/dist/access/field-transforms.d.ts +0 -27
- package/dist/access/field-transforms.d.ts.map +1 -1
- package/dist/access/field-visibility.d.ts +2 -5
- package/dist/access/field-visibility.d.ts.map +1 -1
- package/dist/access/field-visibility.js +89 -41
- package/dist/access/field-visibility.js.map +1 -1
- package/dist/access/index.d.ts +6 -3
- package/dist/access/index.d.ts.map +1 -1
- package/dist/access/index.js +12 -2
- package/dist/access/index.js.map +1 -1
- package/dist/access/query-validation.d.ts +121 -0
- package/dist/access/query-validation.d.ts.map +1 -0
- package/dist/access/query-validation.js +292 -0
- package/dist/access/query-validation.js.map +1 -0
- package/dist/access/relationship-count.d.ts +1 -1
- package/dist/access/relationship-count.d.ts.map +1 -1
- package/dist/access/relationship-count.js +2 -10
- package/dist/access/relationship-count.js.map +1 -1
- package/dist/access/relationship-label-filter.d.ts +23 -23
- package/dist/access/relationship-label-filter.d.ts.map +1 -1
- package/dist/access/relationship-label-filter.js +5 -76
- package/dist/access/relationship-label-filter.js.map +1 -1
- package/dist/access/relationship-label-filter.test.js +19 -56
- package/dist/access/relationship-label-filter.test.js.map +1 -1
- package/dist/access/transaction-registry.d.ts +45 -0
- package/dist/access/transaction-registry.d.ts.map +1 -0
- package/dist/access/transaction-registry.js +37 -0
- package/dist/access/transaction-registry.js.map +1 -0
- package/dist/access/types.d.ts +55 -59
- package/dist/access/types.d.ts.map +1 -1
- package/dist/config/index.d.ts +9 -7
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +10 -18
- package/dist/config/index.js.map +1 -1
- package/dist/config/label.d.ts +6 -13
- package/dist/config/label.d.ts.map +1 -1
- package/dist/config/label.js +6 -13
- package/dist/config/label.js.map +1 -1
- package/dist/config/nav-count.d.ts +11 -19
- package/dist/config/nav-count.d.ts.map +1 -1
- package/dist/config/nav-count.js +11 -19
- package/dist/config/nav-count.js.map +1 -1
- package/dist/config/plugin-engine.d.ts +0 -10
- package/dist/config/plugin-engine.d.ts.map +1 -1
- package/dist/config/plugin-engine.js +1 -37
- package/dist/config/plugin-engine.js.map +1 -1
- package/dist/config/types.d.ts +94 -109
- package/dist/config/types.d.ts.map +1 -1
- package/dist/context/apply-defaults.d.ts +8 -31
- package/dist/context/apply-defaults.d.ts.map +1 -1
- package/dist/context/apply-defaults.js +12 -41
- package/dist/context/apply-defaults.js.map +1 -1
- package/dist/context/hook-pipeline.d.ts +4 -29
- package/dist/context/hook-pipeline.d.ts.map +1 -1
- package/dist/context/hook-pipeline.js +8 -41
- package/dist/context/hook-pipeline.js.map +1 -1
- package/dist/context/index.d.ts +4 -15
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +223 -215
- package/dist/context/index.js.map +1 -1
- package/dist/context/nested-operations.d.ts +7 -26
- package/dist/context/nested-operations.d.ts.map +1 -1
- package/dist/context/nested-operations.js +73 -171
- package/dist/context/nested-operations.js.map +1 -1
- package/dist/context/transaction-boundary.d.ts +36 -47
- package/dist/context/transaction-boundary.d.ts.map +1 -1
- package/dist/context/transaction-boundary.js +92 -79
- package/dist/context/transaction-boundary.js.map +1 -1
- package/dist/context/write-pipeline.d.ts +25 -64
- package/dist/context/write-pipeline.d.ts.map +1 -1
- package/dist/context/write-pipeline.js +81 -111
- package/dist/context/write-pipeline.js.map +1 -1
- package/dist/fields/format-prisma-default.d.ts.map +1 -1
- package/dist/fields/format-prisma-default.js +4 -7
- package/dist/fields/format-prisma-default.js.map +1 -1
- package/dist/fields/index.d.ts +17 -2
- package/dist/fields/index.d.ts.map +1 -1
- package/dist/fields/index.js +136 -147
- package/dist/fields/index.js.map +1 -1
- package/dist/filter/collect.d.ts +26 -3
- package/dist/filter/collect.d.ts.map +1 -1
- package/dist/filter/collect.js +30 -12
- package/dist/filter/collect.js.map +1 -1
- package/dist/filter/filter.test.js +98 -15
- package/dist/filter/filter.test.js.map +1 -1
- package/dist/filter/index.d.ts +1 -0
- package/dist/filter/index.d.ts.map +1 -1
- package/dist/filter/index.js.map +1 -1
- package/dist/filter/map.d.ts.map +1 -1
- package/dist/filter/map.js +0 -5
- package/dist/filter/map.js.map +1 -1
- package/dist/filter/parse.d.ts.map +1 -1
- package/dist/filter/parse.js +2 -9
- package/dist/filter/parse.js.map +1 -1
- package/dist/filter/serialize.d.ts.map +1 -1
- package/dist/filter/serialize.js +2 -4
- package/dist/filter/serialize.js.map +1 -1
- package/dist/hooks/index.d.ts +4 -42
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +5 -59
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -4
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +1 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +4 -0
- package/dist/internal.js.map +1 -1
- package/dist/lib/case-utils.d.ts +0 -32
- package/dist/lib/case-utils.d.ts.map +1 -1
- package/dist/lib/case-utils.js +0 -32
- package/dist/lib/case-utils.js.map +1 -1
- package/dist/mcp/handler.d.ts +0 -4
- package/dist/mcp/handler.d.ts.map +1 -1
- package/dist/mcp/handler.js +12 -69
- package/dist/mcp/handler.js.map +1 -1
- package/dist/query/index.d.ts +55 -227
- package/dist/query/index.d.ts.map +1 -1
- package/dist/query/index.js +41 -117
- package/dist/query/index.js.map +1 -1
- package/dist/query/relationship-options.d.ts +1 -1
- package/dist/query/relationship-options.js +1 -1
- package/dist/utils/password.d.ts +0 -68
- package/dist/utils/password.d.ts.map +1 -1
- package/dist/utils/password.js +7 -76
- package/dist/utils/password.js.map +1 -1
- package/dist/validation/field-config.d.ts.map +1 -1
- package/dist/validation/field-config.js +0 -6
- package/dist/validation/field-config.js.map +1 -1
- package/dist/validation/schema.d.ts +0 -7
- package/dist/validation/schema.d.ts.map +1 -1
- package/dist/validation/schema.js +0 -10
- package/dist/validation/schema.js.map +1 -1
- package/package.json +1 -1
- package/src/access/access-filter.test.ts +205 -275
- package/src/access/access-filter.ts +236 -272
- package/src/access/declared-dependencies.test.ts +277 -0
- package/src/access/declared-dependencies.ts +117 -37
- package/src/access/depth-limits.ts +8 -7
- package/src/access/engine.ts +0 -25
- package/src/access/errors.ts +97 -12
- package/src/access/field-access.test.ts +312 -2
- package/src/access/field-access.ts +118 -42
- package/src/access/field-transforms.ts +8 -39
- package/src/access/field-visibility.ts +99 -45
- package/src/access/index.ts +17 -5
- package/src/access/query-validation.ts +359 -0
- package/src/access/relationship-count.ts +3 -11
- package/src/access/relationship-label-filter.test.ts +19 -68
- package/src/access/relationship-label-filter.ts +27 -104
- package/src/access/transaction-registry.ts +58 -0
- package/src/access/types.ts +83 -86
- package/src/config/index.ts +10 -22
- package/src/config/label.ts +6 -13
- package/src/config/nav-count.ts +11 -19
- package/src/config/plugin-engine.ts +1 -37
- package/src/config/types.ts +95 -110
- package/src/context/apply-defaults.ts +12 -44
- package/src/context/hook-pipeline.ts +12 -67
- package/src/context/index.ts +311 -276
- package/src/context/nested-operations.ts +94 -226
- package/src/context/transaction-boundary.ts +113 -109
- package/src/context/write-pipeline.ts +99 -155
- package/src/fields/format-prisma-default.ts +4 -7
- package/src/fields/index.ts +155 -147
- package/src/filter/collect.ts +48 -12
- package/src/filter/filter.test.ts +153 -15
- package/src/filter/index.ts +1 -0
- package/src/filter/map.ts +0 -5
- package/src/filter/parse.ts +2 -9
- package/src/filter/serialize.ts +2 -4
- package/src/hooks/index.ts +5 -59
- package/src/index.ts +23 -4
- package/src/internal.ts +5 -0
- package/src/lib/case-utils.ts +0 -32
- package/src/mcp/handler.ts +13 -71
- package/src/query/index.ts +82 -235
- package/src/query/relationship-options.ts +1 -1
- package/src/utils/password.ts +7 -76
- package/src/validation/field-config.ts +0 -6
- package/src/validation/schema.ts +0 -10
- package/tests/access-relationships.test.ts +18 -16
- package/tests/computed-field-selective-evaluation.test.ts +418 -0
- package/tests/context.test.ts +727 -1
- package/tests/field-types.test.ts +222 -0
- package/tests/mcp-handler.test.ts +34 -0
- package/tests/needs-declared-dependencies.test.ts +7 -4
- package/tests/resolve-chain.test.ts +11 -11
- package/tests/transaction-boundary-outermost.test.ts +530 -0
- package/tsconfig.tsbuildinfo +1 -1
package/dist/utils/password.d.ts
CHANGED
|
@@ -1,81 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hash a plain text password using bcrypt
|
|
3
|
-
*
|
|
4
|
-
* @param plainPassword - The plain text password to hash
|
|
5
|
-
* @param costFactor - The bcrypt cost factor (default: 10)
|
|
6
|
-
* @returns Promise resolving to the hashed password
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```typescript
|
|
10
|
-
* const hashed = await hashPassword('mypassword')
|
|
11
|
-
* // Returns: $2a$10$...
|
|
12
|
-
* ```
|
|
13
|
-
*/
|
|
14
1
|
export declare function hashPassword(plainPassword: string, costFactor?: number): Promise<string>;
|
|
15
|
-
/**
|
|
16
|
-
* Compare a plain text password with a hashed password
|
|
17
|
-
*
|
|
18
|
-
* @param plainPassword - The plain text password to compare
|
|
19
|
-
* @param hashedPassword - The hashed password to compare against
|
|
20
|
-
* @returns Promise resolving to true if passwords match, false otherwise
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```typescript
|
|
24
|
-
* const isValid = await comparePassword('mypassword', hashedPassword)
|
|
25
|
-
* if (isValid) {
|
|
26
|
-
* // Password is correct
|
|
27
|
-
* }
|
|
28
|
-
* ```
|
|
29
|
-
*/
|
|
30
2
|
export declare function comparePassword(plainPassword: string, hashedPassword: string): Promise<boolean>;
|
|
31
|
-
/**
|
|
32
|
-
* Check if a string appears to be a bcrypt hash
|
|
33
|
-
* Bcrypt hashes follow the format: $2a$10$...
|
|
34
|
-
*
|
|
35
|
-
* @param value - The string to check
|
|
36
|
-
* @returns True if the string looks like a bcrypt hash
|
|
37
|
-
*/
|
|
38
3
|
export declare function isHashedPassword(value: string): boolean;
|
|
39
|
-
/**
|
|
40
|
-
* HashedPassword class wraps a bcrypt hash and provides a compare method
|
|
41
|
-
* This allows password field values to be used as strings while also
|
|
42
|
-
* providing a convenient compare() method for authentication
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* ```typescript
|
|
46
|
-
* const user = await context.db.user.findUnique({ where: { id: '1' } })
|
|
47
|
-
* const isValid = await user.password.compare('plaintextPassword')
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
4
|
export declare class HashedPassword {
|
|
51
5
|
private readonly hash;
|
|
52
6
|
constructor(hash: string);
|
|
53
|
-
/**
|
|
54
|
-
* Compare a plain text password with this hashed password
|
|
55
|
-
*
|
|
56
|
-
* @param plainPassword - The plain text password to compare
|
|
57
|
-
* @returns Promise resolving to true if passwords match
|
|
58
|
-
*/
|
|
59
7
|
compare(plainPassword: string): Promise<boolean>;
|
|
60
|
-
/**
|
|
61
|
-
* Get the underlying hash string
|
|
62
|
-
* This allows the HashedPassword to be used anywhere a string is expected
|
|
63
|
-
*/
|
|
64
8
|
toString(): string;
|
|
65
|
-
/**
|
|
66
|
-
* Get the underlying hash when used in string contexts
|
|
67
|
-
* This allows the HashedPassword to be coerced to a string automatically
|
|
68
|
-
*/
|
|
69
9
|
[Symbol.toPrimitive](hint: string): string;
|
|
70
|
-
/**
|
|
71
|
-
* Return the hash for JSON serialization
|
|
72
|
-
* This ensures the hash is properly serialized when converting to JSON
|
|
73
|
-
*/
|
|
74
10
|
toJSON(): string;
|
|
75
|
-
/**
|
|
76
|
-
* Get the underlying hash value
|
|
77
|
-
* This allows accessing the raw hash string
|
|
78
|
-
*/
|
|
79
11
|
valueOf(): string;
|
|
80
12
|
}
|
|
81
13
|
//# sourceMappingURL=password.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/utils/password.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/utils/password.ts"],"names":[],"mappings":"AAKA,wBAAsB,YAAY,CAChC,aAAa,EAAE,MAAM,EACrB,UAAU,GAAE,MAA4B,GACvC,OAAO,CAAC,MAAM,CAAC,CAMjB;AAED,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIvD;AAID,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,MAAM,EAIxC;IAEK,OAAO,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAErD;IAED,QAAQ,IAAI,MAAM,CAEjB;IAGD,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzC;IAGD,MAAM,IAAI,MAAM,CAEf;IAED,OAAO,IAAI,MAAM,CAEhB;CACF"}
|
package/dist/utils/password.js
CHANGED
|
@@ -1,44 +1,12 @@
|
|
|
1
1
|
import bcrypt from 'bcryptjs';
|
|
2
|
-
|
|
3
|
-
* Default bcrypt cost factor (rounds)
|
|
4
|
-
* Higher values = more secure but slower
|
|
5
|
-
* 10 is a good balance for production use
|
|
6
|
-
*/
|
|
2
|
+
// Bcrypt cost factor: higher is slower but more resistant to brute force.
|
|
7
3
|
const DEFAULT_COST_FACTOR = 10;
|
|
8
|
-
/**
|
|
9
|
-
* Hash a plain text password using bcrypt
|
|
10
|
-
*
|
|
11
|
-
* @param plainPassword - The plain text password to hash
|
|
12
|
-
* @param costFactor - The bcrypt cost factor (default: 10)
|
|
13
|
-
* @returns Promise resolving to the hashed password
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```typescript
|
|
17
|
-
* const hashed = await hashPassword('mypassword')
|
|
18
|
-
* // Returns: $2a$10$...
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
4
|
export async function hashPassword(plainPassword, costFactor = DEFAULT_COST_FACTOR) {
|
|
22
5
|
if (typeof plainPassword !== 'string' || plainPassword.length === 0) {
|
|
23
6
|
throw new Error('Password must be a non-empty string');
|
|
24
7
|
}
|
|
25
8
|
return bcrypt.hash(plainPassword, costFactor);
|
|
26
9
|
}
|
|
27
|
-
/**
|
|
28
|
-
* Compare a plain text password with a hashed password
|
|
29
|
-
*
|
|
30
|
-
* @param plainPassword - The plain text password to compare
|
|
31
|
-
* @param hashedPassword - The hashed password to compare against
|
|
32
|
-
* @returns Promise resolving to true if passwords match, false otherwise
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```typescript
|
|
36
|
-
* const isValid = await comparePassword('mypassword', hashedPassword)
|
|
37
|
-
* if (isValid) {
|
|
38
|
-
* // Password is correct
|
|
39
|
-
* }
|
|
40
|
-
* ```
|
|
41
|
-
*/
|
|
42
10
|
export async function comparePassword(plainPassword, hashedPassword) {
|
|
43
11
|
if (typeof plainPassword !== 'string' || typeof hashedPassword !== 'string') {
|
|
44
12
|
return false;
|
|
@@ -50,36 +18,19 @@ export async function comparePassword(plainPassword, hashedPassword) {
|
|
|
50
18
|
return await bcrypt.compare(plainPassword, hashedPassword);
|
|
51
19
|
}
|
|
52
20
|
catch (error) {
|
|
53
|
-
//
|
|
21
|
+
// Fail closed on a malformed hash or other bcrypt error, rather than
|
|
22
|
+
// letting it propagate as an authentication-bypassing exception.
|
|
54
23
|
console.error('Password comparison failed:', error);
|
|
55
24
|
return false;
|
|
56
25
|
}
|
|
57
26
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Check if a string appears to be a bcrypt hash
|
|
60
|
-
* Bcrypt hashes follow the format: $2a$10$...
|
|
61
|
-
*
|
|
62
|
-
* @param value - The string to check
|
|
63
|
-
* @returns True if the string looks like a bcrypt hash
|
|
64
|
-
*/
|
|
65
27
|
export function isHashedPassword(value) {
|
|
66
28
|
if (typeof value !== 'string')
|
|
67
29
|
return false;
|
|
68
|
-
// Bcrypt hashes start with $2a$, $2b$, or $2y$ followed by cost factor
|
|
69
|
-
// and are typically 60 characters long
|
|
70
30
|
return /^\$2[aby]\$\d{2}\$.{53}$/.test(value);
|
|
71
31
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
* This allows password field values to be used as strings while also
|
|
75
|
-
* providing a convenient compare() method for authentication
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* ```typescript
|
|
79
|
-
* const user = await context.db.user.findUnique({ where: { id: '1' } })
|
|
80
|
-
* const isValid = await user.password.compare('plaintextPassword')
|
|
81
|
-
* ```
|
|
82
|
-
*/
|
|
32
|
+
// Wraps a bcrypt hash so a password field's value can still be used as a
|
|
33
|
+
// plain string while also exposing compare() for authentication.
|
|
83
34
|
export class HashedPassword {
|
|
84
35
|
hash;
|
|
85
36
|
constructor(hash) {
|
|
@@ -88,43 +39,23 @@ export class HashedPassword {
|
|
|
88
39
|
throw new Error('HashedPassword requires a non-empty hash string');
|
|
89
40
|
}
|
|
90
41
|
}
|
|
91
|
-
/**
|
|
92
|
-
* Compare a plain text password with this hashed password
|
|
93
|
-
*
|
|
94
|
-
* @param plainPassword - The plain text password to compare
|
|
95
|
-
* @returns Promise resolving to true if passwords match
|
|
96
|
-
*/
|
|
97
42
|
async compare(plainPassword) {
|
|
98
43
|
return comparePassword(plainPassword, this.hash);
|
|
99
44
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Get the underlying hash string
|
|
102
|
-
* This allows the HashedPassword to be used anywhere a string is expected
|
|
103
|
-
*/
|
|
104
45
|
toString() {
|
|
105
46
|
return this.hash;
|
|
106
47
|
}
|
|
107
|
-
|
|
108
|
-
* Get the underlying hash when used in string contexts
|
|
109
|
-
* This allows the HashedPassword to be coerced to a string automatically
|
|
110
|
-
*/
|
|
48
|
+
// Implicit coercion (template literals, string concatenation) resolves here.
|
|
111
49
|
[Symbol.toPrimitive](hint) {
|
|
112
50
|
if (hint === 'string' || hint === 'default') {
|
|
113
51
|
return this.hash;
|
|
114
52
|
}
|
|
115
53
|
return this.hash;
|
|
116
54
|
}
|
|
117
|
-
|
|
118
|
-
* Return the hash for JSON serialization
|
|
119
|
-
* This ensures the hash is properly serialized when converting to JSON
|
|
120
|
-
*/
|
|
55
|
+
// JSON.stringify calls this when present, so the hash serializes as a plain string.
|
|
121
56
|
toJSON() {
|
|
122
57
|
return this.hash;
|
|
123
58
|
}
|
|
124
|
-
/**
|
|
125
|
-
* Get the underlying hash value
|
|
126
|
-
* This allows accessing the raw hash string
|
|
127
|
-
*/
|
|
128
59
|
valueOf() {
|
|
129
60
|
return this.hash;
|
|
130
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/utils/password.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAA;AAE7B
|
|
1
|
+
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/utils/password.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,UAAU,CAAA;AAE7B,0EAA0E;AAC1E,MAAM,mBAAmB,GAAG,EAAE,CAAA;AAE9B,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,aAAqB,EACrB,UAAU,GAAW,mBAAmB;IAExC,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;IACxD,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,CAAA;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,aAAqB,EACrB,cAAsB;IAEtB,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,OAAO,cAAc,KAAK,QAAQ,EAAE,CAAC;QAC5E,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,cAAc,CAAC,CAAA;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,qEAAqE;QACrE,iEAAiE;QACjE,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAA;QACnD,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAE3C,OAAO,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAC/C,CAAC;AAED,yEAAyE;AACzE,iEAAiE;AACjE,MAAM,OAAO,cAAc;IACI,IAAI;IAAjC,YAA6B,IAAY;oBAAZ,IAAI;QAC/B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;QACpE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,aAAqB;QACjC,OAAO,eAAe,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;IAClD,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;IAED,6EAA6E;IAC7E,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAY;QAC/B,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC,IAAI,CAAA;QAClB,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;IAED,oFAAoF;IACpF,MAAM;QACJ,OAAO,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-config.d.ts","sourceRoot":"","sources":["../../src/validation/field-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAErE;;;;;;;;;GASG;AACH,MAAM,WAAW,0BAA0B;IACzC,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAA;IAChB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAA;IACjB,2CAA2C;IAC3C,aAAa,EAAE,eAAe,GAAG,mBAAmB,GAAG,cAAc,GAAG,mBAAmB,CAAA;IAC3F,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAA;CAChB;
|
|
1
|
+
{"version":3,"file":"field-config.d.ts","sourceRoot":"","sources":["../../src/validation/field-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAErE;;;;;;;;;GASG;AACH,MAAM,WAAW,0BAA0B;IACzC,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAA;IAChB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAA;IACjB,2CAA2C;IAC3C,aAAa,EAAE,eAAe,GAAG,mBAAmB,GAAG,cAAc,GAAG,mBAAmB,CAAA;IAC3F,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAA;CAChB;AAqCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,0BAA0B,EAAE,CAgC9B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,0BAA0B,EAAE,CAWzF"}
|
|
@@ -17,9 +17,6 @@ function hasFieldMethod(field, method) {
|
|
|
17
17
|
const value = Reflect.get(field, method);
|
|
18
18
|
return typeof value === 'function';
|
|
19
19
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Build the canonical error message for a missing contract method.
|
|
22
|
-
*/
|
|
23
20
|
function buildMessage(fieldType, method, fieldKey, listKey) {
|
|
24
21
|
const location = listKey ? `Field "${listKey}.${fieldKey}"` : `Field "${fieldKey}"`;
|
|
25
22
|
return (`${location} (type "${fieldType}") is not self-contained: it does not implement ` +
|
|
@@ -61,17 +58,14 @@ export function validateFieldConfig(field, fieldKey, listKey) {
|
|
|
61
58
|
}
|
|
62
59
|
};
|
|
63
60
|
if (field.type === 'relationship') {
|
|
64
|
-
// Relationships render through the relationship path only.
|
|
65
61
|
requireMethod('getPrismaRelation');
|
|
66
62
|
return errors;
|
|
67
63
|
}
|
|
68
64
|
if (field.virtual === true || field.type === 'virtual') {
|
|
69
|
-
// Virtual fields are not persisted, so getPrismaType is intentionally absent.
|
|
70
65
|
requireMethod('getTypeScriptType');
|
|
71
66
|
requireMethod('getZodSchema');
|
|
72
67
|
return errors;
|
|
73
68
|
}
|
|
74
|
-
// Stored scalar fields must implement the full generation contract.
|
|
75
69
|
requireMethod('getPrismaType');
|
|
76
70
|
requireMethod('getTypeScriptType');
|
|
77
71
|
requireMethod('getZodSchema');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-config.js","sourceRoot":"","sources":["../../src/validation/field-config.ts"],"names":[],"mappings":"AAyBA;;;GAGG;AACH,SAAS,iBAAiB,CAAC,KAAkB;IAC3C,OAAO,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AACzF,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,KAAkB,EAAE,MAAc;IACxD,MAAM,KAAK,GAAY,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACjD,OAAO,OAAO,KAAK,KAAK,UAAU,CAAA;AACpC,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"field-config.js","sourceRoot":"","sources":["../../src/validation/field-config.ts"],"names":[],"mappings":"AAyBA;;;GAGG;AACH,SAAS,iBAAiB,CAAC,KAAkB;IAC3C,OAAO,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AACzF,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,KAAkB,EAAE,MAAc;IACxD,MAAM,KAAK,GAAY,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACjD,OAAO,OAAO,KAAK,KAAK,UAAU,CAAA;AACpC,CAAC;AAED,SAAS,YAAY,CACnB,SAAiB,EACjB,MAAmD,EACnD,QAAgB,EAChB,OAAgB;IAEhB,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,OAAO,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,UAAU,QAAQ,GAAG,CAAA;IACnF,OAAO,CACL,GAAG,QAAQ,WAAW,SAAS,kDAAkD;QACjF,GAAG,MAAM,mEAAmE;QAC5E,8DAA8D,CAC/D,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAkB,EAClB,QAAgB,EAChB,OAAgB;IAEhB,MAAM,MAAM,GAAiC,EAAE,CAAA;IAC/C,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAA;IAE1C,MAAM,aAAa,GAAG,CAAC,MAAmD,EAAQ,EAAE;QAClF,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;YACnC,MAAM,CAAC,IAAI,CAAC;gBACV,OAAO;gBACP,QAAQ;gBACR,SAAS;gBACT,aAAa,EAAE,MAAM;gBACrB,OAAO,EAAE,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC;aAC5D,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAA;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QAClC,aAAa,CAAC,mBAAmB,CAAC,CAAA;QAClC,OAAO,MAAM,CAAA;IACf,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACvD,aAAa,CAAC,mBAAmB,CAAC,CAAA;QAClC,aAAa,CAAC,cAAc,CAAC,CAAA;QAC7B,OAAO,MAAM,CAAA;IACf,CAAC;IAED,aAAa,CAAC,eAAe,CAAC,CAAA;IAC9B,aAAa,CAAC,mBAAmB,CAAC,CAAA;IAClC,aAAa,CAAC,cAAc,CAAC,CAAA;IAE7B,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,MAAM,MAAM,GAAiC,EAAE,CAAA;IAE/C,KAAK,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACjE,IAAI,CAAC,UAAU,EAAE,MAAM;YAAE,SAAQ;QACjC,KAAK,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACxE,MAAM,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAA;QACrE,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import type { FieldConfig } from '../config/types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Generate Zod schema from field configurations
|
|
5
|
-
*/
|
|
6
3
|
export declare function generateZodSchema(fieldConfigs: Record<string, FieldConfig>, operation?: 'create' | 'update'): z.ZodObject;
|
|
7
|
-
/**
|
|
8
|
-
* Validate data against field configurations using Zod
|
|
9
|
-
* Returns structured errors by field
|
|
10
|
-
*/
|
|
11
4
|
export declare function validateWithZod(data: Record<string, unknown>, fieldConfigs: Record<string, FieldConfig>, operation?: 'create' | 'update'): {
|
|
12
5
|
success: true;
|
|
13
6
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/validation/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/validation/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACzC,SAAS,GAAE,QAAQ,GAAG,QAAmB,GACxC,CAAC,CAAC,SAAS,CAsBb;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACzC,SAAS,GAAE,QAAQ,GAAG,QAAmB,GACxC;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAgBxE"}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
/**
|
|
3
|
-
* Generate Zod schema from field configurations
|
|
4
|
-
*/
|
|
5
2
|
export function generateZodSchema(fieldConfigs, operation = 'create') {
|
|
6
3
|
const shape = {};
|
|
7
4
|
for (const [fieldName, fieldConfig] of Object.entries(fieldConfigs)) {
|
|
8
|
-
// Skip system fields, relationships, and virtual fields
|
|
9
5
|
// Virtual fields don't accept input - they only compute output
|
|
10
6
|
if (['id', 'createdAt', 'updatedAt'].includes(fieldName) ||
|
|
11
7
|
fieldConfig.type === 'relationship' ||
|
|
12
8
|
fieldConfig.virtual) {
|
|
13
9
|
continue;
|
|
14
10
|
}
|
|
15
|
-
// Use the field's schema generator
|
|
16
11
|
if (fieldConfig.getZodSchema) {
|
|
17
12
|
shape[fieldName] = fieldConfig.getZodSchema(fieldName, operation);
|
|
18
13
|
}
|
|
@@ -23,17 +18,12 @@ export function generateZodSchema(fieldConfigs, operation = 'create') {
|
|
|
23
18
|
}
|
|
24
19
|
return z.object(shape);
|
|
25
20
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Validate data against field configurations using Zod
|
|
28
|
-
* Returns structured errors by field
|
|
29
|
-
*/
|
|
30
21
|
export function validateWithZod(data, fieldConfigs, operation = 'create') {
|
|
31
22
|
const schema = generateZodSchema(fieldConfigs, operation);
|
|
32
23
|
const result = schema.safeParse(data);
|
|
33
24
|
if (result.success) {
|
|
34
25
|
return { success: true };
|
|
35
26
|
}
|
|
36
|
-
// Convert Zod errors to field-specific error messages
|
|
37
27
|
const errors = {};
|
|
38
28
|
for (const issue of result.error.issues) {
|
|
39
29
|
const fieldPath = issue.path.join('.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/validation/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/validation/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAGvB,MAAM,UAAU,iBAAiB,CAC/B,YAAyC,EACzC,SAAS,GAAwB,QAAQ;IAEzC,MAAM,KAAK,GAAiC,EAAE,CAAA;IAE9C,KAAK,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACpE,+DAA+D;QAC/D,IACE,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;YACpD,WAAW,CAAC,IAAI,KAAK,cAAc;YACnC,WAAW,CAAC,OAAO,EACnB,CAAC;YACD,SAAQ;QACV,CAAC;QAED,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC;YAC7B,KAAK,CAAC,SAAS,CAAC,GAAG,WAAW,CAAC,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QACnE,CAAC;aAAM,CAAC;YACN,4DAA4D;YAC5D,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAA;QACvC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AACxB,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,IAA6B,EAC7B,YAAyC,EACzC,SAAS,GAAwB,QAAQ;IAEzC,MAAM,MAAM,GAAG,iBAAiB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAA;IAEzD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;IAErC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC1B,CAAC;IAED,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACtC,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,OAAO,CAAA;IACnC,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAA;AACnC,CAAC"}
|