@marmot-systems/common 1.0.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 +153 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +135 -0
- package/dist/index.d.ts +135 -0
- package/dist/index.js +119 -0
- package/dist/index.js.map +1 -0
- package/package.json +42 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
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
|
+
CustomerFormSchema: () => CustomerFormSchema,
|
|
24
|
+
ProductFormSchema: () => ProductFormSchema,
|
|
25
|
+
handleZodCurrency: () => handleZodCurrency,
|
|
26
|
+
normalizeSpaces: () => normalizeSpaces,
|
|
27
|
+
removeAllWhitespace: () => removeAllWhitespace,
|
|
28
|
+
removeDashesAndPlusSign: () => removeDashesAndPlusSign,
|
|
29
|
+
roundWithPrecision: () => roundWithPrecision,
|
|
30
|
+
transformEmptyStringToUndefined: () => transformEmptyStringToUndefined
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(index_exports);
|
|
33
|
+
|
|
34
|
+
// src/schemas/customer_schemas.ts
|
|
35
|
+
var import_zod2 = require("zod");
|
|
36
|
+
|
|
37
|
+
// src/utils/utils.ts
|
|
38
|
+
var import_zod = require("zod");
|
|
39
|
+
function handleZodCurrency(minAmount, maxAmount) {
|
|
40
|
+
return import_zod.z.preprocess((v) => {
|
|
41
|
+
if (v === null || v === void 0) return NaN;
|
|
42
|
+
if (typeof v === "string") {
|
|
43
|
+
const s = v.replace(/[,\s]/g, "");
|
|
44
|
+
if (s === "") return NaN;
|
|
45
|
+
return s;
|
|
46
|
+
}
|
|
47
|
+
return v;
|
|
48
|
+
}, import_zod.z.coerce.number({ message: "Enter a valid number." }).refine(Number.isFinite, { message: "Enter a valid number." })).transform((x) => roundWithPrecision(x, 2)).refine((n) => n >= minAmount, {
|
|
49
|
+
message: `Must be greater than ${minAmount}.`
|
|
50
|
+
}).refine((n) => n <= maxAmount, {
|
|
51
|
+
message: `Exceeds allowed limit ${maxAmount}.`
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
var transformEmptyStringToUndefined = (s) => s.trim() === "" ? void 0 : s;
|
|
55
|
+
var normalizeSpaces = (s) => whitespace(s, "normalize");
|
|
56
|
+
var removeAllWhitespace = (s) => whitespace(s, "remove");
|
|
57
|
+
var whitespace = (s, mode) => {
|
|
58
|
+
if (mode === "remove") {
|
|
59
|
+
return s.replace(/\s+/g, "");
|
|
60
|
+
}
|
|
61
|
+
return s.replace(/\s+/g, " ").trim();
|
|
62
|
+
};
|
|
63
|
+
var removeDashesAndPlusSign = (s) => s.replace(/[+-]/g, "");
|
|
64
|
+
function roundWithPrecision(num, precision, opts) {
|
|
65
|
+
const MAX_PRECISION = 2;
|
|
66
|
+
const { roundType = "half_up" } = opts != null ? opts : {};
|
|
67
|
+
if (!Number.isFinite(num) || num < 0) {
|
|
68
|
+
throw new RangeError("Number must be finite and greater than 0.");
|
|
69
|
+
}
|
|
70
|
+
if (!Number.isFinite(precision) || !Number.isInteger(precision) || precision < 1) {
|
|
71
|
+
throw new RangeError("Precision must be a finite integer greater than 0.");
|
|
72
|
+
}
|
|
73
|
+
if (precision > MAX_PRECISION) {
|
|
74
|
+
throw new RangeError("Max precision allowed is 2.");
|
|
75
|
+
}
|
|
76
|
+
return Number(
|
|
77
|
+
(+(Math.round(+(num + "e" + precision)) + "e" + -precision)).toFixed(
|
|
78
|
+
precision
|
|
79
|
+
)
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/schemas/customer_schemas.ts
|
|
84
|
+
var CustomerFormSchema = import_zod2.z.object({
|
|
85
|
+
customer_name: import_zod2.z.string().transform(normalizeSpaces).pipe(
|
|
86
|
+
import_zod2.z.string().min(1, "Customer name is required").max(50, "Customer name must be at most 50 characters.")
|
|
87
|
+
),
|
|
88
|
+
customer_address: import_zod2.z.string().transform(normalizeSpaces).pipe(
|
|
89
|
+
import_zod2.z.string().max(100, "Customer address must be at most 100 characters.")
|
|
90
|
+
).transform(transformEmptyStringToUndefined).optional(),
|
|
91
|
+
customer_phone_number: import_zod2.z.string().transform(removeAllWhitespace).transform(removeDashesAndPlusSign).refine((s) => s === "" || /^\d{1,15}$/.test(s), {
|
|
92
|
+
message: "Phone number must be from 1 to 15 digits."
|
|
93
|
+
}).transform(transformEmptyStringToUndefined).optional(),
|
|
94
|
+
customer_email_address: import_zod2.z.string().transform(removeAllWhitespace).transform(transformEmptyStringToUndefined).pipe(
|
|
95
|
+
import_zod2.z.string().email().max(254, "Customer email must be at most 254 characters.").transform((email) => email.toLowerCase()).optional()
|
|
96
|
+
).optional(),
|
|
97
|
+
tax_rate: handleZodCurrency(0, 100)
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// src/schemas/product_schemas.ts
|
|
101
|
+
var import_zod3 = require("zod");
|
|
102
|
+
var ProductFormSchema = import_zod3.z.object({
|
|
103
|
+
product_name: import_zod3.z.string().transform(normalizeSpaces).pipe(
|
|
104
|
+
import_zod3.z.string().min(1, "Product name is required").max(50, "Product name must be at most 50 characters.")
|
|
105
|
+
),
|
|
106
|
+
product_description: import_zod3.z.string().transform(normalizeSpaces).pipe(
|
|
107
|
+
import_zod3.z.string().max(100, "Product desription must be at most 100 characters.")
|
|
108
|
+
).transform(transformEmptyStringToUndefined).optional(),
|
|
109
|
+
product_sku: import_zod3.z.string().transform(normalizeSpaces).pipe(import_zod3.z.string().max(30, "Product SKU must be at most 30 characters.")).transform(transformEmptyStringToUndefined).optional(),
|
|
110
|
+
product_upc: import_zod3.z.string().transform((s) => s.replace(/\s+/g, "")).refine((s) => s === "" || /^\d{12}$/.test(s), {
|
|
111
|
+
message: "UPC must be exactly 12 digits"
|
|
112
|
+
}).transform(transformEmptyStringToUndefined).optional(),
|
|
113
|
+
product_gtin_14: import_zod3.z.string().transform((s) => s.replace(/\s+/g, "")).refine((s) => s === "" || /^\d{14}$/.test(s), {
|
|
114
|
+
message: "GTIN14 must be exactly 14 digits"
|
|
115
|
+
}).transform(transformEmptyStringToUndefined).optional(),
|
|
116
|
+
product_type: import_zod3.z.enum(["unit", "weight", "case"], {
|
|
117
|
+
errorMap: () => ({ message: "Product type is required" })
|
|
118
|
+
}),
|
|
119
|
+
weight_unit: import_zod3.z.preprocess((v) => {
|
|
120
|
+
if (v === "") return void 0;
|
|
121
|
+
if (typeof v === "string") return v.trim().toLowerCase();
|
|
122
|
+
return v;
|
|
123
|
+
}, import_zod3.z.enum(["kg", "lb", "g", "oz"]).optional()),
|
|
124
|
+
price: handleZodCurrency(1, 99999),
|
|
125
|
+
cost: handleZodCurrency(1, 99999)
|
|
126
|
+
}).strict().superRefine((data, ctx) => {
|
|
127
|
+
if (data.product_type === "weight" && !data.weight_unit) {
|
|
128
|
+
ctx.addIssue({
|
|
129
|
+
code: import_zod3.z.ZodIssueCode.custom,
|
|
130
|
+
message: "Weight unit is required.",
|
|
131
|
+
path: ["weight_unit"]
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (data.product_type !== "weight" && typeof data.weight_unit !== "undefined") {
|
|
135
|
+
ctx.addIssue({
|
|
136
|
+
code: import_zod3.z.ZodIssueCode.custom,
|
|
137
|
+
message: "Weight unit must be empty",
|
|
138
|
+
path: ["weight_unit"]
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
143
|
+
0 && (module.exports = {
|
|
144
|
+
CustomerFormSchema,
|
|
145
|
+
ProductFormSchema,
|
|
146
|
+
handleZodCurrency,
|
|
147
|
+
normalizeSpaces,
|
|
148
|
+
removeAllWhitespace,
|
|
149
|
+
removeDashesAndPlusSign,
|
|
150
|
+
roundWithPrecision,
|
|
151
|
+
transformEmptyStringToUndefined
|
|
152
|
+
});
|
|
153
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/schemas/customer_schemas.ts","../src/utils/utils.ts","../src/schemas/product_schemas.ts"],"sourcesContent":["export * from \"./schemas/customer_schemas\";\nexport * from \"./schemas/product_schemas\";\nexport * from \"./utils/utils\";\n","import { z } from \"zod\";\nimport * as GlobalUtils from \"../utils/utils\";\n\nexport const CustomerFormSchema = z.object({\n customer_name: z\n .string()\n .transform(GlobalUtils.normalizeSpaces)\n .pipe(\n z\n .string()\n .min(1, \"Customer name is required\")\n .max(50, \"Customer name must be at most 50 characters.\")\n ),\n\n customer_address: z\n .string()\n .transform(GlobalUtils.normalizeSpaces)\n .pipe(\n z.string().max(100, \"Customer address must be at most 100 characters.\")\n )\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n customer_phone_number: z\n .string()\n .transform(GlobalUtils.removeAllWhitespace)\n .transform(GlobalUtils.removeDashesAndPlusSign)\n .refine((s) => s === \"\" || /^\\d{1,15}$/.test(s), {\n message: \"Phone number must be from 1 to 15 digits.\",\n })\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n customer_email_address: z\n .string()\n .transform(GlobalUtils.removeAllWhitespace)\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .pipe(\n z\n .string()\n .email()\n .max(254, \"Customer email must be at most 254 characters.\")\n .transform((email) => email.toLowerCase())\n .optional()\n )\n .optional(),\n\n tax_rate: GlobalUtils.handleZodCurrency(0, 100),\n});\n","import * as GlobalTypes from \"./types\";\nimport { z } from \"zod\";\n\n/**\n * Validates zod currency with precision.\n *\n *\n * @param minAmount\n * @param maxAmount\n * @returns\n */\nexport function handleZodCurrency(minAmount: number, maxAmount: number) {\n return z\n .preprocess((v) => {\n if (v === null || v === undefined) return NaN;\n\n if (typeof v === \"string\") {\n const s = v.replace(/[,\\s]/g, \"\");\n if (s === \"\") return NaN;\n return s;\n }\n\n return v;\n }, z.coerce.number({ message: \"Enter a valid number.\" }).refine(Number.isFinite, { message: \"Enter a valid number.\" }))\n .transform((x) => roundWithPrecision(x, 2))\n .refine((n) => n >= minAmount, {\n message: `Must be greater than ${minAmount}.`,\n })\n .refine((n) => n <= maxAmount, {\n message: `Exceeds allowed limit ${maxAmount}.`,\n });\n}\n\n/**\n * Trims any leading or trailing spaces\n * Transforms empty strings into undefined.\n *\n * @param s\n * @returns\n */\nexport const transformEmptyStringToUndefined = (s: string) =>\n s.trim() === \"\" ? undefined : s;\n\n/**\n * - Collapses any run of whitespace in a string (spaces, tabs, newlines, etc.) into a single ASCII space.\n * - Trims leading and trailing whitespace.\n *\n * @param s\n * @returns\n */\nexport const normalizeSpaces = (s: string) => whitespace(s, \"normalize\");\n\n/**\n * Removes all whitespace from a string\n * @param s\n * @returns\n */\nexport const removeAllWhitespace = (s: string) => whitespace(s, \"remove\");\n\nconst whitespace = (s: string, mode: GlobalTypes.WhitespaceMode) => {\n if (mode === \"remove\") {\n return s.replace(/\\s+/g, \"\");\n }\n\n return s.replace(/\\s+/g, \" \").trim();\n};\n\n/**\n * Removes all dashes and + signs from a string\n * +1-305-555-0123 -> \"13055550123\"\n * 305-555-0123 -> \"3055550123\"\n *\n * @param s\n * @returns\n */\nexport const removeDashesAndPlusSign = (s: string): string =>\n s.replace(/[+-]/g, \"\");\n\n/**\n * Rounds a number to a certain precision.\n * Contract:\n * 1. Number must be finite and non negative.\n * 2. Precision must be finite nonnegative and an integer.\n * 3. Precision must be <= Max precision\n * 4. Returns a number >= 0\n *\n * @param num\n * @param precision\n * @param opts\n * @returns\n */\nexport function roundWithPrecision(\n num: number,\n precision: number,\n opts?: GlobalTypes.ToFixedOptions\n): number {\n const MAX_PRECISION = 2;\n const { roundType = \"half_up\" } = opts ?? {};\n\n if (!Number.isFinite(num) || num < 0) {\n throw new RangeError(\"Number must be finite and greater than 0.\");\n }\n\n if (\n !Number.isFinite(precision) ||\n !Number.isInteger(precision) ||\n precision < 1\n ) {\n throw new RangeError(\"Precision must be a finite integer greater than 0.\");\n }\n\n if (precision > MAX_PRECISION) {\n throw new RangeError(\"Max precision allowed is 2.\");\n }\n\n return Number(\n (+(Math.round(+(num + \"e\" + precision)) + \"e\" + -precision)).toFixed(\n precision\n )\n );\n}\n","import { z } from \"zod\";\nimport * as GlobalUtils from \"../utils/utils\";\n\nexport const ProductFormSchema = z\n .object({\n product_name: z\n .string()\n .transform(GlobalUtils.normalizeSpaces)\n .pipe(\n z\n .string()\n .min(1, \"Product name is required\")\n .max(50, \"Product name must be at most 50 characters.\")\n ),\n\n product_description: z\n .string()\n .transform(GlobalUtils.normalizeSpaces)\n .pipe(\n z\n .string()\n .max(100, \"Product desription must be at most 100 characters.\")\n )\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n product_sku: z\n .string()\n .transform(GlobalUtils.normalizeSpaces)\n .pipe(z.string().max(30, \"Product SKU must be at most 30 characters.\"))\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n product_upc: z\n .string()\n .transform((s) => s.replace(/\\s+/g, \"\"))\n .refine((s) => s === \"\" || /^\\d{12}$/.test(s), {\n message: \"UPC must be exactly 12 digits\",\n })\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n product_gtin_14: z\n .string()\n .transform((s) => s.replace(/\\s+/g, \"\"))\n .refine((s) => s === \"\" || /^\\d{14}$/.test(s), {\n message: \"GTIN14 must be exactly 14 digits\",\n })\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n product_type: z.enum([\"unit\", \"weight\", \"case\"], {\n errorMap: () => ({ message: \"Product type is required\" }),\n }),\n\n weight_unit: z.preprocess((v) => {\n if (v === \"\") return undefined;\n if (typeof v === \"string\") return v.trim().toLowerCase();\n return v;\n }, z.enum([\"kg\", \"lb\", \"g\", \"oz\"]).optional()),\n\n price: GlobalUtils.handleZodCurrency(1, 99_999),\n cost: GlobalUtils.handleZodCurrency(1, 99_999),\n })\n .strict()\n\n .superRefine((data, ctx) => {\n if (data.product_type === \"weight\" && !data.weight_unit) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Weight unit is required.\",\n path: [\"weight_unit\"],\n });\n }\n\n if (\n data.product_type !== \"weight\" &&\n typeof data.weight_unit !== \"undefined\"\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Weight unit must be empty\",\n path: [\"weight_unit\"],\n });\n }\n });\n"],"mappings":"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","names":["import_zod","import_zod"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const CustomerFormSchema: z.ZodObject<{
|
|
4
|
+
customer_name: z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>;
|
|
5
|
+
customer_address: z.ZodOptional<z.ZodEffects<z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>, string | undefined, string>>;
|
|
6
|
+
customer_phone_number: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string, string>, string | undefined, string>>;
|
|
7
|
+
customer_email_address: z.ZodOptional<z.ZodPipeline<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string | undefined, string>, z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>>>;
|
|
8
|
+
tax_rate: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodNumber, number, number>, number, unknown>, number, unknown>, number, unknown>, number, unknown>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
customer_name: string;
|
|
11
|
+
tax_rate: number;
|
|
12
|
+
customer_address?: string | undefined;
|
|
13
|
+
customer_phone_number?: string | undefined;
|
|
14
|
+
customer_email_address?: string | undefined;
|
|
15
|
+
}, {
|
|
16
|
+
customer_name: string;
|
|
17
|
+
customer_address?: string | undefined;
|
|
18
|
+
customer_phone_number?: string | undefined;
|
|
19
|
+
customer_email_address?: string | undefined;
|
|
20
|
+
tax_rate?: unknown;
|
|
21
|
+
}>;
|
|
22
|
+
|
|
23
|
+
declare const ProductFormSchema: z.ZodEffects<z.ZodObject<{
|
|
24
|
+
product_name: z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>;
|
|
25
|
+
product_description: z.ZodOptional<z.ZodEffects<z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>, string | undefined, string>>;
|
|
26
|
+
product_sku: z.ZodOptional<z.ZodEffects<z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>, string | undefined, string>>;
|
|
27
|
+
product_upc: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string | undefined, string>>;
|
|
28
|
+
product_gtin_14: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string | undefined, string>>;
|
|
29
|
+
product_type: z.ZodEnum<["unit", "weight", "case"]>;
|
|
30
|
+
weight_unit: z.ZodEffects<z.ZodOptional<z.ZodEnum<["kg", "lb", "g", "oz"]>>, "kg" | "lb" | "g" | "oz" | undefined, unknown>;
|
|
31
|
+
price: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodNumber, number, number>, number, unknown>, number, unknown>, number, unknown>, number, unknown>;
|
|
32
|
+
cost: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodNumber, number, number>, number, unknown>, number, unknown>, number, unknown>, number, unknown>;
|
|
33
|
+
}, "strict", z.ZodTypeAny, {
|
|
34
|
+
product_name: string;
|
|
35
|
+
product_type: "unit" | "weight" | "case";
|
|
36
|
+
price: number;
|
|
37
|
+
cost: number;
|
|
38
|
+
product_description?: string | undefined;
|
|
39
|
+
product_sku?: string | undefined;
|
|
40
|
+
product_upc?: string | undefined;
|
|
41
|
+
product_gtin_14?: string | undefined;
|
|
42
|
+
weight_unit?: "kg" | "lb" | "g" | "oz" | undefined;
|
|
43
|
+
}, {
|
|
44
|
+
product_name: string;
|
|
45
|
+
product_type: "unit" | "weight" | "case";
|
|
46
|
+
product_description?: string | undefined;
|
|
47
|
+
product_sku?: string | undefined;
|
|
48
|
+
product_upc?: string | undefined;
|
|
49
|
+
product_gtin_14?: string | undefined;
|
|
50
|
+
weight_unit?: unknown;
|
|
51
|
+
price?: unknown;
|
|
52
|
+
cost?: unknown;
|
|
53
|
+
}>, {
|
|
54
|
+
product_name: string;
|
|
55
|
+
product_type: "unit" | "weight" | "case";
|
|
56
|
+
price: number;
|
|
57
|
+
cost: number;
|
|
58
|
+
product_description?: string | undefined;
|
|
59
|
+
product_sku?: string | undefined;
|
|
60
|
+
product_upc?: string | undefined;
|
|
61
|
+
product_gtin_14?: string | undefined;
|
|
62
|
+
weight_unit?: "kg" | "lb" | "g" | "oz" | undefined;
|
|
63
|
+
}, {
|
|
64
|
+
product_name: string;
|
|
65
|
+
product_type: "unit" | "weight" | "case";
|
|
66
|
+
product_description?: string | undefined;
|
|
67
|
+
product_sku?: string | undefined;
|
|
68
|
+
product_upc?: string | undefined;
|
|
69
|
+
product_gtin_14?: string | undefined;
|
|
70
|
+
weight_unit?: unknown;
|
|
71
|
+
price?: unknown;
|
|
72
|
+
cost?: unknown;
|
|
73
|
+
}>;
|
|
74
|
+
|
|
75
|
+
type RoundType = "half_up";
|
|
76
|
+
interface ToFixedOptions {
|
|
77
|
+
roundType?: RoundType;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Validates zod currency with precision.
|
|
82
|
+
*
|
|
83
|
+
*
|
|
84
|
+
* @param minAmount
|
|
85
|
+
* @param maxAmount
|
|
86
|
+
* @returns
|
|
87
|
+
*/
|
|
88
|
+
declare function handleZodCurrency(minAmount: number, maxAmount: number): z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodNumber, number, number>, number, unknown>, number, unknown>, number, unknown>, number, unknown>;
|
|
89
|
+
/**
|
|
90
|
+
* Trims any leading or trailing spaces
|
|
91
|
+
* Transforms empty strings into undefined.
|
|
92
|
+
*
|
|
93
|
+
* @param s
|
|
94
|
+
* @returns
|
|
95
|
+
*/
|
|
96
|
+
declare const transformEmptyStringToUndefined: (s: string) => string | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* - Collapses any run of whitespace in a string (spaces, tabs, newlines, etc.) into a single ASCII space.
|
|
99
|
+
* - Trims leading and trailing whitespace.
|
|
100
|
+
*
|
|
101
|
+
* @param s
|
|
102
|
+
* @returns
|
|
103
|
+
*/
|
|
104
|
+
declare const normalizeSpaces: (s: string) => string;
|
|
105
|
+
/**
|
|
106
|
+
* Removes all whitespace from a string
|
|
107
|
+
* @param s
|
|
108
|
+
* @returns
|
|
109
|
+
*/
|
|
110
|
+
declare const removeAllWhitespace: (s: string) => string;
|
|
111
|
+
/**
|
|
112
|
+
* Removes all dashes and + signs from a string
|
|
113
|
+
* +1-305-555-0123 -> "13055550123"
|
|
114
|
+
* 305-555-0123 -> "3055550123"
|
|
115
|
+
*
|
|
116
|
+
* @param s
|
|
117
|
+
* @returns
|
|
118
|
+
*/
|
|
119
|
+
declare const removeDashesAndPlusSign: (s: string) => string;
|
|
120
|
+
/**
|
|
121
|
+
* Rounds a number to a certain precision.
|
|
122
|
+
* Contract:
|
|
123
|
+
* 1. Number must be finite and non negative.
|
|
124
|
+
* 2. Precision must be finite nonnegative and an integer.
|
|
125
|
+
* 3. Precision must be <= Max precision
|
|
126
|
+
* 4. Returns a number >= 0
|
|
127
|
+
*
|
|
128
|
+
* @param num
|
|
129
|
+
* @param precision
|
|
130
|
+
* @param opts
|
|
131
|
+
* @returns
|
|
132
|
+
*/
|
|
133
|
+
declare function roundWithPrecision(num: number, precision: number, opts?: ToFixedOptions): number;
|
|
134
|
+
|
|
135
|
+
export { CustomerFormSchema, ProductFormSchema, handleZodCurrency, normalizeSpaces, removeAllWhitespace, removeDashesAndPlusSign, roundWithPrecision, transformEmptyStringToUndefined };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const CustomerFormSchema: z.ZodObject<{
|
|
4
|
+
customer_name: z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>;
|
|
5
|
+
customer_address: z.ZodOptional<z.ZodEffects<z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>, string | undefined, string>>;
|
|
6
|
+
customer_phone_number: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string, string>, string | undefined, string>>;
|
|
7
|
+
customer_email_address: z.ZodOptional<z.ZodPipeline<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string | undefined, string>, z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>>>;
|
|
8
|
+
tax_rate: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodNumber, number, number>, number, unknown>, number, unknown>, number, unknown>, number, unknown>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
customer_name: string;
|
|
11
|
+
tax_rate: number;
|
|
12
|
+
customer_address?: string | undefined;
|
|
13
|
+
customer_phone_number?: string | undefined;
|
|
14
|
+
customer_email_address?: string | undefined;
|
|
15
|
+
}, {
|
|
16
|
+
customer_name: string;
|
|
17
|
+
customer_address?: string | undefined;
|
|
18
|
+
customer_phone_number?: string | undefined;
|
|
19
|
+
customer_email_address?: string | undefined;
|
|
20
|
+
tax_rate?: unknown;
|
|
21
|
+
}>;
|
|
22
|
+
|
|
23
|
+
declare const ProductFormSchema: z.ZodEffects<z.ZodObject<{
|
|
24
|
+
product_name: z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>;
|
|
25
|
+
product_description: z.ZodOptional<z.ZodEffects<z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>, string | undefined, string>>;
|
|
26
|
+
product_sku: z.ZodOptional<z.ZodEffects<z.ZodPipeline<z.ZodEffects<z.ZodString, string, string>, z.ZodString>, string | undefined, string>>;
|
|
27
|
+
product_upc: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string | undefined, string>>;
|
|
28
|
+
product_gtin_14: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>, string | undefined, string>>;
|
|
29
|
+
product_type: z.ZodEnum<["unit", "weight", "case"]>;
|
|
30
|
+
weight_unit: z.ZodEffects<z.ZodOptional<z.ZodEnum<["kg", "lb", "g", "oz"]>>, "kg" | "lb" | "g" | "oz" | undefined, unknown>;
|
|
31
|
+
price: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodNumber, number, number>, number, unknown>, number, unknown>, number, unknown>, number, unknown>;
|
|
32
|
+
cost: z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodNumber, number, number>, number, unknown>, number, unknown>, number, unknown>, number, unknown>;
|
|
33
|
+
}, "strict", z.ZodTypeAny, {
|
|
34
|
+
product_name: string;
|
|
35
|
+
product_type: "unit" | "weight" | "case";
|
|
36
|
+
price: number;
|
|
37
|
+
cost: number;
|
|
38
|
+
product_description?: string | undefined;
|
|
39
|
+
product_sku?: string | undefined;
|
|
40
|
+
product_upc?: string | undefined;
|
|
41
|
+
product_gtin_14?: string | undefined;
|
|
42
|
+
weight_unit?: "kg" | "lb" | "g" | "oz" | undefined;
|
|
43
|
+
}, {
|
|
44
|
+
product_name: string;
|
|
45
|
+
product_type: "unit" | "weight" | "case";
|
|
46
|
+
product_description?: string | undefined;
|
|
47
|
+
product_sku?: string | undefined;
|
|
48
|
+
product_upc?: string | undefined;
|
|
49
|
+
product_gtin_14?: string | undefined;
|
|
50
|
+
weight_unit?: unknown;
|
|
51
|
+
price?: unknown;
|
|
52
|
+
cost?: unknown;
|
|
53
|
+
}>, {
|
|
54
|
+
product_name: string;
|
|
55
|
+
product_type: "unit" | "weight" | "case";
|
|
56
|
+
price: number;
|
|
57
|
+
cost: number;
|
|
58
|
+
product_description?: string | undefined;
|
|
59
|
+
product_sku?: string | undefined;
|
|
60
|
+
product_upc?: string | undefined;
|
|
61
|
+
product_gtin_14?: string | undefined;
|
|
62
|
+
weight_unit?: "kg" | "lb" | "g" | "oz" | undefined;
|
|
63
|
+
}, {
|
|
64
|
+
product_name: string;
|
|
65
|
+
product_type: "unit" | "weight" | "case";
|
|
66
|
+
product_description?: string | undefined;
|
|
67
|
+
product_sku?: string | undefined;
|
|
68
|
+
product_upc?: string | undefined;
|
|
69
|
+
product_gtin_14?: string | undefined;
|
|
70
|
+
weight_unit?: unknown;
|
|
71
|
+
price?: unknown;
|
|
72
|
+
cost?: unknown;
|
|
73
|
+
}>;
|
|
74
|
+
|
|
75
|
+
type RoundType = "half_up";
|
|
76
|
+
interface ToFixedOptions {
|
|
77
|
+
roundType?: RoundType;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Validates zod currency with precision.
|
|
82
|
+
*
|
|
83
|
+
*
|
|
84
|
+
* @param minAmount
|
|
85
|
+
* @param maxAmount
|
|
86
|
+
* @returns
|
|
87
|
+
*/
|
|
88
|
+
declare function handleZodCurrency(minAmount: number, maxAmount: number): z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodEffects<z.ZodNumber, number, number>, number, unknown>, number, unknown>, number, unknown>, number, unknown>;
|
|
89
|
+
/**
|
|
90
|
+
* Trims any leading or trailing spaces
|
|
91
|
+
* Transforms empty strings into undefined.
|
|
92
|
+
*
|
|
93
|
+
* @param s
|
|
94
|
+
* @returns
|
|
95
|
+
*/
|
|
96
|
+
declare const transformEmptyStringToUndefined: (s: string) => string | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* - Collapses any run of whitespace in a string (spaces, tabs, newlines, etc.) into a single ASCII space.
|
|
99
|
+
* - Trims leading and trailing whitespace.
|
|
100
|
+
*
|
|
101
|
+
* @param s
|
|
102
|
+
* @returns
|
|
103
|
+
*/
|
|
104
|
+
declare const normalizeSpaces: (s: string) => string;
|
|
105
|
+
/**
|
|
106
|
+
* Removes all whitespace from a string
|
|
107
|
+
* @param s
|
|
108
|
+
* @returns
|
|
109
|
+
*/
|
|
110
|
+
declare const removeAllWhitespace: (s: string) => string;
|
|
111
|
+
/**
|
|
112
|
+
* Removes all dashes and + signs from a string
|
|
113
|
+
* +1-305-555-0123 -> "13055550123"
|
|
114
|
+
* 305-555-0123 -> "3055550123"
|
|
115
|
+
*
|
|
116
|
+
* @param s
|
|
117
|
+
* @returns
|
|
118
|
+
*/
|
|
119
|
+
declare const removeDashesAndPlusSign: (s: string) => string;
|
|
120
|
+
/**
|
|
121
|
+
* Rounds a number to a certain precision.
|
|
122
|
+
* Contract:
|
|
123
|
+
* 1. Number must be finite and non negative.
|
|
124
|
+
* 2. Precision must be finite nonnegative and an integer.
|
|
125
|
+
* 3. Precision must be <= Max precision
|
|
126
|
+
* 4. Returns a number >= 0
|
|
127
|
+
*
|
|
128
|
+
* @param num
|
|
129
|
+
* @param precision
|
|
130
|
+
* @param opts
|
|
131
|
+
* @returns
|
|
132
|
+
*/
|
|
133
|
+
declare function roundWithPrecision(num: number, precision: number, opts?: ToFixedOptions): number;
|
|
134
|
+
|
|
135
|
+
export { CustomerFormSchema, ProductFormSchema, handleZodCurrency, normalizeSpaces, removeAllWhitespace, removeDashesAndPlusSign, roundWithPrecision, transformEmptyStringToUndefined };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// src/schemas/customer_schemas.ts
|
|
2
|
+
import { z as z2 } from "zod";
|
|
3
|
+
|
|
4
|
+
// src/utils/utils.ts
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
function handleZodCurrency(minAmount, maxAmount) {
|
|
7
|
+
return z.preprocess((v) => {
|
|
8
|
+
if (v === null || v === void 0) return NaN;
|
|
9
|
+
if (typeof v === "string") {
|
|
10
|
+
const s = v.replace(/[,\s]/g, "");
|
|
11
|
+
if (s === "") return NaN;
|
|
12
|
+
return s;
|
|
13
|
+
}
|
|
14
|
+
return v;
|
|
15
|
+
}, z.coerce.number({ message: "Enter a valid number." }).refine(Number.isFinite, { message: "Enter a valid number." })).transform((x) => roundWithPrecision(x, 2)).refine((n) => n >= minAmount, {
|
|
16
|
+
message: `Must be greater than ${minAmount}.`
|
|
17
|
+
}).refine((n) => n <= maxAmount, {
|
|
18
|
+
message: `Exceeds allowed limit ${maxAmount}.`
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
var transformEmptyStringToUndefined = (s) => s.trim() === "" ? void 0 : s;
|
|
22
|
+
var normalizeSpaces = (s) => whitespace(s, "normalize");
|
|
23
|
+
var removeAllWhitespace = (s) => whitespace(s, "remove");
|
|
24
|
+
var whitespace = (s, mode) => {
|
|
25
|
+
if (mode === "remove") {
|
|
26
|
+
return s.replace(/\s+/g, "");
|
|
27
|
+
}
|
|
28
|
+
return s.replace(/\s+/g, " ").trim();
|
|
29
|
+
};
|
|
30
|
+
var removeDashesAndPlusSign = (s) => s.replace(/[+-]/g, "");
|
|
31
|
+
function roundWithPrecision(num, precision, opts) {
|
|
32
|
+
const MAX_PRECISION = 2;
|
|
33
|
+
const { roundType = "half_up" } = opts != null ? opts : {};
|
|
34
|
+
if (!Number.isFinite(num) || num < 0) {
|
|
35
|
+
throw new RangeError("Number must be finite and greater than 0.");
|
|
36
|
+
}
|
|
37
|
+
if (!Number.isFinite(precision) || !Number.isInteger(precision) || precision < 1) {
|
|
38
|
+
throw new RangeError("Precision must be a finite integer greater than 0.");
|
|
39
|
+
}
|
|
40
|
+
if (precision > MAX_PRECISION) {
|
|
41
|
+
throw new RangeError("Max precision allowed is 2.");
|
|
42
|
+
}
|
|
43
|
+
return Number(
|
|
44
|
+
(+(Math.round(+(num + "e" + precision)) + "e" + -precision)).toFixed(
|
|
45
|
+
precision
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/schemas/customer_schemas.ts
|
|
51
|
+
var CustomerFormSchema = z2.object({
|
|
52
|
+
customer_name: z2.string().transform(normalizeSpaces).pipe(
|
|
53
|
+
z2.string().min(1, "Customer name is required").max(50, "Customer name must be at most 50 characters.")
|
|
54
|
+
),
|
|
55
|
+
customer_address: z2.string().transform(normalizeSpaces).pipe(
|
|
56
|
+
z2.string().max(100, "Customer address must be at most 100 characters.")
|
|
57
|
+
).transform(transformEmptyStringToUndefined).optional(),
|
|
58
|
+
customer_phone_number: z2.string().transform(removeAllWhitespace).transform(removeDashesAndPlusSign).refine((s) => s === "" || /^\d{1,15}$/.test(s), {
|
|
59
|
+
message: "Phone number must be from 1 to 15 digits."
|
|
60
|
+
}).transform(transformEmptyStringToUndefined).optional(),
|
|
61
|
+
customer_email_address: z2.string().transform(removeAllWhitespace).transform(transformEmptyStringToUndefined).pipe(
|
|
62
|
+
z2.string().email().max(254, "Customer email must be at most 254 characters.").transform((email) => email.toLowerCase()).optional()
|
|
63
|
+
).optional(),
|
|
64
|
+
tax_rate: handleZodCurrency(0, 100)
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// src/schemas/product_schemas.ts
|
|
68
|
+
import { z as z3 } from "zod";
|
|
69
|
+
var ProductFormSchema = z3.object({
|
|
70
|
+
product_name: z3.string().transform(normalizeSpaces).pipe(
|
|
71
|
+
z3.string().min(1, "Product name is required").max(50, "Product name must be at most 50 characters.")
|
|
72
|
+
),
|
|
73
|
+
product_description: z3.string().transform(normalizeSpaces).pipe(
|
|
74
|
+
z3.string().max(100, "Product desription must be at most 100 characters.")
|
|
75
|
+
).transform(transformEmptyStringToUndefined).optional(),
|
|
76
|
+
product_sku: z3.string().transform(normalizeSpaces).pipe(z3.string().max(30, "Product SKU must be at most 30 characters.")).transform(transformEmptyStringToUndefined).optional(),
|
|
77
|
+
product_upc: z3.string().transform((s) => s.replace(/\s+/g, "")).refine((s) => s === "" || /^\d{12}$/.test(s), {
|
|
78
|
+
message: "UPC must be exactly 12 digits"
|
|
79
|
+
}).transform(transformEmptyStringToUndefined).optional(),
|
|
80
|
+
product_gtin_14: z3.string().transform((s) => s.replace(/\s+/g, "")).refine((s) => s === "" || /^\d{14}$/.test(s), {
|
|
81
|
+
message: "GTIN14 must be exactly 14 digits"
|
|
82
|
+
}).transform(transformEmptyStringToUndefined).optional(),
|
|
83
|
+
product_type: z3.enum(["unit", "weight", "case"], {
|
|
84
|
+
errorMap: () => ({ message: "Product type is required" })
|
|
85
|
+
}),
|
|
86
|
+
weight_unit: z3.preprocess((v) => {
|
|
87
|
+
if (v === "") return void 0;
|
|
88
|
+
if (typeof v === "string") return v.trim().toLowerCase();
|
|
89
|
+
return v;
|
|
90
|
+
}, z3.enum(["kg", "lb", "g", "oz"]).optional()),
|
|
91
|
+
price: handleZodCurrency(1, 99999),
|
|
92
|
+
cost: handleZodCurrency(1, 99999)
|
|
93
|
+
}).strict().superRefine((data, ctx) => {
|
|
94
|
+
if (data.product_type === "weight" && !data.weight_unit) {
|
|
95
|
+
ctx.addIssue({
|
|
96
|
+
code: z3.ZodIssueCode.custom,
|
|
97
|
+
message: "Weight unit is required.",
|
|
98
|
+
path: ["weight_unit"]
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (data.product_type !== "weight" && typeof data.weight_unit !== "undefined") {
|
|
102
|
+
ctx.addIssue({
|
|
103
|
+
code: z3.ZodIssueCode.custom,
|
|
104
|
+
message: "Weight unit must be empty",
|
|
105
|
+
path: ["weight_unit"]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
export {
|
|
110
|
+
CustomerFormSchema,
|
|
111
|
+
ProductFormSchema,
|
|
112
|
+
handleZodCurrency,
|
|
113
|
+
normalizeSpaces,
|
|
114
|
+
removeAllWhitespace,
|
|
115
|
+
removeDashesAndPlusSign,
|
|
116
|
+
roundWithPrecision,
|
|
117
|
+
transformEmptyStringToUndefined
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schemas/customer_schemas.ts","../src/utils/utils.ts","../src/schemas/product_schemas.ts"],"sourcesContent":["import { z } from \"zod\";\nimport * as GlobalUtils from \"../utils/utils\";\n\nexport const CustomerFormSchema = z.object({\n customer_name: z\n .string()\n .transform(GlobalUtils.normalizeSpaces)\n .pipe(\n z\n .string()\n .min(1, \"Customer name is required\")\n .max(50, \"Customer name must be at most 50 characters.\")\n ),\n\n customer_address: z\n .string()\n .transform(GlobalUtils.normalizeSpaces)\n .pipe(\n z.string().max(100, \"Customer address must be at most 100 characters.\")\n )\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n customer_phone_number: z\n .string()\n .transform(GlobalUtils.removeAllWhitespace)\n .transform(GlobalUtils.removeDashesAndPlusSign)\n .refine((s) => s === \"\" || /^\\d{1,15}$/.test(s), {\n message: \"Phone number must be from 1 to 15 digits.\",\n })\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n customer_email_address: z\n .string()\n .transform(GlobalUtils.removeAllWhitespace)\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .pipe(\n z\n .string()\n .email()\n .max(254, \"Customer email must be at most 254 characters.\")\n .transform((email) => email.toLowerCase())\n .optional()\n )\n .optional(),\n\n tax_rate: GlobalUtils.handleZodCurrency(0, 100),\n});\n","import * as GlobalTypes from \"./types\";\nimport { z } from \"zod\";\n\n/**\n * Validates zod currency with precision.\n *\n *\n * @param minAmount\n * @param maxAmount\n * @returns\n */\nexport function handleZodCurrency(minAmount: number, maxAmount: number) {\n return z\n .preprocess((v) => {\n if (v === null || v === undefined) return NaN;\n\n if (typeof v === \"string\") {\n const s = v.replace(/[,\\s]/g, \"\");\n if (s === \"\") return NaN;\n return s;\n }\n\n return v;\n }, z.coerce.number({ message: \"Enter a valid number.\" }).refine(Number.isFinite, { message: \"Enter a valid number.\" }))\n .transform((x) => roundWithPrecision(x, 2))\n .refine((n) => n >= minAmount, {\n message: `Must be greater than ${minAmount}.`,\n })\n .refine((n) => n <= maxAmount, {\n message: `Exceeds allowed limit ${maxAmount}.`,\n });\n}\n\n/**\n * Trims any leading or trailing spaces\n * Transforms empty strings into undefined.\n *\n * @param s\n * @returns\n */\nexport const transformEmptyStringToUndefined = (s: string) =>\n s.trim() === \"\" ? undefined : s;\n\n/**\n * - Collapses any run of whitespace in a string (spaces, tabs, newlines, etc.) into a single ASCII space.\n * - Trims leading and trailing whitespace.\n *\n * @param s\n * @returns\n */\nexport const normalizeSpaces = (s: string) => whitespace(s, \"normalize\");\n\n/**\n * Removes all whitespace from a string\n * @param s\n * @returns\n */\nexport const removeAllWhitespace = (s: string) => whitespace(s, \"remove\");\n\nconst whitespace = (s: string, mode: GlobalTypes.WhitespaceMode) => {\n if (mode === \"remove\") {\n return s.replace(/\\s+/g, \"\");\n }\n\n return s.replace(/\\s+/g, \" \").trim();\n};\n\n/**\n * Removes all dashes and + signs from a string\n * +1-305-555-0123 -> \"13055550123\"\n * 305-555-0123 -> \"3055550123\"\n *\n * @param s\n * @returns\n */\nexport const removeDashesAndPlusSign = (s: string): string =>\n s.replace(/[+-]/g, \"\");\n\n/**\n * Rounds a number to a certain precision.\n * Contract:\n * 1. Number must be finite and non negative.\n * 2. Precision must be finite nonnegative and an integer.\n * 3. Precision must be <= Max precision\n * 4. Returns a number >= 0\n *\n * @param num\n * @param precision\n * @param opts\n * @returns\n */\nexport function roundWithPrecision(\n num: number,\n precision: number,\n opts?: GlobalTypes.ToFixedOptions\n): number {\n const MAX_PRECISION = 2;\n const { roundType = \"half_up\" } = opts ?? {};\n\n if (!Number.isFinite(num) || num < 0) {\n throw new RangeError(\"Number must be finite and greater than 0.\");\n }\n\n if (\n !Number.isFinite(precision) ||\n !Number.isInteger(precision) ||\n precision < 1\n ) {\n throw new RangeError(\"Precision must be a finite integer greater than 0.\");\n }\n\n if (precision > MAX_PRECISION) {\n throw new RangeError(\"Max precision allowed is 2.\");\n }\n\n return Number(\n (+(Math.round(+(num + \"e\" + precision)) + \"e\" + -precision)).toFixed(\n precision\n )\n );\n}\n","import { z } from \"zod\";\nimport * as GlobalUtils from \"../utils/utils\";\n\nexport const ProductFormSchema = z\n .object({\n product_name: z\n .string()\n .transform(GlobalUtils.normalizeSpaces)\n .pipe(\n z\n .string()\n .min(1, \"Product name is required\")\n .max(50, \"Product name must be at most 50 characters.\")\n ),\n\n product_description: z\n .string()\n .transform(GlobalUtils.normalizeSpaces)\n .pipe(\n z\n .string()\n .max(100, \"Product desription must be at most 100 characters.\")\n )\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n product_sku: z\n .string()\n .transform(GlobalUtils.normalizeSpaces)\n .pipe(z.string().max(30, \"Product SKU must be at most 30 characters.\"))\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n product_upc: z\n .string()\n .transform((s) => s.replace(/\\s+/g, \"\"))\n .refine((s) => s === \"\" || /^\\d{12}$/.test(s), {\n message: \"UPC must be exactly 12 digits\",\n })\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n product_gtin_14: z\n .string()\n .transform((s) => s.replace(/\\s+/g, \"\"))\n .refine((s) => s === \"\" || /^\\d{14}$/.test(s), {\n message: \"GTIN14 must be exactly 14 digits\",\n })\n .transform(GlobalUtils.transformEmptyStringToUndefined)\n .optional(),\n\n product_type: z.enum([\"unit\", \"weight\", \"case\"], {\n errorMap: () => ({ message: \"Product type is required\" }),\n }),\n\n weight_unit: z.preprocess((v) => {\n if (v === \"\") return undefined;\n if (typeof v === \"string\") return v.trim().toLowerCase();\n return v;\n }, z.enum([\"kg\", \"lb\", \"g\", \"oz\"]).optional()),\n\n price: GlobalUtils.handleZodCurrency(1, 99_999),\n cost: GlobalUtils.handleZodCurrency(1, 99_999),\n })\n .strict()\n\n .superRefine((data, ctx) => {\n if (data.product_type === \"weight\" && !data.weight_unit) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Weight unit is required.\",\n path: [\"weight_unit\"],\n });\n }\n\n if (\n data.product_type !== \"weight\" &&\n typeof data.weight_unit !== \"undefined\"\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Weight unit must be empty\",\n path: [\"weight_unit\"],\n });\n }\n });\n"],"mappings":"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","names":["z","z","z","z"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@marmot-systems/common",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Schemas and utils shared across Marmot apps",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup",
|
|
21
|
+
"test": "npm run test:unit",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"test:unit": "vitest -c vitest.unit.config.ts --run",
|
|
24
|
+
"prepublishOnly": "npm run test && npm run build"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [],
|
|
30
|
+
"author": "",
|
|
31
|
+
"license": "ISC",
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^24.6.2",
|
|
34
|
+
"ts-node": "^10.9.2",
|
|
35
|
+
"tsup": "^8.5.0",
|
|
36
|
+
"typescript": "^5.9.3",
|
|
37
|
+
"vitest": "^3.2.4"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"zod": "^3.24.1"
|
|
41
|
+
}
|
|
42
|
+
}
|