@mantiq/validation 0.1.3 → 0.2.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mantiq/validation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Rule engine, form requests",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,14 +40,15 @@
|
|
|
40
40
|
"LICENSE"
|
|
41
41
|
],
|
|
42
42
|
"scripts": {
|
|
43
|
-
"build": "bun build ./src/index.ts --outdir ./dist --target bun",
|
|
43
|
+
"build": "bun build ./src/index.ts --outdir ./dist --target bun --packages=external",
|
|
44
44
|
"test": "bun test",
|
|
45
45
|
"typecheck": "tsc --noEmit",
|
|
46
46
|
"clean": "rm -rf dist"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"bun-types": "latest",
|
|
50
|
-
"typescript": "^5.7.0"
|
|
50
|
+
"typescript": "^5.7.0",
|
|
51
|
+
"@mantiq/core": "workspace:*"
|
|
51
52
|
},
|
|
52
53
|
"peerDependencies": {
|
|
53
54
|
"@mantiq/core": "^0.1.0"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { PresenceVerifier } from './contracts/PresenceVerifier.ts'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Database-backed presence verifier for `exists` and `unique` validation rules.
|
|
5
|
+
* Uses the database connection's query builder to check for row existence.
|
|
6
|
+
*/
|
|
7
|
+
export class DatabasePresenceVerifier implements PresenceVerifier {
|
|
8
|
+
constructor(private readonly connection: any) {}
|
|
9
|
+
|
|
10
|
+
async getCount(
|
|
11
|
+
table: string,
|
|
12
|
+
column: string,
|
|
13
|
+
value: any,
|
|
14
|
+
excludeId?: string | number | null,
|
|
15
|
+
idColumn = 'id',
|
|
16
|
+
extra: [string, string, any][] = [],
|
|
17
|
+
): Promise<number> {
|
|
18
|
+
let query = this.connection.table(table).where(column, value)
|
|
19
|
+
|
|
20
|
+
if (excludeId !== undefined && excludeId !== null) {
|
|
21
|
+
query = query.where(idColumn, '!=', excludeId)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
for (const [col, op, val] of extra) {
|
|
25
|
+
query = query.where(col, op, val)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return query.count()
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async getMultiCount(
|
|
32
|
+
table: string,
|
|
33
|
+
column: string,
|
|
34
|
+
values: any[],
|
|
35
|
+
extra: [string, string, any][] = [],
|
|
36
|
+
): Promise<number> {
|
|
37
|
+
let query = this.connection.table(table).whereIn(column, values)
|
|
38
|
+
|
|
39
|
+
for (const [col, op, val] of extra) {
|
|
40
|
+
query = query.where(col, op, val)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return query.count()
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ServiceProvider } from '@mantiq/core'
|
|
2
2
|
import { Validator } from './Validator.ts'
|
|
3
|
+
import { DatabasePresenceVerifier } from './DatabasePresenceVerifier.ts'
|
|
4
|
+
import { setPresenceVerifier } from './helpers/validate.ts'
|
|
3
5
|
import type { Rule } from './contracts/Rule.ts'
|
|
4
6
|
import type { PresenceVerifier } from './contracts/PresenceVerifier.ts'
|
|
5
7
|
|
|
@@ -8,15 +10,11 @@ export const PRESENCE_VERIFIER = Symbol('PresenceVerifier')
|
|
|
8
10
|
/**
|
|
9
11
|
* Registers validation-related bindings in the container.
|
|
10
12
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* app.register(new ValidationServiceProvider(app))
|
|
14
|
-
*
|
|
15
|
-
* // To enable database rules (exists, unique), also bind a PresenceVerifier:
|
|
16
|
-
* app.singleton(PRESENCE_VERIFIER, () => new DatabasePresenceVerifier(db))
|
|
13
|
+
* Automatically wires up DatabasePresenceVerifier for `exists` and `unique`
|
|
14
|
+
* rules when @mantiq/database is available.
|
|
17
15
|
*/
|
|
18
16
|
export class ValidationServiceProvider extends ServiceProvider {
|
|
19
|
-
register(): void {
|
|
17
|
+
override register(): void {
|
|
20
18
|
// Bind a factory that creates pre-configured Validators
|
|
21
19
|
this.app.bind('validator', () => {
|
|
22
20
|
return (
|
|
@@ -26,15 +24,31 @@ export class ValidationServiceProvider extends ServiceProvider {
|
|
|
26
24
|
attributes?: Record<string, string>,
|
|
27
25
|
) => {
|
|
28
26
|
const validator = new Validator(data, rules, messages, attributes)
|
|
29
|
-
// Auto-attach presence verifier if one is bound
|
|
30
27
|
try {
|
|
31
28
|
const verifier = this.app.make<PresenceVerifier>(PRESENCE_VERIFIER)
|
|
32
29
|
validator.setPresenceVerifier(verifier)
|
|
33
30
|
} catch {
|
|
34
|
-
// No presence verifier bound
|
|
31
|
+
// No presence verifier bound
|
|
35
32
|
}
|
|
36
33
|
return validator
|
|
37
34
|
}
|
|
38
35
|
})
|
|
39
36
|
}
|
|
37
|
+
|
|
38
|
+
override async boot(): Promise<void> {
|
|
39
|
+
// Auto-wire DatabasePresenceVerifier using the default DB connection
|
|
40
|
+
try {
|
|
41
|
+
const { DatabaseManager } = await import('@mantiq/database')
|
|
42
|
+
const dbManager = this.app.make(DatabaseManager)
|
|
43
|
+
const verifier = new DatabasePresenceVerifier(dbManager.connection())
|
|
44
|
+
|
|
45
|
+
// Register in container for validator factory
|
|
46
|
+
this.app.singleton(PRESENCE_VERIFIER, () => verifier)
|
|
47
|
+
|
|
48
|
+
// Set globally for the validate() helper function
|
|
49
|
+
setPresenceVerifier(verifier)
|
|
50
|
+
} catch {
|
|
51
|
+
// @mantiq/database not installed — unique/exists rules unavailable
|
|
52
|
+
}
|
|
53
|
+
}
|
|
40
54
|
}
|
package/src/helpers/validate.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { Validator, type RuleDefinition } from '../Validator.ts'
|
|
2
|
+
import type { PresenceVerifier } from '../contracts/PresenceVerifier.ts'
|
|
3
|
+
|
|
4
|
+
/** Global presence verifier — set by ValidationServiceProvider. */
|
|
5
|
+
let _globalVerifier: PresenceVerifier | null = null
|
|
6
|
+
|
|
7
|
+
export function setPresenceVerifier(verifier: PresenceVerifier): void {
|
|
8
|
+
_globalVerifier = verifier
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function getPresenceVerifier(): PresenceVerifier | null {
|
|
12
|
+
return _globalVerifier
|
|
13
|
+
}
|
|
2
14
|
|
|
3
15
|
/**
|
|
4
16
|
* Validate data against rules. Returns validated data or throws ValidationError.
|
|
@@ -6,7 +18,7 @@ import { Validator, type RuleDefinition } from '../Validator.ts'
|
|
|
6
18
|
* @example
|
|
7
19
|
* const data = await validate(
|
|
8
20
|
* { name: 'Alice', email: 'alice@example.com' },
|
|
9
|
-
* { name: 'required|string|max:255', email: 'required|email' },
|
|
21
|
+
* { name: 'required|string|max:255', email: 'required|email|unique:users,email' },
|
|
10
22
|
* )
|
|
11
23
|
*/
|
|
12
24
|
export async function validate(
|
|
@@ -15,5 +27,9 @@ export async function validate(
|
|
|
15
27
|
messages?: Record<string, string>,
|
|
16
28
|
attributes?: Record<string, string>,
|
|
17
29
|
): Promise<Record<string, any>> {
|
|
18
|
-
|
|
30
|
+
const validator = new Validator(data, rules, messages, attributes)
|
|
31
|
+
if (_globalVerifier) {
|
|
32
|
+
validator.setPresenceVerifier(_globalVerifier)
|
|
33
|
+
}
|
|
34
|
+
return validator.validate()
|
|
19
35
|
}
|
package/src/index.ts
CHANGED
|
@@ -34,7 +34,10 @@ export {
|
|
|
34
34
|
} from './rules/builtin.ts'
|
|
35
35
|
|
|
36
36
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
37
|
-
export { validate } from './helpers/validate.ts'
|
|
37
|
+
export { validate, setPresenceVerifier, getPresenceVerifier } from './helpers/validate.ts'
|
|
38
|
+
|
|
39
|
+
// ── Presence Verifier ────────────────────────────────────────────────────────
|
|
40
|
+
export { DatabasePresenceVerifier } from './DatabasePresenceVerifier.ts'
|
|
38
41
|
|
|
39
42
|
// ── Service Provider ─────────────────────────────────────────────────────────
|
|
40
43
|
export { ValidationServiceProvider, PRESENCE_VERIFIER } from './ValidationServiceProvider.ts'
|