Skip to content

Commit 1b50016

Browse files
committed
chore: wip
1 parent 0d99954 commit 1b50016

File tree

7 files changed

+139
-27
lines changed

7 files changed

+139
-27
lines changed

.stacks/core/error-handling/src/index.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { fs } from '@stacksjs/storage'
22
import { log } from '@stacksjs/cli'
33
import { logsPath } from '@stacksjs/path'
4-
import { ValidationError } from '@stacksjs/types'
5-
import type { StacksError } from '@stacksjs/types'
4+
5+
import type { StacksError, ValidationError } from '@stacksjs/types'
66

77
export {
88
Err,
@@ -33,7 +33,7 @@ class ErrorHandler {
3333
static writeErrorToFile(err: StacksError) {
3434
let formattedError: string
3535

36-
if (err instanceof ValidationError)
36+
if (isErrorOfTypeValidation(err))
3737
formattedError = `[${new Date().toISOString()}] ${err.name}: ${err.messages}\n`
3838
else
3939
formattedError = `[${new Date().toISOString()}] ${err.name}: ${err.message}\n`
@@ -49,6 +49,10 @@ class ErrorHandler {
4949
}
5050
}
5151

52+
function isErrorOfTypeValidation(err: any): err is ValidationError {
53+
return err && typeof err.message === 'string'
54+
}
55+
5256
export function handleError(err: StacksError, options?: any): void {
5357
ErrorHandler.handle(err, options)
5458
}

.stacks/core/types/build.config.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,26 @@ const devEntries: Entries = [{
77
input: './src/',
88
outDir: './dist/',
99
}]
10-
const buildEntries = devEntries
10+
const buildEntries = [{
11+
input: './src/index',
12+
outDir: './dist/',
13+
}]
1114
const command = process.env.npm_lifecycle_script
1215
const entries: Entries = command?.includes('--stub') ? devEntries : buildEntries
1316

17+
// eslint-disable-next-line no-console
18+
console.log('entries', entries)
19+
1420
export default defineBuildConfig({
1521
alias,
1622

1723
entries,
1824

19-
// externals: [
20-
// '@vinejs/vine',
21-
// ],
22-
//
25+
externals: [
26+
// '@vinejs/vine',
27+
'@stacksjs/utils',
28+
],
29+
2330
rollup: {
2431
inlineDependencies: true,
2532
},

.stacks/core/types/src/errors.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
import {
2+
Err,
3+
Ok,
4+
Result,
5+
ResultAsync,
6+
} from 'neverthrow'
7+
18
export declare class ValidationError extends Error {
29
messages: any
310
status: number
@@ -14,4 +21,4 @@ export {
1421
Ok,
1522
Result,
1623
ResultAsync,
17-
} from 'neverthrow'
24+
}

.stacks/core/validation/build.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ export default defineBuildConfig({
99

1010
externals: [
1111
'@vinejs/vine',
12-
'@vinejs/vine/build/src/types',
1312
'vite',
1413
'validator',
1514
'@stacksjs/path',

.stacks/core/validation/src/rules.ts

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,100 @@
1-
import type { FieldContext } from '@vinejs/vine/build/src/types'
21
import { USD, currency } from '@stacksjs/utils'
32
import { validator } from './validate'
43

4+
/**
5+
* Thanks to VineJS for the following types:
6+
*
7+
* The context shared with the entire validation pipeline.
8+
* Each field gets its own context object.
9+
*/
10+
export interface FieldContext {
11+
/**
12+
* Field value
13+
*/
14+
value: unknown
15+
16+
/**
17+
* The data property is the top-level object under validation.
18+
*/
19+
data: any
20+
21+
/**
22+
* Shared metadata across the entire validation lifecycle. It can be
23+
* used to pass data between validation rules
24+
*/
25+
meta: Record<string, any>
26+
27+
/**
28+
* Mutate the value of field under validation.
29+
*/
30+
mutate(newValue: any, field: FieldContext): void
31+
32+
/**
33+
* Report error to the error reporter
34+
*/
35+
report: ErrorReporterContract['report']
36+
37+
/**
38+
* Is this field valid. Default: true
39+
*/
40+
isValid: boolean
41+
42+
/**
43+
* Is this field has value defined.
44+
*/
45+
isDefined: boolean
46+
47+
/**
48+
* Wildcard path for the field. The value is a nested
49+
* pointer to the field under validation.
50+
*
51+
* In case of arrays, the `*` wildcard is used.
52+
*/
53+
wildCardPath: string
54+
55+
/**
56+
* The parent property is the parent of the field. It could be an
57+
* array or an object.
58+
*/
59+
parent: any
60+
61+
/**
62+
* Name of the field under validation. In case of an array, the field
63+
* name will be a number
64+
*/
65+
name: string | number
66+
67+
/**
68+
* Is this field an array member
69+
*/
70+
isArrayMember: boolean
71+
}
72+
73+
/**
74+
* Thanks to VineJS for the following types:
75+
*
76+
* The error reporter is used to report errors during the validation
77+
* process.
78+
*/
79+
export interface ErrorReporterContract {
80+
/**
81+
* A boolean to known if there are one or more
82+
* errors.
83+
*/
84+
hasErrors: boolean
85+
86+
/**
87+
* Creates an instance of an exception to throw
88+
*/
89+
createError(): Error
90+
91+
/**
92+
* Report error for a field
93+
*/
94+
report(message: string, rule: string, field: FieldContext, args?: Record<string, any>): any
95+
}
96+
97+
// export const isMoney = validator.createRule((value: unknown, _, field: FieldContext) => {
598
export const isMoney = validator.createRule((value: unknown, _, field: FieldContext) => {
699
/**
7100
* Convert string representation of a number to a JavaScript
@@ -30,4 +123,4 @@ export const isMoney = validator.createRule((value: unknown, _, field: FieldCont
30123
* Mutate the field's value
31124
*/
32125
field.mutate(amount, field)
33-
})
126+
}) as any
Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1+
import type { VineString as ValidationString } from '@vinejs/vine'
12
import validator, { Vine as Validator } from '@vinejs/vine'
23
import { MoneyValidator } from './types/money'
34

45
Validator.macro('money', () => {
56
return new MoneyValidator()
67
})
78

8-
const validate = validator.validate
9-
const string = validator.string
10-
const number = validator.number
11-
const boolean = validator.boolean
12-
const array = validator.array
13-
const object = validator.object
14-
const any = validator.any
15-
const email = () => validator.string().email()
9+
const validate: Validator['validate'] = () => validator.validate()
1610

17-
export { validate, validator, Validator, string, number, boolean, array, object, any, email }
11+
const string: ValidationString = validator.string()
12+
const number: Validator['number'] = validator.number
13+
const boolean: Validator['boolean'] = validator.boolean
14+
const array: Validator['array'] = validator.array
15+
const object: Validator['object'] = validator.object
16+
const any: Validator['any'] = validator.any
17+
// const email = () => validator.string().email()
18+
19+
export { validate, validator, Validator, string, number, boolean, array, object, any }

app/models/User.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { faker } from 'stacks/core/faker/src'
2-
import { email, string } from 'stacks/core/validation/src'
3-
import { defineModel } from 'stacks/core/utils/src'
1+
import { faker } from '@stacksjs/faker'
2+
import { string } from '@stacksjs/validation'
3+
import { defineModel } from '@stacksjs/utils'
44

55
export default defineModel({
66
name: 'User', // defaults to the sanitized file name
@@ -13,22 +13,22 @@ export default defineModel({
1313
fields: {
1414
name: {
1515
validator: {
16-
rule: string().minLength(3).maxLength(255),
16+
rule: string.minLength(3).maxLength(255).nullable(),
1717
message: 'Name must be between 3 and 255 characters',
1818
},
1919
factory: () => faker.person.fullName(),
2020
},
2121
email: {
2222
unique: true,
2323
validator: {
24-
rule: email(),
24+
rule: string.email(),
2525
message: 'Email must be a valid email address',
2626
},
2727
factory: () => faker.internet.email(),
2828
},
2929
password: {
3030
validator: {
31-
rule: string().minLength(6).maxLength(255),
31+
rule: string.minLength(6).maxLength(255),
3232
message: 'Password must be between 6 and 255 characters',
3333
},
3434
factory: () => faker.internet.password(),

0 commit comments

Comments
 (0)