adria-forms
Advanced tools
Comparing version 0.2.3 to 0.2.4
declare type MaybePromise<T> = T | Promise<T>; | ||
declare type FormDataMap<T> = Map<T, any | null>; | ||
declare type FormDataMap<T = any> = Map<T, any | null>; | ||
declare type Validate<T> = (value: any | null, form: FormDataMap<T>) => MaybePromise<any | void>; | ||
@@ -7,3 +7,3 @@ declare type Not<T, A> = T extends A ? never : T; | ||
declare type ErrorRecord<F extends FieldRecord<string> | FieldRecord<never>> = { | ||
[FieldName in keyof F]: Awaited<ReturnType<F[FieldName]>> | (string & Record<never, never>); | ||
[FieldName in keyof F]: Awaited<ReturnType<F[FieldName]>>; | ||
}; | ||
@@ -14,4 +14,4 @@ export declare class Form<Fields extends FieldRecord<never> = {}> { | ||
field: <FieldName extends string, V extends Validate<FieldName | keyof Fields>>(fieldName: Not<FieldName, keyof Fields>, validate: V) => Form<Fields & Record<FieldName, V>>; | ||
validate: (formData: FormData) => Promise<ErrorRecord<Fields> | null>; | ||
validate: (formData: FormData | Record<string, string | number>) => Promise<ErrorRecord<Fields> | null>; | ||
} | ||
export {}; |
@@ -12,5 +12,7 @@ export class Form { | ||
const errors = {}; | ||
const formDataMap = new Map(formData.entries()); | ||
const formDataMap = formData instanceof FormData | ||
? new Map(formData.entries()) | ||
: new Map(Object.entries(formData)); | ||
for (const [fieldName, validate] of Object.entries(this.fields)) { | ||
const formValue = formData.get(fieldName); | ||
const formValue = formDataMap.get(fieldName); | ||
const result = await validate(formValue, formDataMap); | ||
@@ -17,0 +19,0 @@ if (result === undefined) |
export { Form } from "./form.js"; | ||
export { pattern, max, maxLength, min, minLength, required } from "./utils.js"; |
export { Form } from "./form.js"; | ||
export { pattern, max, maxLength, min, minLength, required } from "./utils.js"; |
{ | ||
"name": "adria-forms", | ||
"version": "0.2.3", | ||
"description": "A super simple form validation library", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"module": "index.js", | ||
"type": "module", | ||
"files": [ | ||
"./**/*" | ||
], | ||
"scripts": { | ||
"build": "tsc && cp ./package.json ./dist && cp ./README.md ./dist" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/pilcrowOnPaper/adria" | ||
}, | ||
"keywords": [ | ||
"form", | ||
"validation" | ||
], | ||
"exports": { | ||
".": "./index.js" | ||
}, | ||
"author": "pilcrow", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/pilcrowOnPaper/adria/issues" | ||
}, | ||
"homepage": "https://github.com/pilcrowOnPaper/adria#readme", | ||
"devDependencies": { | ||
"@types/cli-color": "^2.0.2", | ||
"@types/node": "^18.7.18", | ||
"typescript": "^4.8.3" | ||
}, | ||
"dependencies": { | ||
"cli-color": "^2.0.3" | ||
} | ||
"name": "adria-forms", | ||
"version": "0.2.4", | ||
"description": "A super simple form validation library", | ||
"main": "index.js", | ||
"types": "index.d.ts", | ||
"module": "index.js", | ||
"type": "module", | ||
"files": [ | ||
"./**/*" | ||
], | ||
"scripts": { | ||
"build": "tsc && cp ./package.json ./dist && cp ./README.md ./dist && cp ./.npmignore ./dist", | ||
"test": "npx ts-node --esm -T test/index.ts" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/pilcrowOnPaper/adria" | ||
}, | ||
"keywords": [ | ||
"form", | ||
"validation" | ||
], | ||
"exports": { | ||
".": "./index.js" | ||
}, | ||
"author": "pilcrow", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/pilcrowOnPaper/adria/issues" | ||
}, | ||
"homepage": "https://github.com/pilcrowOnPaper/adria#readme", | ||
"devDependencies": { | ||
"@types/cli-color": "^2.0.2", | ||
"@types/node": "^18.7.18", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^4.8.3" | ||
} | ||
} |
@@ -17,9 +17,9 @@ # Adria | ||
const form = new Form().field("username", (value) => { | ||
if (!value) return "Please enter your username"; | ||
if (typeof value !== "string") return "Invalid input"; | ||
if (value.length < 4) return "Username must be at least 4 characters long"; | ||
return; // success | ||
if (!value) return "Please enter your username"; | ||
if (typeof value !== "string") return "Invalid input"; | ||
if (value.length < 4) return "Username must be at least 4 characters long"; | ||
return; // success | ||
}); | ||
const formData = new FormData(); | ||
const formData = new FormData(); // can be a regular object as well | ||
@@ -41,7 +41,7 @@ const errors = await form.validate(formData); | ||
const field: ( | ||
fieldName: string, | ||
validate: ( | ||
value: null | FormDataEntryValue, | ||
formData: Map<string, FormDataEntryValue | null> | ||
) => MaybePromise<void | any> | ||
fieldName: string, | ||
validate: ( | ||
value: null | FormDataEntryValue, | ||
formData: Map<string, FormDataEntryValue | null> | ||
) => MaybePromise<void | any> | ||
) => this; | ||
@@ -54,18 +54,18 @@ ``` | ||
new Form() | ||
.field("username", (value) => { | ||
if (!value) | ||
return { | ||
code: 0, | ||
message: "empty input", | ||
}; | ||
return; // success | ||
}) | ||
.field("password", (_, formData) => { | ||
const usernameField = formData.get("username"); // autocompletes username, password | ||
const passwordField = formData.get("randomFieldName"); // TS will yell at you since the field doesn't exist yet | ||
}) | ||
.field( | ||
"username" // TS will yell at you since this field already exists | ||
// ... | ||
); | ||
.field("username", (value) => { | ||
if (!value) | ||
return { | ||
code: 0, | ||
message: "empty input", | ||
}; | ||
return; // success | ||
}) | ||
.field("password", (_, formData) => { | ||
const usernameField = formData.get("username"); // autocompletes username, password | ||
const passwordField = formData.get("randomFieldName"); // TS will yell at you since the field doesn't exist yet | ||
}) | ||
.field( | ||
"username" // TS will yell at you since this field already exists | ||
// ... | ||
); | ||
``` | ||
@@ -75,6 +75,8 @@ | ||
Validates the form data. Will only check fields defined with `.field()`. Will return `null` if the form data is valid or a fieldName:errorMessage record if not. | ||
Validates the form data. Will only check fields defined with `.field()`. Will return `null` if the form data is valid or a `fieldName:errorMessage` record if not. | ||
```ts | ||
const validate: (formData: FormData) => Promise<Record<string, any> | null>; | ||
const validate: ( | ||
formData: FormData | Record<any, any> | ||
) => Promise<Record<string, any> | null>; | ||
``` | ||
@@ -86,12 +88,12 @@ | ||
const form = new Form() | ||
.field("username", () => { | ||
return "error"; | ||
}) | ||
.field("password", () => { | ||
return { | ||
code: 0, | ||
}; | ||
}); | ||
.field("username", () => { | ||
return "error"; | ||
}) | ||
.field("password", () => { | ||
return { | ||
code: 0, | ||
}; | ||
}); | ||
const errors = await form.validate(formData as FormData); | ||
const errors = await form.validate(formData); | ||
@@ -103,11 +105,11 @@ const userNameError: "fail" = errors.username; // autocomplete username, password | ||
## TypeScript tips | ||
## TypeScript | ||
In the previous example (validate()), errors will only be typed with a value when the validate function returns a string/number. We can fix this by typing the return value of the validate function `as const`. | ||
In the previous example (`validate()`), errors will only be typed with a value when the validate function returns a string/number. We can fix this by typing the return value of the validate function `as const`. | ||
```ts | ||
const form = new Form().field("password", () => { | ||
return { | ||
code: 0, | ||
} as const; | ||
return { | ||
code: 0, | ||
} as const; | ||
}); | ||
@@ -114,0 +116,0 @@ |
8015
0
8
99
115
4
- Removedcli-color@^2.0.3
- Removedcli-color@2.0.4(transitive)
- Removedd@1.0.2(transitive)
- Removedes5-ext@0.10.64(transitive)
- Removedes6-iterator@2.0.3(transitive)
- Removedes6-symbol@3.1.4(transitive)
- Removedes6-weak-map@2.0.3(transitive)
- Removedesniff@2.0.1(transitive)
- Removedevent-emitter@0.3.5(transitive)
- Removedext@1.7.0(transitive)
- Removedis-promise@2.2.2(transitive)
- Removedlru-queue@0.1.0(transitive)
- Removedmemoizee@0.4.17(transitive)
- Removednext-tick@1.1.0(transitive)
- Removedtimers-ext@0.1.8(transitive)
- Removedtype@2.7.3(transitive)