@gunubin/vorm-core 0.1.0 → 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/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # @gunubin/vorm-core
2
2
 
3
+ [![npm](https://img.shields.io/npm/v/@gunubin/vorm-core)](https://www.npmjs.com/package/@gunubin/vorm-core)
4
+
3
5
  VO-first form validation core — branded types, field schemas, and validation logic.
4
6
 
5
7
  Part of the [vorm](https://github.com/gunubin/vorm) monorepo.
package/dist/index.cjs CHANGED
@@ -21,14 +21,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  VOValidationError: () => VOValidationError,
24
- buildOutputValues: () => buildOutputValues,
25
- createField: () => createField,
26
- createFormSchema: () => createFormSchema,
27
24
  createRule: () => createRule,
28
25
  safeValidateAndCreate: () => safeValidateAndCreate,
26
+ toStandardSchema: () => toStandardSchema,
29
27
  validateAndCreate: () => validateAndCreate,
30
- validateField: () => validateField,
31
- validateForm: () => validateForm,
32
28
  vo: () => vo
33
29
  });
34
30
  module.exports = __toCommonJS(index_exports);
@@ -74,124 +70,6 @@ function createRule(code, validate) {
74
70
  }));
75
71
  }
76
72
 
77
- // src/create-field.ts
78
- function createField(voOrConfig, options) {
79
- if (voOrConfig && "create" in voOrConfig && typeof voOrConfig.create === "function") {
80
- let factory2 = function(config2 = {}) {
81
- return {
82
- vo: voDef,
83
- required: config2.required ?? false,
84
- messages: mergeMessages(definitionMessages2, config2.messages),
85
- rules: [...voDef.rules],
86
- parse: parse2,
87
- format: format2
88
- };
89
- };
90
- var factory = factory2;
91
- const voDef = voOrConfig;
92
- const definitionMessages2 = options?.messages;
93
- const parse2 = options?.parse;
94
- const format2 = options?.format;
95
- return factory2;
96
- }
97
- const config = voOrConfig ?? {};
98
- const definitionMessages = config.messages;
99
- const definitionRules = config.rules ?? [];
100
- const parse = config.parse;
101
- const format = config.format;
102
- function factory(factoryConfig = {}) {
103
- return {
104
- vo: null,
105
- required: factoryConfig.required ?? false,
106
- messages: mergeMessages(definitionMessages, factoryConfig.messages),
107
- rules: [...definitionRules],
108
- parse,
109
- format
110
- };
111
- }
112
- return factory;
113
- }
114
- function mergeMessages(definition, factory) {
115
- if (!definition && !factory) return {};
116
- if (!definition) return factory;
117
- if (!factory) return definition;
118
- if (typeof factory === "function") return factory;
119
- if (typeof definition === "function") return factory;
120
- return { ...definition, ...factory };
121
- }
122
-
123
- // src/create-form-schema.ts
124
- function createFormSchema(config) {
125
- return {
126
- fields: config.fields,
127
- messages: config.messages,
128
- resolver: config.resolver
129
- };
130
- }
131
-
132
- // src/resolve-message.ts
133
- var DEFAULT_MESSAGES = {
134
- REQUIRED: "This field is required"
135
- };
136
- function resolveMessage(code, ...messageSources) {
137
- for (const source of messageSources) {
138
- if (!source) continue;
139
- if (typeof source === "function") {
140
- const result = source({ code });
141
- if (result) return result;
142
- } else {
143
- const msg = source[code];
144
- if (msg) return msg;
145
- }
146
- }
147
- return DEFAULT_MESSAGES[code] ?? code;
148
- }
149
-
150
- // src/validate-field.ts
151
- function validateField(value, fieldSchema, formMessages) {
152
- if (fieldSchema.required) {
153
- if (value === void 0 || value === null || value === "") {
154
- const code = "REQUIRED";
155
- const message = resolveMessage(code, formMessages, fieldSchema.messages);
156
- return { code, message };
157
- }
158
- } else {
159
- if (value === void 0 || value === null || value === "") {
160
- return null;
161
- }
162
- }
163
- for (const rule of fieldSchema.rules) {
164
- if (!rule.validate(value)) {
165
- const message = resolveMessage(rule.code, formMessages, fieldSchema.messages);
166
- return { code: rule.code, message };
167
- }
168
- }
169
- return null;
170
- }
171
-
172
- // src/validate-form.ts
173
- function validateForm(values, schema) {
174
- const errors = {};
175
- for (const [name, fieldSchema] of Object.entries(schema.fields)) {
176
- const value = values[name];
177
- const formMessages = schema.messages?.[name];
178
- const error = validateField(value, fieldSchema, formMessages);
179
- if (error) {
180
- errors[name] = error;
181
- }
182
- }
183
- if (Object.keys(errors).length > 0) {
184
- return errors;
185
- }
186
- if (schema.resolver) {
187
- const resolverErrors = schema.resolver(values);
188
- if (resolverErrors) {
189
- return { ...errors, ...resolverErrors };
190
- }
191
- }
192
- return errors;
193
- }
194
-
195
73
  // src/validate-and-create.ts
196
74
  function validateAndCreate(value, rules, name) {
197
75
  for (const rule of rules) {
@@ -210,33 +88,34 @@ function safeValidateAndCreate(value, rules) {
210
88
  return { success: true, data: value };
211
89
  }
212
90
 
213
- // src/build-output-values.ts
214
- function buildOutputValues(values, fields) {
215
- const output = {};
216
- for (const [name, fieldSchema] of Object.entries(fields)) {
217
- let value = values[name];
218
- const isEmpty = value === void 0 || value === null || value === "";
219
- if (isEmpty) {
220
- output[name] = void 0;
221
- continue;
222
- }
223
- if (fieldSchema.vo) {
224
- value = fieldSchema.vo.create(value);
91
+ // src/standard-schema.ts
92
+ function toStandardSchema(voDef) {
93
+ return {
94
+ "~standard": {
95
+ version: 1,
96
+ vendor: "vorm",
97
+ validate(value) {
98
+ const issues = [];
99
+ for (const rule of voDef.rules) {
100
+ if (!rule.validate(value)) {
101
+ issues.push({ message: rule.code });
102
+ }
103
+ }
104
+ if (issues.length > 0) {
105
+ return { issues };
106
+ }
107
+ return { value };
108
+ },
109
+ types: void 0
225
110
  }
226
- output[name] = value;
227
- }
228
- return output;
111
+ };
229
112
  }
230
113
  // Annotate the CommonJS export names for ESM import in node:
231
114
  0 && (module.exports = {
232
115
  VOValidationError,
233
- buildOutputValues,
234
- createField,
235
- createFormSchema,
236
116
  createRule,
237
117
  safeValidateAndCreate,
118
+ toStandardSchema,
238
119
  validateAndCreate,
239
- validateField,
240
- validateForm,
241
120
  vo
242
121
  });
package/dist/index.d.cts CHANGED
@@ -23,46 +23,10 @@ type VODefinition<TInput, TBrand extends string, TCodes extends string = string>
23
23
  type Infer<D> = D extends VODefinition<infer T, infer B, any> ? Brand<T, B> : D extends {
24
24
  create: (input: any) => infer R;
25
25
  } ? R : never;
26
- type ErrorMessageMap<C extends string = string> = {
27
- [K in C]?: string;
28
- };
29
- type ErrorMessageFn<C extends string = string> = (error: {
30
- code: C;
31
- }) => string;
32
- type ErrorMessages<C extends string = string> = ErrorMessageMap<C> | ErrorMessageFn<C>;
33
26
  type VOLike<TInput, TOutput, TCodes extends string = string> = {
34
27
  rules: ValidationRule<TInput, TCodes>[];
35
28
  create: (input: TInput) => TOutput;
36
29
  };
37
- type FieldSchema<T, TOutput, TRequired extends boolean, TCodes extends string = string> = {
38
- vo: VOLike<T, TOutput, TCodes> | null;
39
- required: TRequired;
40
- messages: ErrorMessages<TCodes | (TRequired extends true ? 'REQUIRED' : never)>;
41
- rules: ValidationRule<T, TCodes>[];
42
- parse?: (raw: string) => T;
43
- format?: (value: T) => string;
44
- };
45
- type FieldError = {
46
- code: string;
47
- message: string;
48
- };
49
- type FormErrors = Record<string, FieldError>;
50
- type FormSchemaConfig<TFields extends Record<string, FieldSchema<any, any, boolean, any>>> = {
51
- fields: TFields;
52
- messages?: Record<string, ErrorMessages>;
53
- resolver?: (values: FormInputValues<TFields>) => FormErrors | null;
54
- };
55
- type FormSchema<TFields extends Record<string, FieldSchema<any, any, boolean, any>>> = {
56
- fields: TFields;
57
- messages?: Record<string, ErrorMessages>;
58
- resolver?: (values: FormInputValues<TFields>) => FormErrors | null;
59
- };
60
- type FormInputValues<TFields extends Record<string, FieldSchema<any, any, boolean, any>>> = {
61
- [K in keyof TFields]: TFields[K] extends FieldSchema<infer TInput, any, infer TRequired, any> ? TRequired extends true ? TInput : TInput | undefined : never;
62
- };
63
- type FormOutputValues<TFields extends Record<string, FieldSchema<any, any, boolean, any>>> = {
64
- [K in keyof TFields]: TFields[K] extends FieldSchema<any, infer TOutput, infer TRequired, any> ? TRequired extends true ? TOutput : TOutput | undefined : never;
65
- };
66
30
 
67
31
  declare class VOValidationError extends Error {
68
32
  readonly brand: string;
@@ -75,34 +39,6 @@ declare function vo<B extends string, T = string, C extends string = string>(bra
75
39
  type RuleCreator<T, O, C extends string = string> = O extends void ? () => ValidationRule<T, C> : (option: O) => ValidationRule<T, C>;
76
40
  declare function createRule<T, O = void, C extends string = string>(code: C, validate: (value: T, option: O) => boolean): RuleCreator<T, O, C>;
77
41
 
78
- type FieldFactory<TInput, TOutput, TCodes extends string> = {
79
- (config: {
80
- required: true;
81
- messages?: ErrorMessages<TCodes | 'REQUIRED'>;
82
- }): FieldSchema<TInput, TOutput, true, TCodes>;
83
- (config?: {
84
- required?: false;
85
- messages?: ErrorMessages<TCodes>;
86
- }): FieldSchema<TInput, TOutput, false, TCodes>;
87
- };
88
- declare function createField<TInput, TOutput, TCodes extends string>(vo: VOLike<TInput, TOutput, TCodes>, options?: {
89
- messages?: ErrorMessages<TCodes>;
90
- parse?: (raw: string) => TInput;
91
- format?: (value: TInput) => string;
92
- }): FieldFactory<TInput, TOutput, TCodes>;
93
- declare function createField<T, TOut = T, TCodes extends string = string>(config?: {
94
- rules?: ValidationRule<T, TCodes>[];
95
- messages?: ErrorMessages<TCodes>;
96
- parse?: (raw: string) => T;
97
- format?: (value: T) => string;
98
- }): FieldFactory<T, TOut, TCodes>;
99
-
100
- declare function createFormSchema<TFields extends Record<string, FieldSchema<any, any, boolean, any>>>(config: FormSchemaConfig<TFields>): FormSchema<TFields>;
101
-
102
- declare function validateField<T>(value: T | undefined | null, fieldSchema: FieldSchema<T, any, boolean, any>, formMessages?: ErrorMessages): FieldError | null;
103
-
104
- declare function validateForm<TFields extends Record<string, FieldSchema<any, any, boolean, any>>>(values: FormInputValues<TFields>, schema: FormSchema<TFields>): FormErrors;
105
-
106
42
  declare function validateAndCreate<T>(value: T, rules: readonly {
107
43
  code: string;
108
44
  validate: (value: T) => boolean;
@@ -112,6 +48,41 @@ declare function safeValidateAndCreate<T>(value: T, rules: readonly {
112
48
  validate: (value: T) => boolean;
113
49
  }[]): CreateResult<T>;
114
50
 
115
- declare function buildOutputValues(values: Record<string, unknown>, fields: Record<string, FieldSchema<any, any, boolean, any>>): Record<string, unknown>;
51
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
52
+ readonly '~standard': StandardSchemaV1.Props<Input, Output>;
53
+ }
54
+ declare namespace StandardSchemaV1 {
55
+ interface Props<Input = unknown, Output = Input> {
56
+ readonly version: 1;
57
+ readonly vendor: string;
58
+ readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
59
+ readonly types?: Types<Input, Output> | undefined;
60
+ }
61
+ type Result<Output> = SuccessResult<Output> | FailureResult;
62
+ interface SuccessResult<Output> {
63
+ readonly value: Output;
64
+ readonly issues?: undefined;
65
+ }
66
+ interface FailureResult {
67
+ readonly issues: ReadonlyArray<Issue>;
68
+ }
69
+ interface Issue {
70
+ readonly message: string;
71
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
72
+ }
73
+ interface PathSegment {
74
+ readonly key: PropertyKey;
75
+ }
76
+ interface Types<Input = unknown, Output = Input> {
77
+ readonly input?: Input;
78
+ readonly output?: Output;
79
+ }
80
+ type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
81
+ type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
82
+ }
83
+ /**
84
+ * Wraps a VODefinition as a Standard Schema v1 compliant object.
85
+ */
86
+ declare function toStandardSchema<TInput, TBrand extends string, TCodes extends string>(voDef: VODefinition<TInput, TBrand, TCodes>): StandardSchemaV1<TInput, Brand<TInput, TBrand>>;
116
87
 
117
- export { type Brand, type CreateResult, type ErrorMessageFn, type ErrorMessageMap, type ErrorMessages, type FieldError, type FieldSchema, type FormErrors, type FormInputValues, type FormOutputValues, type FormSchema, type Infer, type VODefinition, type VOLike, VOValidationError, type ValidationRule, buildOutputValues, createField, createFormSchema, createRule, safeValidateAndCreate, validateAndCreate, validateField, validateForm, vo };
88
+ export { type Brand, type CreateResult, type Infer, StandardSchemaV1, type VODefinition, type VOLike, VOValidationError, type ValidationRule, createRule, safeValidateAndCreate, toStandardSchema, validateAndCreate, vo };
package/dist/index.d.ts CHANGED
@@ -23,46 +23,10 @@ type VODefinition<TInput, TBrand extends string, TCodes extends string = string>
23
23
  type Infer<D> = D extends VODefinition<infer T, infer B, any> ? Brand<T, B> : D extends {
24
24
  create: (input: any) => infer R;
25
25
  } ? R : never;
26
- type ErrorMessageMap<C extends string = string> = {
27
- [K in C]?: string;
28
- };
29
- type ErrorMessageFn<C extends string = string> = (error: {
30
- code: C;
31
- }) => string;
32
- type ErrorMessages<C extends string = string> = ErrorMessageMap<C> | ErrorMessageFn<C>;
33
26
  type VOLike<TInput, TOutput, TCodes extends string = string> = {
34
27
  rules: ValidationRule<TInput, TCodes>[];
35
28
  create: (input: TInput) => TOutput;
36
29
  };
37
- type FieldSchema<T, TOutput, TRequired extends boolean, TCodes extends string = string> = {
38
- vo: VOLike<T, TOutput, TCodes> | null;
39
- required: TRequired;
40
- messages: ErrorMessages<TCodes | (TRequired extends true ? 'REQUIRED' : never)>;
41
- rules: ValidationRule<T, TCodes>[];
42
- parse?: (raw: string) => T;
43
- format?: (value: T) => string;
44
- };
45
- type FieldError = {
46
- code: string;
47
- message: string;
48
- };
49
- type FormErrors = Record<string, FieldError>;
50
- type FormSchemaConfig<TFields extends Record<string, FieldSchema<any, any, boolean, any>>> = {
51
- fields: TFields;
52
- messages?: Record<string, ErrorMessages>;
53
- resolver?: (values: FormInputValues<TFields>) => FormErrors | null;
54
- };
55
- type FormSchema<TFields extends Record<string, FieldSchema<any, any, boolean, any>>> = {
56
- fields: TFields;
57
- messages?: Record<string, ErrorMessages>;
58
- resolver?: (values: FormInputValues<TFields>) => FormErrors | null;
59
- };
60
- type FormInputValues<TFields extends Record<string, FieldSchema<any, any, boolean, any>>> = {
61
- [K in keyof TFields]: TFields[K] extends FieldSchema<infer TInput, any, infer TRequired, any> ? TRequired extends true ? TInput : TInput | undefined : never;
62
- };
63
- type FormOutputValues<TFields extends Record<string, FieldSchema<any, any, boolean, any>>> = {
64
- [K in keyof TFields]: TFields[K] extends FieldSchema<any, infer TOutput, infer TRequired, any> ? TRequired extends true ? TOutput : TOutput | undefined : never;
65
- };
66
30
 
67
31
  declare class VOValidationError extends Error {
68
32
  readonly brand: string;
@@ -75,34 +39,6 @@ declare function vo<B extends string, T = string, C extends string = string>(bra
75
39
  type RuleCreator<T, O, C extends string = string> = O extends void ? () => ValidationRule<T, C> : (option: O) => ValidationRule<T, C>;
76
40
  declare function createRule<T, O = void, C extends string = string>(code: C, validate: (value: T, option: O) => boolean): RuleCreator<T, O, C>;
77
41
 
78
- type FieldFactory<TInput, TOutput, TCodes extends string> = {
79
- (config: {
80
- required: true;
81
- messages?: ErrorMessages<TCodes | 'REQUIRED'>;
82
- }): FieldSchema<TInput, TOutput, true, TCodes>;
83
- (config?: {
84
- required?: false;
85
- messages?: ErrorMessages<TCodes>;
86
- }): FieldSchema<TInput, TOutput, false, TCodes>;
87
- };
88
- declare function createField<TInput, TOutput, TCodes extends string>(vo: VOLike<TInput, TOutput, TCodes>, options?: {
89
- messages?: ErrorMessages<TCodes>;
90
- parse?: (raw: string) => TInput;
91
- format?: (value: TInput) => string;
92
- }): FieldFactory<TInput, TOutput, TCodes>;
93
- declare function createField<T, TOut = T, TCodes extends string = string>(config?: {
94
- rules?: ValidationRule<T, TCodes>[];
95
- messages?: ErrorMessages<TCodes>;
96
- parse?: (raw: string) => T;
97
- format?: (value: T) => string;
98
- }): FieldFactory<T, TOut, TCodes>;
99
-
100
- declare function createFormSchema<TFields extends Record<string, FieldSchema<any, any, boolean, any>>>(config: FormSchemaConfig<TFields>): FormSchema<TFields>;
101
-
102
- declare function validateField<T>(value: T | undefined | null, fieldSchema: FieldSchema<T, any, boolean, any>, formMessages?: ErrorMessages): FieldError | null;
103
-
104
- declare function validateForm<TFields extends Record<string, FieldSchema<any, any, boolean, any>>>(values: FormInputValues<TFields>, schema: FormSchema<TFields>): FormErrors;
105
-
106
42
  declare function validateAndCreate<T>(value: T, rules: readonly {
107
43
  code: string;
108
44
  validate: (value: T) => boolean;
@@ -112,6 +48,41 @@ declare function safeValidateAndCreate<T>(value: T, rules: readonly {
112
48
  validate: (value: T) => boolean;
113
49
  }[]): CreateResult<T>;
114
50
 
115
- declare function buildOutputValues(values: Record<string, unknown>, fields: Record<string, FieldSchema<any, any, boolean, any>>): Record<string, unknown>;
51
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
52
+ readonly '~standard': StandardSchemaV1.Props<Input, Output>;
53
+ }
54
+ declare namespace StandardSchemaV1 {
55
+ interface Props<Input = unknown, Output = Input> {
56
+ readonly version: 1;
57
+ readonly vendor: string;
58
+ readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
59
+ readonly types?: Types<Input, Output> | undefined;
60
+ }
61
+ type Result<Output> = SuccessResult<Output> | FailureResult;
62
+ interface SuccessResult<Output> {
63
+ readonly value: Output;
64
+ readonly issues?: undefined;
65
+ }
66
+ interface FailureResult {
67
+ readonly issues: ReadonlyArray<Issue>;
68
+ }
69
+ interface Issue {
70
+ readonly message: string;
71
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
72
+ }
73
+ interface PathSegment {
74
+ readonly key: PropertyKey;
75
+ }
76
+ interface Types<Input = unknown, Output = Input> {
77
+ readonly input?: Input;
78
+ readonly output?: Output;
79
+ }
80
+ type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input'];
81
+ type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output'];
82
+ }
83
+ /**
84
+ * Wraps a VODefinition as a Standard Schema v1 compliant object.
85
+ */
86
+ declare function toStandardSchema<TInput, TBrand extends string, TCodes extends string>(voDef: VODefinition<TInput, TBrand, TCodes>): StandardSchemaV1<TInput, Brand<TInput, TBrand>>;
116
87
 
117
- export { type Brand, type CreateResult, type ErrorMessageFn, type ErrorMessageMap, type ErrorMessages, type FieldError, type FieldSchema, type FormErrors, type FormInputValues, type FormOutputValues, type FormSchema, type Infer, type VODefinition, type VOLike, VOValidationError, type ValidationRule, buildOutputValues, createField, createFormSchema, createRule, safeValidateAndCreate, validateAndCreate, validateField, validateForm, vo };
88
+ export { type Brand, type CreateResult, type Infer, StandardSchemaV1, type VODefinition, type VOLike, VOValidationError, type ValidationRule, createRule, safeValidateAndCreate, toStandardSchema, validateAndCreate, vo };
package/dist/index.js CHANGED
@@ -39,124 +39,6 @@ function createRule(code, validate) {
39
39
  }));
40
40
  }
41
41
 
42
- // src/create-field.ts
43
- function createField(voOrConfig, options) {
44
- if (voOrConfig && "create" in voOrConfig && typeof voOrConfig.create === "function") {
45
- let factory2 = function(config2 = {}) {
46
- return {
47
- vo: voDef,
48
- required: config2.required ?? false,
49
- messages: mergeMessages(definitionMessages2, config2.messages),
50
- rules: [...voDef.rules],
51
- parse: parse2,
52
- format: format2
53
- };
54
- };
55
- var factory = factory2;
56
- const voDef = voOrConfig;
57
- const definitionMessages2 = options?.messages;
58
- const parse2 = options?.parse;
59
- const format2 = options?.format;
60
- return factory2;
61
- }
62
- const config = voOrConfig ?? {};
63
- const definitionMessages = config.messages;
64
- const definitionRules = config.rules ?? [];
65
- const parse = config.parse;
66
- const format = config.format;
67
- function factory(factoryConfig = {}) {
68
- return {
69
- vo: null,
70
- required: factoryConfig.required ?? false,
71
- messages: mergeMessages(definitionMessages, factoryConfig.messages),
72
- rules: [...definitionRules],
73
- parse,
74
- format
75
- };
76
- }
77
- return factory;
78
- }
79
- function mergeMessages(definition, factory) {
80
- if (!definition && !factory) return {};
81
- if (!definition) return factory;
82
- if (!factory) return definition;
83
- if (typeof factory === "function") return factory;
84
- if (typeof definition === "function") return factory;
85
- return { ...definition, ...factory };
86
- }
87
-
88
- // src/create-form-schema.ts
89
- function createFormSchema(config) {
90
- return {
91
- fields: config.fields,
92
- messages: config.messages,
93
- resolver: config.resolver
94
- };
95
- }
96
-
97
- // src/resolve-message.ts
98
- var DEFAULT_MESSAGES = {
99
- REQUIRED: "This field is required"
100
- };
101
- function resolveMessage(code, ...messageSources) {
102
- for (const source of messageSources) {
103
- if (!source) continue;
104
- if (typeof source === "function") {
105
- const result = source({ code });
106
- if (result) return result;
107
- } else {
108
- const msg = source[code];
109
- if (msg) return msg;
110
- }
111
- }
112
- return DEFAULT_MESSAGES[code] ?? code;
113
- }
114
-
115
- // src/validate-field.ts
116
- function validateField(value, fieldSchema, formMessages) {
117
- if (fieldSchema.required) {
118
- if (value === void 0 || value === null || value === "") {
119
- const code = "REQUIRED";
120
- const message = resolveMessage(code, formMessages, fieldSchema.messages);
121
- return { code, message };
122
- }
123
- } else {
124
- if (value === void 0 || value === null || value === "") {
125
- return null;
126
- }
127
- }
128
- for (const rule of fieldSchema.rules) {
129
- if (!rule.validate(value)) {
130
- const message = resolveMessage(rule.code, formMessages, fieldSchema.messages);
131
- return { code: rule.code, message };
132
- }
133
- }
134
- return null;
135
- }
136
-
137
- // src/validate-form.ts
138
- function validateForm(values, schema) {
139
- const errors = {};
140
- for (const [name, fieldSchema] of Object.entries(schema.fields)) {
141
- const value = values[name];
142
- const formMessages = schema.messages?.[name];
143
- const error = validateField(value, fieldSchema, formMessages);
144
- if (error) {
145
- errors[name] = error;
146
- }
147
- }
148
- if (Object.keys(errors).length > 0) {
149
- return errors;
150
- }
151
- if (schema.resolver) {
152
- const resolverErrors = schema.resolver(values);
153
- if (resolverErrors) {
154
- return { ...errors, ...resolverErrors };
155
- }
156
- }
157
- return errors;
158
- }
159
-
160
42
  // src/validate-and-create.ts
161
43
  function validateAndCreate(value, rules, name) {
162
44
  for (const rule of rules) {
@@ -175,32 +57,33 @@ function safeValidateAndCreate(value, rules) {
175
57
  return { success: true, data: value };
176
58
  }
177
59
 
178
- // src/build-output-values.ts
179
- function buildOutputValues(values, fields) {
180
- const output = {};
181
- for (const [name, fieldSchema] of Object.entries(fields)) {
182
- let value = values[name];
183
- const isEmpty = value === void 0 || value === null || value === "";
184
- if (isEmpty) {
185
- output[name] = void 0;
186
- continue;
187
- }
188
- if (fieldSchema.vo) {
189
- value = fieldSchema.vo.create(value);
60
+ // src/standard-schema.ts
61
+ function toStandardSchema(voDef) {
62
+ return {
63
+ "~standard": {
64
+ version: 1,
65
+ vendor: "vorm",
66
+ validate(value) {
67
+ const issues = [];
68
+ for (const rule of voDef.rules) {
69
+ if (!rule.validate(value)) {
70
+ issues.push({ message: rule.code });
71
+ }
72
+ }
73
+ if (issues.length > 0) {
74
+ return { issues };
75
+ }
76
+ return { value };
77
+ },
78
+ types: void 0
190
79
  }
191
- output[name] = value;
192
- }
193
- return output;
80
+ };
194
81
  }
195
82
  export {
196
83
  VOValidationError,
197
- buildOutputValues,
198
- createField,
199
- createFormSchema,
200
84
  createRule,
201
85
  safeValidateAndCreate,
86
+ toStandardSchema,
202
87
  validateAndCreate,
203
- validateField,
204
- validateForm,
205
88
  vo
206
89
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gunubin/vorm-core",
3
- "version": "0.1.0",
4
- "description": "VO-first form validation core branded types, field schemas, and validation logic",
3
+ "version": "0.2.0",
4
+ "description": "Branded value object definitions with type-safe validation rules",
5
5
  "keywords": [
6
6
  "form",
7
7
  "validation",