@mohasinac/validation 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ addressSchema: () => addressSchema,
24
+ dateStringSchema: () => dateStringSchema,
25
+ emailSchema: () => emailSchema,
26
+ mediaUrlSchema: () => mediaUrlSchema,
27
+ objectIdSchema: () => objectIdSchema,
28
+ paginationQuerySchema: () => paginationQuerySchema,
29
+ passwordSchema: () => passwordSchema,
30
+ phoneSchema: () => phoneSchema,
31
+ setupZodErrorMap: () => setupZodErrorMap,
32
+ urlSchema: () => urlSchema,
33
+ zodErrorMap: () => zodErrorMap
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/schemas.ts
38
+ var import_zod = require("zod");
39
+ var paginationQuerySchema = import_zod.z.object({
40
+ page: import_zod.z.coerce.number().int().positive().default(1),
41
+ limit: import_zod.z.coerce.number().int().positive().max(100).default(20),
42
+ sortBy: import_zod.z.string().optional(),
43
+ sortOrder: import_zod.z.enum(["asc", "desc"]).default("desc"),
44
+ search: import_zod.z.string().min(1).max(100).optional()
45
+ });
46
+ var objectIdSchema = import_zod.z.string().regex(/^[a-z0-9-]+$/);
47
+ var urlSchema = import_zod.z.string().url().max(2048);
48
+ var APPROVED_MEDIA_DOMAINS = [
49
+ "firebasestorage.googleapis.com",
50
+ "storage.googleapis.com",
51
+ "res.cloudinary.com",
52
+ "images.unsplash.com",
53
+ "cdn.letitrip.in"
54
+ ];
55
+ var mediaUrlSchema = import_zod.z.string().url().max(2048).refine(
56
+ (url) => {
57
+ try {
58
+ const { hostname } = new URL(url);
59
+ return APPROVED_MEDIA_DOMAINS.some(
60
+ (domain) => hostname === domain || hostname.endsWith(`.${domain}`)
61
+ );
62
+ } catch (e) {
63
+ return false;
64
+ }
65
+ },
66
+ { message: "Image or video URL must be hosted on an approved CDN domain" }
67
+ );
68
+ var dateStringSchema = import_zod.z.string().datetime();
69
+ var passwordSchema = import_zod.z.string().min(12, "Password must be at least 12 characters").max(128, "Password must be less than 128 characters").refine(
70
+ (p) => /[A-Z]/.test(p) && /[a-z]/.test(p) && /\d/.test(p) && /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(p),
71
+ "Password must contain uppercase, lowercase, number, and special character"
72
+ ).refine(
73
+ (p) => !["qwerty", "asdf", "zxcv", "123456", "password", "admin"].some(
74
+ (pat) => p.toLowerCase().includes(pat)
75
+ ),
76
+ "Password contains common patterns"
77
+ );
78
+ var phoneSchema = import_zod.z.string().refine(
79
+ (phone) => /^\+?[1-9]\d{1,14}$/.test(phone.replace(/\D/g, "")),
80
+ "Invalid phone number format"
81
+ ).refine((phone) => {
82
+ const digits = phone.replace(/\D/g, "");
83
+ return digits.length >= 10 && digits.length <= 15;
84
+ }, "Phone number must have 10-15 digits");
85
+ var emailSchema = import_zod.z.string().email().max(255);
86
+ var addressSchema = import_zod.z.object({
87
+ street: import_zod.z.string().min(5, "Street address too short").max(100, "Street address too long").refine(
88
+ (street) => !/^[\d\s]+$/.test(street),
89
+ "Street must contain non-numeric characters"
90
+ ),
91
+ city: import_zod.z.string().min(2, "City name too short").regex(/^[a-zA-Z\s\-']+$/, "Invalid city name"),
92
+ state: import_zod.z.string().min(2, "State code required").max(50, "Invalid state"),
93
+ pincode: import_zod.z.string().refine((pin) => /^\d{5,6}$/.test(pin), "Invalid pincode format"),
94
+ country: import_zod.z.string().length(2, "Country code must be 2 characters").toUpperCase()
95
+ });
96
+
97
+ // src/zod-error-map.ts
98
+ var import_zod2 = require("zod");
99
+ function zodErrorMap(issue) {
100
+ var _a, _b, _c, _d;
101
+ const code = issue.code;
102
+ if (code === "invalid_type") {
103
+ const inp = issue.input;
104
+ if (inp === void 0 || inp === null) {
105
+ return { message: "This field is required" };
106
+ }
107
+ return { message: "Invalid type" };
108
+ }
109
+ if (code === "too_small") {
110
+ const i = issue;
111
+ const min = Number((_a = i.minimum) != null ? _a : 0);
112
+ if (i.origin === "string") {
113
+ if (min <= 1) return { message: "This field is required" };
114
+ return {
115
+ message: `Must be at least ${min} character${min === 1 ? "" : "s"}`
116
+ };
117
+ }
118
+ if (i.origin === "array" || i.origin === "set") {
119
+ return {
120
+ message: `Must contain at least ${min} item${min === 1 ? "" : "s"}`
121
+ };
122
+ }
123
+ return { message: `Must be at least ${min}` };
124
+ }
125
+ if (code === "too_big") {
126
+ const i = issue;
127
+ const max = Number((_b = i.maximum) != null ? _b : 0);
128
+ if (i.origin === "string") {
129
+ return {
130
+ message: `Must be at most ${max} character${max === 1 ? "" : "s"}`
131
+ };
132
+ }
133
+ if (i.origin === "array" || i.origin === "set") {
134
+ return {
135
+ message: `Must contain at most ${max} item${max === 1 ? "" : "s"}`
136
+ };
137
+ }
138
+ return { message: `Must be at most ${max}` };
139
+ }
140
+ if (code === "invalid_format") {
141
+ const fmt = (_c = issue.format) != null ? _c : "";
142
+ if (fmt === "email")
143
+ return { message: "Please enter a valid email address" };
144
+ if (fmt === "url") return { message: "Please enter a valid URL" };
145
+ if (fmt === "uuid" || fmt === "guid")
146
+ return { message: "Invalid ID format" };
147
+ if (fmt === "regex") return { message: "Invalid input provided" };
148
+ return { message: `Invalid ${fmt} format` };
149
+ }
150
+ if (code === "invalid_value") {
151
+ const opts = issue.values;
152
+ if (opts == null ? void 0 : opts.length) {
153
+ return { message: `Invalid value. Expected one of: ${opts.join(", ")}` };
154
+ }
155
+ return { message: "Invalid input provided" };
156
+ }
157
+ if (code === "custom") {
158
+ const msg = issue.message;
159
+ if (msg) return { message: msg };
160
+ }
161
+ return {
162
+ message: (_d = issue.message) != null ? _d : "Invalid value"
163
+ };
164
+ }
165
+ var _applied = false;
166
+ function setupZodErrorMap() {
167
+ if (_applied) return;
168
+ import_zod2.z.setErrorMap(zodErrorMap);
169
+ _applied = true;
170
+ }
171
+ // Annotate the CommonJS export names for ESM import in node:
172
+ 0 && (module.exports = {
173
+ addressSchema,
174
+ dateStringSchema,
175
+ emailSchema,
176
+ mediaUrlSchema,
177
+ objectIdSchema,
178
+ paginationQuerySchema,
179
+ passwordSchema,
180
+ phoneSchema,
181
+ setupZodErrorMap,
182
+ urlSchema,
183
+ zodErrorMap
184
+ });
@@ -0,0 +1,63 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const paginationQuerySchema: z.ZodObject<{
4
+ page: z.ZodDefault<z.ZodNumber>;
5
+ limit: z.ZodDefault<z.ZodNumber>;
6
+ sortBy: z.ZodOptional<z.ZodString>;
7
+ sortOrder: z.ZodDefault<z.ZodEnum<["asc", "desc"]>>;
8
+ search: z.ZodOptional<z.ZodString>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ page: number;
11
+ limit: number;
12
+ sortOrder: "asc" | "desc";
13
+ sortBy?: string | undefined;
14
+ search?: string | undefined;
15
+ }, {
16
+ page?: number | undefined;
17
+ limit?: number | undefined;
18
+ sortBy?: string | undefined;
19
+ sortOrder?: "asc" | "desc" | undefined;
20
+ search?: string | undefined;
21
+ }>;
22
+ declare const objectIdSchema: z.ZodString;
23
+ declare const urlSchema: z.ZodString;
24
+ declare const mediaUrlSchema: z.ZodEffects<z.ZodString, string, string>;
25
+ declare const dateStringSchema: z.ZodString;
26
+ declare const passwordSchema: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
27
+ declare const phoneSchema: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
28
+ declare const emailSchema: z.ZodString;
29
+ declare const addressSchema: z.ZodObject<{
30
+ street: z.ZodEffects<z.ZodString, string, string>;
31
+ city: z.ZodString;
32
+ state: z.ZodString;
33
+ pincode: z.ZodEffects<z.ZodString, string, string>;
34
+ country: z.ZodString;
35
+ }, "strip", z.ZodTypeAny, {
36
+ street: string;
37
+ city: string;
38
+ state: string;
39
+ pincode: string;
40
+ country: string;
41
+ }, {
42
+ street: string;
43
+ city: string;
44
+ state: string;
45
+ pincode: string;
46
+ country: string;
47
+ }>;
48
+
49
+ /**
50
+ * Custom Zod v4 error map that replaces machine-y messages with human-friendly strings.
51
+ *
52
+ * Zod v4 notes:
53
+ * - Error map takes a single `issue` argument (no `ctx`)
54
+ * - `invalid_string` → `invalid_format` (format in `issue.format`)
55
+ * - `invalid_enum_value` → `invalid_value`
56
+ */
57
+ declare function zodErrorMap(issue: Parameters<Parameters<typeof z.setErrorMap>[0]>[0]): {
58
+ message: string;
59
+ };
60
+ /** Apply the custom error map globally. Safe to call multiple times. */
61
+ declare function setupZodErrorMap(): void;
62
+
63
+ export { addressSchema, dateStringSchema, emailSchema, mediaUrlSchema, objectIdSchema, paginationQuerySchema, passwordSchema, phoneSchema, setupZodErrorMap, urlSchema, zodErrorMap };
@@ -0,0 +1,63 @@
1
+ import { z } from 'zod';
2
+
3
+ declare const paginationQuerySchema: z.ZodObject<{
4
+ page: z.ZodDefault<z.ZodNumber>;
5
+ limit: z.ZodDefault<z.ZodNumber>;
6
+ sortBy: z.ZodOptional<z.ZodString>;
7
+ sortOrder: z.ZodDefault<z.ZodEnum<["asc", "desc"]>>;
8
+ search: z.ZodOptional<z.ZodString>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ page: number;
11
+ limit: number;
12
+ sortOrder: "asc" | "desc";
13
+ sortBy?: string | undefined;
14
+ search?: string | undefined;
15
+ }, {
16
+ page?: number | undefined;
17
+ limit?: number | undefined;
18
+ sortBy?: string | undefined;
19
+ sortOrder?: "asc" | "desc" | undefined;
20
+ search?: string | undefined;
21
+ }>;
22
+ declare const objectIdSchema: z.ZodString;
23
+ declare const urlSchema: z.ZodString;
24
+ declare const mediaUrlSchema: z.ZodEffects<z.ZodString, string, string>;
25
+ declare const dateStringSchema: z.ZodString;
26
+ declare const passwordSchema: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
27
+ declare const phoneSchema: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
28
+ declare const emailSchema: z.ZodString;
29
+ declare const addressSchema: z.ZodObject<{
30
+ street: z.ZodEffects<z.ZodString, string, string>;
31
+ city: z.ZodString;
32
+ state: z.ZodString;
33
+ pincode: z.ZodEffects<z.ZodString, string, string>;
34
+ country: z.ZodString;
35
+ }, "strip", z.ZodTypeAny, {
36
+ street: string;
37
+ city: string;
38
+ state: string;
39
+ pincode: string;
40
+ country: string;
41
+ }, {
42
+ street: string;
43
+ city: string;
44
+ state: string;
45
+ pincode: string;
46
+ country: string;
47
+ }>;
48
+
49
+ /**
50
+ * Custom Zod v4 error map that replaces machine-y messages with human-friendly strings.
51
+ *
52
+ * Zod v4 notes:
53
+ * - Error map takes a single `issue` argument (no `ctx`)
54
+ * - `invalid_string` → `invalid_format` (format in `issue.format`)
55
+ * - `invalid_enum_value` → `invalid_value`
56
+ */
57
+ declare function zodErrorMap(issue: Parameters<Parameters<typeof z.setErrorMap>[0]>[0]): {
58
+ message: string;
59
+ };
60
+ /** Apply the custom error map globally. Safe to call multiple times. */
61
+ declare function setupZodErrorMap(): void;
62
+
63
+ export { addressSchema, dateStringSchema, emailSchema, mediaUrlSchema, objectIdSchema, paginationQuerySchema, passwordSchema, phoneSchema, setupZodErrorMap, urlSchema, zodErrorMap };
package/dist/index.js ADDED
@@ -0,0 +1,147 @@
1
+ // src/schemas.ts
2
+ import { z } from "zod";
3
+ var paginationQuerySchema = z.object({
4
+ page: z.coerce.number().int().positive().default(1),
5
+ limit: z.coerce.number().int().positive().max(100).default(20),
6
+ sortBy: z.string().optional(),
7
+ sortOrder: z.enum(["asc", "desc"]).default("desc"),
8
+ search: z.string().min(1).max(100).optional()
9
+ });
10
+ var objectIdSchema = z.string().regex(/^[a-z0-9-]+$/);
11
+ var urlSchema = z.string().url().max(2048);
12
+ var APPROVED_MEDIA_DOMAINS = [
13
+ "firebasestorage.googleapis.com",
14
+ "storage.googleapis.com",
15
+ "res.cloudinary.com",
16
+ "images.unsplash.com",
17
+ "cdn.letitrip.in"
18
+ ];
19
+ var mediaUrlSchema = z.string().url().max(2048).refine(
20
+ (url) => {
21
+ try {
22
+ const { hostname } = new URL(url);
23
+ return APPROVED_MEDIA_DOMAINS.some(
24
+ (domain) => hostname === domain || hostname.endsWith(`.${domain}`)
25
+ );
26
+ } catch (e) {
27
+ return false;
28
+ }
29
+ },
30
+ { message: "Image or video URL must be hosted on an approved CDN domain" }
31
+ );
32
+ var dateStringSchema = z.string().datetime();
33
+ var passwordSchema = z.string().min(12, "Password must be at least 12 characters").max(128, "Password must be less than 128 characters").refine(
34
+ (p) => /[A-Z]/.test(p) && /[a-z]/.test(p) && /\d/.test(p) && /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(p),
35
+ "Password must contain uppercase, lowercase, number, and special character"
36
+ ).refine(
37
+ (p) => !["qwerty", "asdf", "zxcv", "123456", "password", "admin"].some(
38
+ (pat) => p.toLowerCase().includes(pat)
39
+ ),
40
+ "Password contains common patterns"
41
+ );
42
+ var phoneSchema = z.string().refine(
43
+ (phone) => /^\+?[1-9]\d{1,14}$/.test(phone.replace(/\D/g, "")),
44
+ "Invalid phone number format"
45
+ ).refine((phone) => {
46
+ const digits = phone.replace(/\D/g, "");
47
+ return digits.length >= 10 && digits.length <= 15;
48
+ }, "Phone number must have 10-15 digits");
49
+ var emailSchema = z.string().email().max(255);
50
+ var addressSchema = z.object({
51
+ street: z.string().min(5, "Street address too short").max(100, "Street address too long").refine(
52
+ (street) => !/^[\d\s]+$/.test(street),
53
+ "Street must contain non-numeric characters"
54
+ ),
55
+ city: z.string().min(2, "City name too short").regex(/^[a-zA-Z\s\-']+$/, "Invalid city name"),
56
+ state: z.string().min(2, "State code required").max(50, "Invalid state"),
57
+ pincode: z.string().refine((pin) => /^\d{5,6}$/.test(pin), "Invalid pincode format"),
58
+ country: z.string().length(2, "Country code must be 2 characters").toUpperCase()
59
+ });
60
+
61
+ // src/zod-error-map.ts
62
+ import { z as z2 } from "zod";
63
+ function zodErrorMap(issue) {
64
+ var _a, _b, _c, _d;
65
+ const code = issue.code;
66
+ if (code === "invalid_type") {
67
+ const inp = issue.input;
68
+ if (inp === void 0 || inp === null) {
69
+ return { message: "This field is required" };
70
+ }
71
+ return { message: "Invalid type" };
72
+ }
73
+ if (code === "too_small") {
74
+ const i = issue;
75
+ const min = Number((_a = i.minimum) != null ? _a : 0);
76
+ if (i.origin === "string") {
77
+ if (min <= 1) return { message: "This field is required" };
78
+ return {
79
+ message: `Must be at least ${min} character${min === 1 ? "" : "s"}`
80
+ };
81
+ }
82
+ if (i.origin === "array" || i.origin === "set") {
83
+ return {
84
+ message: `Must contain at least ${min} item${min === 1 ? "" : "s"}`
85
+ };
86
+ }
87
+ return { message: `Must be at least ${min}` };
88
+ }
89
+ if (code === "too_big") {
90
+ const i = issue;
91
+ const max = Number((_b = i.maximum) != null ? _b : 0);
92
+ if (i.origin === "string") {
93
+ return {
94
+ message: `Must be at most ${max} character${max === 1 ? "" : "s"}`
95
+ };
96
+ }
97
+ if (i.origin === "array" || i.origin === "set") {
98
+ return {
99
+ message: `Must contain at most ${max} item${max === 1 ? "" : "s"}`
100
+ };
101
+ }
102
+ return { message: `Must be at most ${max}` };
103
+ }
104
+ if (code === "invalid_format") {
105
+ const fmt = (_c = issue.format) != null ? _c : "";
106
+ if (fmt === "email")
107
+ return { message: "Please enter a valid email address" };
108
+ if (fmt === "url") return { message: "Please enter a valid URL" };
109
+ if (fmt === "uuid" || fmt === "guid")
110
+ return { message: "Invalid ID format" };
111
+ if (fmt === "regex") return { message: "Invalid input provided" };
112
+ return { message: `Invalid ${fmt} format` };
113
+ }
114
+ if (code === "invalid_value") {
115
+ const opts = issue.values;
116
+ if (opts == null ? void 0 : opts.length) {
117
+ return { message: `Invalid value. Expected one of: ${opts.join(", ")}` };
118
+ }
119
+ return { message: "Invalid input provided" };
120
+ }
121
+ if (code === "custom") {
122
+ const msg = issue.message;
123
+ if (msg) return { message: msg };
124
+ }
125
+ return {
126
+ message: (_d = issue.message) != null ? _d : "Invalid value"
127
+ };
128
+ }
129
+ var _applied = false;
130
+ function setupZodErrorMap() {
131
+ if (_applied) return;
132
+ z2.setErrorMap(zodErrorMap);
133
+ _applied = true;
134
+ }
135
+ export {
136
+ addressSchema,
137
+ dateStringSchema,
138
+ emailSchema,
139
+ mediaUrlSchema,
140
+ objectIdSchema,
141
+ paginationQuerySchema,
142
+ passwordSchema,
143
+ phoneSchema,
144
+ setupZodErrorMap,
145
+ urlSchema,
146
+ zodErrorMap
147
+ };
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@mohasinac/validation",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "private": false,
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "description": "Zod schemas and custom error map for API request validation",
10
+ "main": "./dist/index.cjs",
11
+ "module": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "require": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsup src/index.ts --format esm,cjs --dts",
25
+ "dev": "tsup --watch",
26
+ "typecheck": "tsc --noEmit"
27
+ },
28
+ "dependencies": {
29
+ "zod": "^3.24.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.0.0",
33
+ "tsup": "^8.5.0",
34
+ "typescript": "^5.9.3"
35
+ }
36
+ }