@postxl/utils 1.1.0 → 1.3.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.
@@ -1,2 +1,2 @@
1
- import { CapitalizedKeys, ColorFn, CompareFn, Conjugated, Debrand, DeepPartial, DefaultMap$1 as DefaultMap, Dictionary, Direction, Exact, ExhaustiveSwitchCheck$1 as ExhaustiveSwitchCheck, Getter, NestedMap$1 as NestedMap, NonEmptyArray, Optional, Page, Prettify, Result$1 as Result, SerializedResult, Transformer, TypedError, TypedMapping$1 as TypedMapping, UncapitalizeObjectKeys, UncapitalizedKeys, UnionOmit, UnionPick, XOR, addAndSort$1 as addAndSort, assertArray$1 as assertArray, assertType$1 as assertType, blue$1 as blue, bold$1 as bold, booleanCode$1 as booleanCode, capitalize$1 as capitalize, capitalizeKeys$1 as capitalizeKeys, commentLines$1 as commentLines, compare$1 as compare, compareBooleans$1 as compareBooleans, compareDates$1 as compareDates, compareFields$1 as compareFields, compareNumbers$1 as compareNumbers, compareStrings$1 as compareStrings, compareValues$1 as compareValues, conjugateNames$1 as conjugateNames, cyan$1 as cyan, dictGetAndAssert$1 as dictGetAndAssert, ensureUnique$1 as ensureUnique, equals$1 as equals, err$1 as err, excelBigIntDecoder$1 as excelBigIntDecoder, excelBigIntNullableDecoder$1 as excelBigIntNullableDecoder, excelBigIntStrictDecoder$1 as excelBigIntStrictDecoder, excelBooleanDecoder$1 as excelBooleanDecoder, excelBooleanNullableDecoder$1 as excelBooleanNullableDecoder, excelBooleanStrictDecoder$1 as excelBooleanStrictDecoder, excelDateDecoder$1 as excelDateDecoder, excelDateNullableDecoder$1 as excelDateNullableDecoder, excelIntDecoder$1 as excelIntDecoder, excelIntNullableDecoder$1 as excelIntNullableDecoder, excelIntStrictDecoder$1 as excelIntStrictDecoder, excelNumberDecoder$1 as excelNumberDecoder, excelNumberNullableDecoder$1 as excelNumberNullableDecoder, excelNumberStrictDecoder$1 as excelNumberStrictDecoder, excelStringDecoder$1 as excelStringDecoder, excelStringNullableDecoder$1 as excelStringNullableDecoder, excelStringStrictDecoder$1 as excelStringStrictDecoder, filterDict$1 as filterDict, filterMap$1 as filterMap, format$1 as format, generateRandomAlphanumericString$1 as generateRandomAlphanumericString, gray$1 as gray, green$1 as green, groupBy$1 as groupBy, groupByCurried$1 as groupByCurried, groupByToDict$1 as groupByToDict, groupByToMap$1 as groupByToMap, idToDict$1 as idToDict, inverse$1 as inverse, isCamelCase$1 as isCamelCase, isDate$1 as isDate, isKebabCase$1 as isKebabCase, isPascalCase$1 as isPascalCase, isPlural$1 as isPlural, isSlug$1 as isSlug, isSnakeCase$1 as isSnakeCase, italic$1 as italic, keyGetter$1 as keyGetter, lowerFirst$1 as lowerFirst, mapDict$1 as mapDict, mapGetAndAssert$1 as mapGetAndAssert, mapLimit$1 as mapLimit, mapMap$1 as mapMap, mapMapKeyValues$1 as mapMapKeyValues, mapMapKeys$1 as mapMapKeys, mapMapValues$1 as mapMapValues, mapToDict$1 as mapToDict, ok$1 as ok, omit$1 as omit, pipeZodTransformers$1 as pipeZodTransformers, pluralize$1 as pluralize, randomInt$1 as randomInt, red$1 as red, removeSecrets$1 as removeSecrets, removeUndefinedProperties$1 as removeUndefinedProperties, setDirection$1 as setDirection, slice$1 as slice, slugify$1 as slugify, sort$1 as sort, timeStamp$1 as timeStamp, toCamelCase$1 as toCamelCase, toDict$1 as toDict, toExcelColumnName$1 as toExcelColumnName, toExcelTableName$1 as toExcelTableName, toHumanReadable$1 as toHumanReadable, toKebabCase$1 as toKebabCase, toPascalCase$1 as toPascalCase, toSnakeCase$1 as toSnakeCase, uncapitalize$1 as uncapitalize, uncapitalizeKeys$1 as uncapitalizeKeys, underline$1 as underline, unionErrorMessage$1 as unionErrorMessage, uniq$1 as uniq, upperFirst$1 as upperFirst, yellow$1 as yellow } from "./zod-excel.decoders-CGmBv5CD.js";
2
- export { CapitalizedKeys, ColorFn, CompareFn, Conjugated, Debrand, DeepPartial, DefaultMap, Dictionary, Direction, Exact, ExhaustiveSwitchCheck, Getter, NestedMap, NonEmptyArray, Optional, Page, Prettify, Result, SerializedResult, Transformer, TypedError, TypedMapping, UncapitalizeObjectKeys, UncapitalizedKeys, UnionOmit, UnionPick, XOR, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow };
1
+ import { CapitalizedKeys, ColorFn, CompareFn, Conjugated, Debrand, DeepPartial, DefaultMap$1 as DefaultMap, Dictionary, Direction, Exact, ExhaustiveSwitchCheck$1 as ExhaustiveSwitchCheck, Getter, NestedMap$1 as NestedMap, NonEmptyArray, Optional, Page, Prettify, Result$1 as Result, SerializedResult, Transformer, TypedError, TypedMapping$1 as TypedMapping, UncapitalizeObjectKeys, UncapitalizedKeys, UnionOmit, UnionPick, XOR, addAndSort$1 as addAndSort, assertArray$1 as assertArray, assertType$1 as assertType, blue$1 as blue, bold$1 as bold, booleanCode$1 as booleanCode, capitalize$1 as capitalize, capitalizeKeys$1 as capitalizeKeys, commentLines$1 as commentLines, compare$1 as compare, compareBooleans$1 as compareBooleans, compareDates$1 as compareDates, compareFields$1 as compareFields, compareNumbers$1 as compareNumbers, compareStrings$1 as compareStrings, compareValues$1 as compareValues, conjugateNames$1 as conjugateNames, cyan$1 as cyan, dictGetAndAssert$1 as dictGetAndAssert, ensureUnique$1 as ensureUnique, equals$1 as equals, err$1 as err, excelBigIntDecoder$1 as excelBigIntDecoder, excelBigIntNullableDecoder$1 as excelBigIntNullableDecoder, excelBigIntStrictDecoder$1 as excelBigIntStrictDecoder, excelBooleanDecoder$1 as excelBooleanDecoder, excelBooleanNullableDecoder$1 as excelBooleanNullableDecoder, excelBooleanStrictDecoder$1 as excelBooleanStrictDecoder, excelDateDecoder$1 as excelDateDecoder, excelDateNullableDecoder$1 as excelDateNullableDecoder, excelIntDecoder$1 as excelIntDecoder, excelIntNullableDecoder$1 as excelIntNullableDecoder, excelIntStrictDecoder$1 as excelIntStrictDecoder, excelNumberDecoder$1 as excelNumberDecoder, excelNumberNullableDecoder$1 as excelNumberNullableDecoder, excelNumberStrictDecoder$1 as excelNumberStrictDecoder, excelStringDecoder$1 as excelStringDecoder, excelStringNullableDecoder$1 as excelStringNullableDecoder, excelStringStrictDecoder$1 as excelStringStrictDecoder, filterDict$1 as filterDict, filterMap$1 as filterMap, format$1 as format, generateRandomAlphanumericString$1 as generateRandomAlphanumericString, gray$1 as gray, green$1 as green, groupBy$1 as groupBy, groupByCurried$1 as groupByCurried, groupByToDict$1 as groupByToDict, groupByToMap$1 as groupByToMap, idToDict$1 as idToDict, inverse$1 as inverse, isCamelCase$1 as isCamelCase, isDate$1 as isDate, isKebabCase$1 as isKebabCase, isPascalCase$1 as isPascalCase, isPlural$1 as isPlural, isSlug$1 as isSlug, isSnakeCase$1 as isSnakeCase, italic$1 as italic, keyGetter$1 as keyGetter, lowerFirst$1 as lowerFirst, mapDict$1 as mapDict, mapGetAndAssert$1 as mapGetAndAssert, mapLimit$1 as mapLimit, mapMap$1 as mapMap, mapMapKeyValues$1 as mapMapKeyValues, mapMapKeys$1 as mapMapKeys, mapMapValues$1 as mapMapValues, mapToDict$1 as mapToDict, netWorkDays$1 as netWorkDays, ok$1 as ok, omit$1 as omit, pipeZodTransformers$1 as pipeZodTransformers, pluralize$1 as pluralize, randomInt$1 as randomInt, red$1 as red, removeSecrets$1 as removeSecrets, removeUndefinedProperties$1 as removeUndefinedProperties, setDirection$1 as setDirection, slice$1 as slice, slugify$1 as slugify, sort$1 as sort, timeStamp$1 as timeStamp, toCamelCase$1 as toCamelCase, toDict$1 as toDict, toExcelColumnName$1 as toExcelColumnName, toExcelTableName$1 as toExcelTableName, toHumanReadable$1 as toHumanReadable, toKebabCase$1 as toKebabCase, toPascalCase$1 as toPascalCase, toSnakeCase$1 as toSnakeCase, uncapitalize$1 as uncapitalize, uncapitalizeKeys$1 as uncapitalizeKeys, underline$1 as underline, unionErrorMessage$1 as unionErrorMessage, uniq$1 as uniq, upperFirst$1 as upperFirst, yellow$1 as yellow } from "./zod-excel.decoders-CdwNiqIF.js";
2
+ export { CapitalizedKeys, ColorFn, CompareFn, Conjugated, Debrand, DeepPartial, DefaultMap, Dictionary, Direction, Exact, ExhaustiveSwitchCheck, Getter, NestedMap, NonEmptyArray, Optional, Page, Prettify, Result, SerializedResult, Transformer, TypedError, TypedMapping, UncapitalizeObjectKeys, UncapitalizedKeys, UnionOmit, UnionPick, XOR, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, netWorkDays, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow };
@@ -1,3 +1,3 @@
1
- import { DefaultMap, ExhaustiveSwitchCheck, NestedMap, Result, TypedMapping, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow } from "./zod-excel.decoders-BJliEI1Y.js";
1
+ import { DefaultMap, ExhaustiveSwitchCheck, NestedMap, Result, TypedMapping, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, netWorkDays, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow } from "./zod-excel.decoders-RJhEcAm0.js";
2
2
 
3
- export { DefaultMap, ExhaustiveSwitchCheck, NestedMap, Result, TypedMapping, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow };
3
+ export { DefaultMap, ExhaustiveSwitchCheck, NestedMap, Result, TypedMapping, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, netWorkDays, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CapitalizedKeys, ColorFn, CompareFn, Conjugated, Debrand, DeepPartial, DefaultMap$1 as DefaultMap, Dictionary, Direction, Exact, ExhaustiveSwitchCheck$1 as ExhaustiveSwitchCheck, Getter, NestedMap$1 as NestedMap, NonEmptyArray, Optional, Page, Prettify, Result$1 as Result, SerializedResult, Transformer, TypedError, TypedMapping$1 as TypedMapping, UncapitalizeObjectKeys, UncapitalizedKeys, UnionOmit, UnionPick, XOR, addAndSort$1 as addAndSort, assertArray$1 as assertArray, assertType$1 as assertType, blue$1 as blue, bold$1 as bold, booleanCode$1 as booleanCode, capitalize$1 as capitalize, capitalizeKeys$1 as capitalizeKeys, commentLines$1 as commentLines, compare$1 as compare, compareBooleans$1 as compareBooleans, compareDates$1 as compareDates, compareFields$1 as compareFields, compareNumbers$1 as compareNumbers, compareStrings$1 as compareStrings, compareValues$1 as compareValues, conjugateNames$1 as conjugateNames, cyan$1 as cyan, dictGetAndAssert$1 as dictGetAndAssert, ensureUnique$1 as ensureUnique, equals$1 as equals, err$1 as err, excelBigIntDecoder$1 as excelBigIntDecoder, excelBigIntNullableDecoder$1 as excelBigIntNullableDecoder, excelBigIntStrictDecoder$1 as excelBigIntStrictDecoder, excelBooleanDecoder$1 as excelBooleanDecoder, excelBooleanNullableDecoder$1 as excelBooleanNullableDecoder, excelBooleanStrictDecoder$1 as excelBooleanStrictDecoder, excelDateDecoder$1 as excelDateDecoder, excelDateNullableDecoder$1 as excelDateNullableDecoder, excelIntDecoder$1 as excelIntDecoder, excelIntNullableDecoder$1 as excelIntNullableDecoder, excelIntStrictDecoder$1 as excelIntStrictDecoder, excelNumberDecoder$1 as excelNumberDecoder, excelNumberNullableDecoder$1 as excelNumberNullableDecoder, excelNumberStrictDecoder$1 as excelNumberStrictDecoder, excelStringDecoder$1 as excelStringDecoder, excelStringNullableDecoder$1 as excelStringNullableDecoder, excelStringStrictDecoder$1 as excelStringStrictDecoder, filterDict$1 as filterDict, filterMap$1 as filterMap, format$1 as format, generateRandomAlphanumericString$1 as generateRandomAlphanumericString, gray$1 as gray, green$1 as green, groupBy$1 as groupBy, groupByCurried$1 as groupByCurried, groupByToDict$1 as groupByToDict, groupByToMap$1 as groupByToMap, idToDict$1 as idToDict, inverse$1 as inverse, isCamelCase$1 as isCamelCase, isDate$1 as isDate, isKebabCase$1 as isKebabCase, isPascalCase$1 as isPascalCase, isPlural$1 as isPlural, isSlug$1 as isSlug, isSnakeCase$1 as isSnakeCase, italic$1 as italic, keyGetter$1 as keyGetter, lowerFirst$1 as lowerFirst, mapDict$1 as mapDict, mapGetAndAssert$1 as mapGetAndAssert, mapLimit$1 as mapLimit, mapMap$1 as mapMap, mapMapKeyValues$1 as mapMapKeyValues, mapMapKeys$1 as mapMapKeys, mapMapValues$1 as mapMapValues, mapToDict$1 as mapToDict, ok$1 as ok, omit$1 as omit, pipeZodTransformers$1 as pipeZodTransformers, pluralize$1 as pluralize, randomInt$1 as randomInt, red$1 as red, removeSecrets$1 as removeSecrets, removeUndefinedProperties$1 as removeUndefinedProperties, setDirection$1 as setDirection, slice$1 as slice, slugify$1 as slugify, sort$1 as sort, timeStamp$1 as timeStamp, toCamelCase$1 as toCamelCase, toDict$1 as toDict, toExcelColumnName$1 as toExcelColumnName, toExcelTableName$1 as toExcelTableName, toHumanReadable$1 as toHumanReadable, toKebabCase$1 as toKebabCase, toPascalCase$1 as toPascalCase, toSnakeCase$1 as toSnakeCase, uncapitalize$1 as uncapitalize, uncapitalizeKeys$1 as uncapitalizeKeys, underline$1 as underline, unionErrorMessage$1 as unionErrorMessage, uniq$1 as uniq, upperFirst$1 as upperFirst, yellow$1 as yellow } from "./zod-excel.decoders-CGmBv5CD.js";
1
+ import { CapitalizedKeys, ColorFn, CompareFn, Conjugated, Debrand, DeepPartial, DefaultMap$1 as DefaultMap, Dictionary, Direction, Exact, ExhaustiveSwitchCheck$1 as ExhaustiveSwitchCheck, Getter, NestedMap$1 as NestedMap, NonEmptyArray, Optional, Page, Prettify, Result$1 as Result, SerializedResult, Transformer, TypedError, TypedMapping$1 as TypedMapping, UncapitalizeObjectKeys, UncapitalizedKeys, UnionOmit, UnionPick, XOR, addAndSort$1 as addAndSort, assertArray$1 as assertArray, assertType$1 as assertType, blue$1 as blue, bold$1 as bold, booleanCode$1 as booleanCode, capitalize$1 as capitalize, capitalizeKeys$1 as capitalizeKeys, commentLines$1 as commentLines, compare$1 as compare, compareBooleans$1 as compareBooleans, compareDates$1 as compareDates, compareFields$1 as compareFields, compareNumbers$1 as compareNumbers, compareStrings$1 as compareStrings, compareValues$1 as compareValues, conjugateNames$1 as conjugateNames, cyan$1 as cyan, dictGetAndAssert$1 as dictGetAndAssert, ensureUnique$1 as ensureUnique, equals$1 as equals, err$1 as err, excelBigIntDecoder$1 as excelBigIntDecoder, excelBigIntNullableDecoder$1 as excelBigIntNullableDecoder, excelBigIntStrictDecoder$1 as excelBigIntStrictDecoder, excelBooleanDecoder$1 as excelBooleanDecoder, excelBooleanNullableDecoder$1 as excelBooleanNullableDecoder, excelBooleanStrictDecoder$1 as excelBooleanStrictDecoder, excelDateDecoder$1 as excelDateDecoder, excelDateNullableDecoder$1 as excelDateNullableDecoder, excelIntDecoder$1 as excelIntDecoder, excelIntNullableDecoder$1 as excelIntNullableDecoder, excelIntStrictDecoder$1 as excelIntStrictDecoder, excelNumberDecoder$1 as excelNumberDecoder, excelNumberNullableDecoder$1 as excelNumberNullableDecoder, excelNumberStrictDecoder$1 as excelNumberStrictDecoder, excelStringDecoder$1 as excelStringDecoder, excelStringNullableDecoder$1 as excelStringNullableDecoder, excelStringStrictDecoder$1 as excelStringStrictDecoder, filterDict$1 as filterDict, filterMap$1 as filterMap, format$1 as format, generateRandomAlphanumericString$1 as generateRandomAlphanumericString, gray$1 as gray, green$1 as green, groupBy$1 as groupBy, groupByCurried$1 as groupByCurried, groupByToDict$1 as groupByToDict, groupByToMap$1 as groupByToMap, idToDict$1 as idToDict, inverse$1 as inverse, isCamelCase$1 as isCamelCase, isDate$1 as isDate, isKebabCase$1 as isKebabCase, isPascalCase$1 as isPascalCase, isPlural$1 as isPlural, isSlug$1 as isSlug, isSnakeCase$1 as isSnakeCase, italic$1 as italic, keyGetter$1 as keyGetter, lowerFirst$1 as lowerFirst, mapDict$1 as mapDict, mapGetAndAssert$1 as mapGetAndAssert, mapLimit$1 as mapLimit, mapMap$1 as mapMap, mapMapKeyValues$1 as mapMapKeyValues, mapMapKeys$1 as mapMapKeys, mapMapValues$1 as mapMapValues, mapToDict$1 as mapToDict, netWorkDays$1 as netWorkDays, ok$1 as ok, omit$1 as omit, pipeZodTransformers$1 as pipeZodTransformers, pluralize$1 as pluralize, randomInt$1 as randomInt, red$1 as red, removeSecrets$1 as removeSecrets, removeUndefinedProperties$1 as removeUndefinedProperties, setDirection$1 as setDirection, slice$1 as slice, slugify$1 as slugify, sort$1 as sort, timeStamp$1 as timeStamp, toCamelCase$1 as toCamelCase, toDict$1 as toDict, toExcelColumnName$1 as toExcelColumnName, toExcelTableName$1 as toExcelTableName, toHumanReadable$1 as toHumanReadable, toKebabCase$1 as toKebabCase, toPascalCase$1 as toPascalCase, toSnakeCase$1 as toSnakeCase, uncapitalize$1 as uncapitalize, uncapitalizeKeys$1 as uncapitalizeKeys, underline$1 as underline, unionErrorMessage$1 as unionErrorMessage, uniq$1 as uniq, upperFirst$1 as upperFirst, yellow$1 as yellow } from "./zod-excel.decoders-CdwNiqIF.js";
2
2
 
3
3
  //#region src/check-port.d.ts
4
4
  /**
@@ -19,5 +19,5 @@ declare function checkPortAvailability(port: number, host?: string): Promise<boo
19
19
  declare const checkPort: typeof checkPortAvailability;
20
20
 
21
21
  //#endregion
22
- export { CapitalizedKeys, ColorFn, CompareFn, Conjugated, Debrand, DeepPartial, DefaultMap, Dictionary, Direction, Exact, ExhaustiveSwitchCheck, Getter, NestedMap, NonEmptyArray, Optional, Page, Prettify, Result, SerializedResult, Transformer, TypedError, TypedMapping, UncapitalizeObjectKeys, UncapitalizedKeys, UnionOmit, UnionPick, XOR, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, checkPort, checkPortAvailability, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow };
22
+ export { CapitalizedKeys, ColorFn, CompareFn, Conjugated, Debrand, DeepPartial, DefaultMap, Dictionary, Direction, Exact, ExhaustiveSwitchCheck, Getter, NestedMap, NonEmptyArray, Optional, Page, Prettify, Result, SerializedResult, Transformer, TypedError, TypedMapping, UncapitalizeObjectKeys, UncapitalizedKeys, UnionOmit, UnionPick, XOR, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, checkPort, checkPortAvailability, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, netWorkDays, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow };
23
23
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { DefaultMap, ExhaustiveSwitchCheck, NestedMap, Result, TypedMapping, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow } from "./zod-excel.decoders-BJliEI1Y.js";
1
+ import { DefaultMap, ExhaustiveSwitchCheck, NestedMap, Result, TypedMapping, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, netWorkDays, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow } from "./zod-excel.decoders-RJhEcAm0.js";
2
2
 
3
3
  //#region src/check-port.ts
4
4
  /**
@@ -33,5 +33,5 @@ async function checkPortAvailability(port, host = "127.0.0.1") {
33
33
  const checkPort = checkPortAvailability;
34
34
 
35
35
  //#endregion
36
- export { DefaultMap, ExhaustiveSwitchCheck, NestedMap, Result, TypedMapping, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, checkPort, checkPortAvailability, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow };
36
+ export { DefaultMap, ExhaustiveSwitchCheck, NestedMap, Result, TypedMapping, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, checkPort, checkPortAvailability, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, netWorkDays, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow };
37
37
  //# sourceMappingURL=index.js.map
@@ -112,6 +112,48 @@ declare function timeStamp(): string;
112
112
  * isDate(undefined) // false
113
113
  */
114
114
  declare function isDate(value: unknown): value is Date;
115
+ /**
116
+ * Calculates the number of working days between two dates, excluding weekends
117
+ * and optionally excluding specified holidays. Similar to Excel's NETWORKDAYS function.
118
+ *
119
+ * Working days are Monday through Friday. Both the start date and end date are
120
+ * included in the count if they are working days.
121
+ *
122
+ * The function uses UTC-based date comparisons to ensure consistent behavior
123
+ * across different timezones.
124
+ *
125
+ * @param startDate - The start date of the period
126
+ * @param endDate - The end date of the period
127
+ * @param holidays - Optional array of dates to exclude as holidays
128
+ * @returns The number of working days between the dates (inclusive).
129
+ * Returns a negative number if endDate is before startDate.
130
+ * Returns 0 if either date is invalid.
131
+ *
132
+ * @example
133
+ * // Count working days in a week (Monday to Friday)
134
+ * netWorkDays(new Date('2024-01-08'), new Date('2024-01-12')) // 5
135
+ *
136
+ * @example
137
+ * // Same day that is a working day
138
+ * netWorkDays(new Date('2024-01-08'), new Date('2024-01-08')) // 1
139
+ *
140
+ * @example
141
+ * // Same day that is a weekend
142
+ * netWorkDays(new Date('2024-01-06'), new Date('2024-01-06')) // 0 (Saturday)
143
+ *
144
+ * @example
145
+ * // With holidays
146
+ * netWorkDays(
147
+ * new Date('2024-01-08'),
148
+ * new Date('2024-01-12'),
149
+ * [new Date('2024-01-10')] // Wednesday is a holiday
150
+ * ) // 4
151
+ *
152
+ * @example
153
+ * // End date before start date (returns negative)
154
+ * netWorkDays(new Date('2024-01-12'), new Date('2024-01-08')) // -5
155
+ */
156
+ declare function netWorkDays(startDate: Date, endDate: Date, holidays?: Date[]): number;
115
157
 
116
158
  //#endregion
117
159
  //#region src/dictionary.d.ts
@@ -584,7 +626,7 @@ type ReturnTypeOfLast<T extends any[]> = T extends [...any, infer L] ? L extends
584
626
  */
585
627
  declare function pipeZodTransformers<Initial, Fns extends [Transformer<any, any>, ...Transformer<any, any>[]]>(initialValue: Initial, ctx: z.RefinementCtx, fns: Fns): ReturnTypeOfLast<Fns>;
586
628
  /**
587
- * Returns a Zod error map that returns the given message for union errors.
629
+ * Returns a Zod error callback that returns the given message for union errors.
588
630
  *
589
631
  * This is useful for generating meaningful error messages for unions, e.g.
590
632
  * ```
@@ -603,7 +645,9 @@ declare function pipeZodTransformers<Initial, Fns extends [Transformer<any, any>
603
645
  * )
604
646
  * ```
605
647
  */
606
- declare function unionErrorMessage(param: string | ((data: any) => string)): z.RawCreateParams;
648
+ declare function unionErrorMessage(param: string | ((data: unknown) => string)): {
649
+ error: (issue: any) => string;
650
+ };
607
651
 
608
652
  //#endregion
609
653
  //#region src/zod-excel.decoders.d.ts
@@ -621,7 +665,7 @@ declare function unionErrorMessage(param: string | ((data: any) => string)): z.R
621
665
  *
622
666
  * Any other type will throw an error!
623
667
  */
624
- declare const excelStringStrictDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean]>, string, string | number | boolean>;
668
+ declare const excelStringStrictDecoder: z$1.ZodPipe<z$1.ZodUnion<readonly [z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean]>, z$1.ZodTransform<string, string | number | boolean>>;
625
669
  /**
626
670
  * A decoder that transforms Excel strings to JS strings, also handling numbers and any other potential type
627
671
  *
@@ -638,7 +682,7 @@ declare const excelStringStrictDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodStri
638
682
  *
639
683
  * Null handling: Null values/blank cells will be converted to a blank string.
640
684
  */
641
- declare const excelStringDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean, z$1.ZodNull, z$1.ZodUndefined, z$1.ZodAny]>, string, any>;
685
+ declare const excelStringDecoder: z$1.ZodPipe<z$1.ZodTransform<string, unknown>, z$1.ZodString>;
642
686
  /**
643
687
  * A decoder that transforms Excel strings to JS strings, also handling numbers and null
644
688
  *
@@ -656,7 +700,7 @@ declare const excelStringDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$
656
700
  * Null handling: Blank strings will be converted to null. This is to reflect that in Excel a formula
657
701
  * cannot return null. As a workaround, one often returns a blank string to represent null.
658
702
  */
659
- declare const excelStringNullableDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean, z$1.ZodNull, z$1.ZodUndefined, z$1.ZodAny]>, string | null, any>;
703
+ declare const excelStringNullableDecoder: z$1.ZodPipe<z$1.ZodTransform<string | null, unknown>, z$1.ZodNullable<z$1.ZodString>>;
660
704
  /**
661
705
  * A decoder that transforms Excel numbers to JS numbers, also handling strings and boolean. Will not parse any other type!
662
706
  *
@@ -667,7 +711,7 @@ declare const excelStringNullableDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodSt
667
711
  * - If the value is any other type, it'll throw an error
668
712
  *
669
713
  */
670
- declare const excelNumberStrictDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean]>, number, string | number | boolean>;
714
+ declare const excelNumberStrictDecoder: z$1.ZodPipe<z$1.ZodUnion<readonly [z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean]>, z$1.ZodTransform<number, string | number | boolean>>;
671
715
  /**
672
716
  * A decoder that transforms Excel numbers to JS numbers, also handling strings, boolean and other types.
673
717
  *
@@ -679,10 +723,10 @@ declare const excelNumberStrictDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodStri
679
723
  *
680
724
  * Null handling: Null values/blank cells will be converted to blank strings.
681
725
  */
682
- declare const excelNumberDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean, z$1.ZodNull, z$1.ZodUndefined, z$1.ZodAny]>, number, any>;
726
+ declare const excelNumberDecoder: z$1.ZodPipe<z$1.ZodTransform<number, unknown>, z$1.ZodNumber>;
683
727
  /**
684
728
  * A decoder that transforms Excel numbers to JS numbers, also handling strings, boolean and other types.
685
-
729
+
686
730
  * It'll perform casting based on the following rules:
687
731
  * - If the value is a number, it'll be returned as-is
688
732
  * - If the value is a string, it'll try to parse it to a number. Non-numerical and blank strings will be converted to null
@@ -692,43 +736,43 @@ declare const excelNumberDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$
692
736
  * Null handling: Blank strings will be converted to null. This is to reflect that in Excel a formula
693
737
  * cannot return null. As a workaround, one often returns a blank string to represent null.
694
738
  */
695
- declare const excelNumberNullableDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNull, z$1.ZodNumber, z$1.ZodUndefined, z$1.ZodAny]>, number | null, any>;
739
+ declare const excelNumberNullableDecoder: z$1.ZodPipe<z$1.ZodTransform<number | null, any>, z$1.ZodNullable<z$1.ZodNumber>>;
696
740
  /**
697
741
  * A decoder that transforms Excel numbers to JS integers, also handling strings and boolean. Other types will throw an error.
698
742
  *
699
743
  * If the number is not an integer, an error will be thrown.
700
744
  */
701
- declare const excelIntStrictDecoder: z$1.ZodEffects<z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean]>, number, string | number | boolean>, number, string | number | boolean>;
745
+ declare const excelIntStrictDecoder: z$1.ZodPipe<z$1.ZodPipe<z$1.ZodUnion<readonly [z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean]>, z$1.ZodTransform<number, string | number | boolean>>, z$1.ZodTransform<number, number>>;
702
746
  /**
703
747
  * A decoder that transforms Excel numbers to JS integers, also handling strings and boolean. Other types will be converted to 0.
704
748
  *
705
749
  * If the number is not an integer, an error will be thrown.
706
750
  */
707
- declare const excelIntDecoder: z$1.ZodEffects<z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean, z$1.ZodNull, z$1.ZodUndefined, z$1.ZodAny]>, number, any>, number, any>;
751
+ declare const excelIntDecoder: z$1.ZodPipe<z$1.ZodPipe<z$1.ZodTransform<number, unknown>, z$1.ZodNumber>, z$1.ZodTransform<number, number>>;
708
752
  /**
709
753
  * A decoder that transforms Excel numbers to JS integers, also handling strings and boolean. Other types will be converted to null.
710
754
  *
711
755
  * If the number is not an integer, an error will be thrown.
712
756
  */
713
- declare const excelIntNullableDecoder: z$1.ZodEffects<z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNull, z$1.ZodNumber, z$1.ZodUndefined, z$1.ZodAny]>, number | null, any>, number | null, any>;
757
+ declare const excelIntNullableDecoder: z$1.ZodPipe<z$1.ZodPipe<z$1.ZodTransform<number | null, any>, z$1.ZodNullable<z$1.ZodNumber>>, z$1.ZodTransform<number | null, number | null>>;
714
758
  /**
715
759
  * A decoder that transforms Excel numbers to JS BigInts, also handling strings and boolean. Other types will throw an error.
716
760
  *
717
761
  * If the number is not a (big) integer, an error will be thrown.
718
762
  */
719
- declare const excelBigIntStrictDecoder: z$1.ZodEffects<z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean]>, number, string | number | boolean>, bigint, string | number | boolean>;
763
+ declare const excelBigIntStrictDecoder: z$1.ZodPipe<z$1.ZodPipe<z$1.ZodUnion<readonly [z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean]>, z$1.ZodTransform<number, string | number | boolean>>, z$1.ZodTransform<bigint, number>>;
720
764
  /**
721
765
  * A decoder that transforms Excel numbers to JS BigInts, also handling strings and boolean. Other types will be converted to 0.
722
766
  *
723
767
  * If the number is not a (big) integer, an error will be thrown.
724
768
  */
725
- declare const excelBigIntDecoder: z$1.ZodEffects<z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNumber, z$1.ZodBoolean, z$1.ZodNull, z$1.ZodUndefined, z$1.ZodAny]>, number, any>, bigint, any>;
769
+ declare const excelBigIntDecoder: z$1.ZodPipe<z$1.ZodPipe<z$1.ZodTransform<number, unknown>, z$1.ZodNumber>, z$1.ZodTransform<bigint, number>>;
726
770
  /**
727
771
  * A decoder that transforms Excel numbers to JS BigInts, also handling strings and boolean. Other types will be converted to null.
728
772
  *
729
773
  * If the number is not a (big) integer, an error will be thrown.
730
774
  */
731
- declare const excelBigIntNullableDecoder: z$1.ZodEffects<z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodString, z$1.ZodNull, z$1.ZodNumber, z$1.ZodUndefined, z$1.ZodAny]>, number | null, any>, bigint | null, any>;
775
+ declare const excelBigIntNullableDecoder: z$1.ZodPipe<z$1.ZodPipe<z$1.ZodTransform<number | null, any>, z$1.ZodNullable<z$1.ZodNumber>>, z$1.ZodTransform<bigint | null, number | null>>;
732
776
  /**
733
777
  * A decoder that transforms Excel booleans to JS booleans, also handling numbers and strings.
734
778
  *
@@ -738,7 +782,7 @@ declare const excelBigIntNullableDecoder: z$1.ZodEffects<z$1.ZodEffects<z$1.ZodU
738
782
  * - If the value is boolean, it'll return it as-is
739
783
  * - If the value is any other type, it'll throw an error
740
784
  */
741
- declare const excelBooleanStrictDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodBoolean, z$1.ZodNumber, z$1.ZodString]>, boolean, string | number | boolean>;
785
+ declare const excelBooleanStrictDecoder: z$1.ZodPipe<z$1.ZodUnion<readonly [z$1.ZodBoolean, z$1.ZodNumber, z$1.ZodString]>, z$1.ZodTransform<boolean, string | number | boolean>>;
742
786
  /**
743
787
  * A decoder that transforms Excel booleans to JS booleans, also handling numbers and strings.
744
788
  *
@@ -748,7 +792,7 @@ declare const excelBooleanStrictDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodBoo
748
792
  * - If the value is boolean, it'll return it as-is
749
793
  * - If the value is any other type, it'll return false
750
794
  */
751
- declare const excelBooleanDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodBoolean, z$1.ZodNumber, z$1.ZodNull, z$1.ZodString, z$1.ZodUndefined, z$1.ZodAny]>, boolean, any>;
795
+ declare const excelBooleanDecoder: z$1.ZodPipe<z$1.ZodTransform<boolean, unknown>, z$1.ZodBoolean>;
752
796
  /**
753
797
  * A decoder that transforms Excel booleans to JS booleans, also handling numbers and strings.
754
798
  *
@@ -758,16 +802,16 @@ declare const excelBooleanDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodBoolean,
758
802
  * - If the value is boolean, it'll return it as-is
759
803
  * - If the value is any other type, it'll return null
760
804
  */
761
- declare const excelBooleanNullableDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodBoolean, z$1.ZodNumber, z$1.ZodNull, z$1.ZodString, z$1.ZodUndefined, z$1.ZodAny]>, boolean | null, any>;
805
+ declare const excelBooleanNullableDecoder: z$1.ZodPipe<z$1.ZodTransform<boolean | null, any>, z$1.ZodNullable<z$1.ZodBoolean>>;
762
806
  /**
763
807
  * A decoder that transforms Excel dates to JS Dates
764
808
  */
765
- declare const excelDateDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodDate, z$1.ZodNumber, z$1.ZodString]>, Date, string | number | Date>;
809
+ declare const excelDateDecoder: z$1.ZodPipe<z$1.ZodUnion<readonly [z$1.ZodDate, z$1.ZodNumber, z$1.ZodString]>, z$1.ZodTransform<Date, string | number | Date>>;
766
810
  /**
767
811
  * A decoder that transforms nullable Excel dates to JS Dates
768
812
  */
769
- declare const excelDateNullableDecoder: z$1.ZodEffects<z$1.ZodUnion<[z$1.ZodDate, z$1.ZodString, z$1.ZodNumber, z$1.ZodNull, z$1.ZodUndefined, z$1.ZodAny]>, Date | null, any>;
813
+ declare const excelDateNullableDecoder: z$1.ZodPipe<z$1.ZodTransform<Date | null, unknown>, z$1.ZodNullable<z$1.ZodDate>>;
770
814
 
771
815
  //#endregion
772
- export { CapitalizedKeys, ColorFn, CompareFn, Conjugated, Debrand, DeepPartial, DefaultMap as DefaultMap$1, Dictionary, Direction, Exact, ExhaustiveSwitchCheck as ExhaustiveSwitchCheck$1, Getter, NestedMap as NestedMap$1, NonEmptyArray, Optional, Page, Prettify, Result as Result$1, SerializedResult, Transformer, TypedError, TypedMapping as TypedMapping$1, UncapitalizeObjectKeys, UncapitalizedKeys, UnionOmit, UnionPick, XOR, addAndSort as addAndSort$1, assertArray as assertArray$1, assertType as assertType$1, blue as blue$1, bold as bold$1, booleanCode as booleanCode$1, capitalize as capitalize$1, capitalizeKeys as capitalizeKeys$1, commentLines as commentLines$1, compare as compare$1, compareBooleans as compareBooleans$1, compareDates as compareDates$1, compareFields as compareFields$1, compareNumbers as compareNumbers$1, compareStrings as compareStrings$1, compareValues as compareValues$1, conjugateNames as conjugateNames$1, cyan as cyan$1, dictGetAndAssert as dictGetAndAssert$1, ensureUnique as ensureUnique$1, equals as equals$1, err as err$1, excelBigIntDecoder as excelBigIntDecoder$1, excelBigIntNullableDecoder as excelBigIntNullableDecoder$1, excelBigIntStrictDecoder as excelBigIntStrictDecoder$1, excelBooleanDecoder as excelBooleanDecoder$1, excelBooleanNullableDecoder as excelBooleanNullableDecoder$1, excelBooleanStrictDecoder as excelBooleanStrictDecoder$1, excelDateDecoder as excelDateDecoder$1, excelDateNullableDecoder as excelDateNullableDecoder$1, excelIntDecoder as excelIntDecoder$1, excelIntNullableDecoder as excelIntNullableDecoder$1, excelIntStrictDecoder as excelIntStrictDecoder$1, excelNumberDecoder as excelNumberDecoder$1, excelNumberNullableDecoder as excelNumberNullableDecoder$1, excelNumberStrictDecoder as excelNumberStrictDecoder$1, excelStringDecoder as excelStringDecoder$1, excelStringNullableDecoder as excelStringNullableDecoder$1, excelStringStrictDecoder as excelStringStrictDecoder$1, filterDict as filterDict$1, filterMap as filterMap$1, format as format$1, generateRandomAlphanumericString as generateRandomAlphanumericString$1, gray as gray$1, green as green$1, groupBy as groupBy$1, groupByCurried as groupByCurried$1, groupByToDict as groupByToDict$1, groupByToMap as groupByToMap$1, idToDict as idToDict$1, inverse as inverse$1, isCamelCase as isCamelCase$1, isDate as isDate$1, isKebabCase as isKebabCase$1, isPascalCase as isPascalCase$1, isPlural as isPlural$1, isSlug as isSlug$1, isSnakeCase as isSnakeCase$1, italic as italic$1, keyGetter as keyGetter$1, lowerFirst as lowerFirst$1, mapDict as mapDict$1, mapGetAndAssert as mapGetAndAssert$1, mapLimit as mapLimit$1, mapMap as mapMap$1, mapMapKeyValues as mapMapKeyValues$1, mapMapKeys as mapMapKeys$1, mapMapValues as mapMapValues$1, mapToDict as mapToDict$1, ok as ok$1, omit as omit$1, pipeZodTransformers as pipeZodTransformers$1, pluralize as pluralize$1, randomInt as randomInt$1, red as red$1, removeSecrets as removeSecrets$1, removeUndefinedProperties as removeUndefinedProperties$1, setDirection as setDirection$1, slice as slice$1, slugify as slugify$1, sort as sort$1, timeStamp as timeStamp$1, toCamelCase as toCamelCase$1, toDict as toDict$1, toExcelColumnName as toExcelColumnName$1, toExcelTableName as toExcelTableName$1, toHumanReadable as toHumanReadable$1, toKebabCase as toKebabCase$1, toPascalCase as toPascalCase$1, toSnakeCase as toSnakeCase$1, uncapitalize as uncapitalize$1, uncapitalizeKeys as uncapitalizeKeys$1, underline as underline$1, unionErrorMessage as unionErrorMessage$1, uniq as uniq$1, upperFirst as upperFirst$1, yellow as yellow$1 };
773
- //# sourceMappingURL=zod-excel.decoders-CGmBv5CD.d.ts.map
816
+ export { CapitalizedKeys, ColorFn, CompareFn, Conjugated, Debrand, DeepPartial, DefaultMap as DefaultMap$1, Dictionary, Direction, Exact, ExhaustiveSwitchCheck as ExhaustiveSwitchCheck$1, Getter, NestedMap as NestedMap$1, NonEmptyArray, Optional, Page, Prettify, Result as Result$1, SerializedResult, Transformer, TypedError, TypedMapping as TypedMapping$1, UncapitalizeObjectKeys, UncapitalizedKeys, UnionOmit, UnionPick, XOR, addAndSort as addAndSort$1, assertArray as assertArray$1, assertType as assertType$1, blue as blue$1, bold as bold$1, booleanCode as booleanCode$1, capitalize as capitalize$1, capitalizeKeys as capitalizeKeys$1, commentLines as commentLines$1, compare as compare$1, compareBooleans as compareBooleans$1, compareDates as compareDates$1, compareFields as compareFields$1, compareNumbers as compareNumbers$1, compareStrings as compareStrings$1, compareValues as compareValues$1, conjugateNames as conjugateNames$1, cyan as cyan$1, dictGetAndAssert as dictGetAndAssert$1, ensureUnique as ensureUnique$1, equals as equals$1, err as err$1, excelBigIntDecoder as excelBigIntDecoder$1, excelBigIntNullableDecoder as excelBigIntNullableDecoder$1, excelBigIntStrictDecoder as excelBigIntStrictDecoder$1, excelBooleanDecoder as excelBooleanDecoder$1, excelBooleanNullableDecoder as excelBooleanNullableDecoder$1, excelBooleanStrictDecoder as excelBooleanStrictDecoder$1, excelDateDecoder as excelDateDecoder$1, excelDateNullableDecoder as excelDateNullableDecoder$1, excelIntDecoder as excelIntDecoder$1, excelIntNullableDecoder as excelIntNullableDecoder$1, excelIntStrictDecoder as excelIntStrictDecoder$1, excelNumberDecoder as excelNumberDecoder$1, excelNumberNullableDecoder as excelNumberNullableDecoder$1, excelNumberStrictDecoder as excelNumberStrictDecoder$1, excelStringDecoder as excelStringDecoder$1, excelStringNullableDecoder as excelStringNullableDecoder$1, excelStringStrictDecoder as excelStringStrictDecoder$1, filterDict as filterDict$1, filterMap as filterMap$1, format as format$1, generateRandomAlphanumericString as generateRandomAlphanumericString$1, gray as gray$1, green as green$1, groupBy as groupBy$1, groupByCurried as groupByCurried$1, groupByToDict as groupByToDict$1, groupByToMap as groupByToMap$1, idToDict as idToDict$1, inverse as inverse$1, isCamelCase as isCamelCase$1, isDate as isDate$1, isKebabCase as isKebabCase$1, isPascalCase as isPascalCase$1, isPlural as isPlural$1, isSlug as isSlug$1, isSnakeCase as isSnakeCase$1, italic as italic$1, keyGetter as keyGetter$1, lowerFirst as lowerFirst$1, mapDict as mapDict$1, mapGetAndAssert as mapGetAndAssert$1, mapLimit as mapLimit$1, mapMap as mapMap$1, mapMapKeyValues as mapMapKeyValues$1, mapMapKeys as mapMapKeys$1, mapMapValues as mapMapValues$1, mapToDict as mapToDict$1, netWorkDays as netWorkDays$1, ok as ok$1, omit as omit$1, pipeZodTransformers as pipeZodTransformers$1, pluralize as pluralize$1, randomInt as randomInt$1, red as red$1, removeSecrets as removeSecrets$1, removeUndefinedProperties as removeUndefinedProperties$1, setDirection as setDirection$1, slice as slice$1, slugify as slugify$1, sort as sort$1, timeStamp as timeStamp$1, toCamelCase as toCamelCase$1, toDict as toDict$1, toExcelColumnName as toExcelColumnName$1, toExcelTableName as toExcelTableName$1, toHumanReadable as toHumanReadable$1, toKebabCase as toKebabCase$1, toPascalCase as toPascalCase$1, toSnakeCase as toSnakeCase$1, uncapitalize as uncapitalize$1, uncapitalizeKeys as uncapitalizeKeys$1, underline as underline$1, unionErrorMessage as unionErrorMessage$1, uniq as uniq$1, upperFirst as upperFirst$1, yellow as yellow$1 };
817
+ //# sourceMappingURL=zod-excel.decoders-CdwNiqIF.d.ts.map
@@ -173,6 +173,10 @@ function equals(a, b) {
173
173
  //#endregion
174
174
  //#region src/datetime.ts
175
175
  /**
176
+ * Milliseconds in one day (24 hours × 60 minutes × 60 seconds × 1000 milliseconds)
177
+ */
178
+ const MS_PER_DAY = 864e5;
179
+ /**
176
180
  * returns the default time stamp in format YYMMDD HHMM
177
181
  */
178
182
  function timeStamp() {
@@ -204,6 +208,102 @@ function timeStamp() {
204
208
  function isDate(value) {
205
209
  return value instanceof Date && !Number.isNaN(value.getTime());
206
210
  }
211
+ /**
212
+ * Converts a Date to a normalized date string (YYYY-MM-DD) based on UTC.
213
+ * This is used for consistent date comparisons across timezones.
214
+ *
215
+ * The function extracts the date portion from the ISO 8601 format:
216
+ * - Input: "2024-01-15T12:34:56.789Z" (ISO string)
217
+ * - Output: "2024-01-15" (first 10 characters: YYYY-MM-DD)
218
+ */
219
+ function toDateKey(date) {
220
+ return date.toISOString().slice(0, 10);
221
+ }
222
+ /**
223
+ * Checks if a given date falls on a weekend (Saturday or Sunday) using UTC.
224
+ */
225
+ function isWeekend(date) {
226
+ const day = date.getUTCDay();
227
+ return day === 0 || day === 6;
228
+ }
229
+ /**
230
+ * Creates a new Date representing the start of the UTC day for a given date.
231
+ * This normalizes dates to avoid timezone and time-of-day issues.
232
+ */
233
+ function toUTCDate(date) {
234
+ return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
235
+ }
236
+ /**
237
+ * Calculates the number of working days between two dates, excluding weekends
238
+ * and optionally excluding specified holidays. Similar to Excel's NETWORKDAYS function.
239
+ *
240
+ * Working days are Monday through Friday. Both the start date and end date are
241
+ * included in the count if they are working days.
242
+ *
243
+ * The function uses UTC-based date comparisons to ensure consistent behavior
244
+ * across different timezones.
245
+ *
246
+ * @param startDate - The start date of the period
247
+ * @param endDate - The end date of the period
248
+ * @param holidays - Optional array of dates to exclude as holidays
249
+ * @returns The number of working days between the dates (inclusive).
250
+ * Returns a negative number if endDate is before startDate.
251
+ * Returns 0 if either date is invalid.
252
+ *
253
+ * @example
254
+ * // Count working days in a week (Monday to Friday)
255
+ * netWorkDays(new Date('2024-01-08'), new Date('2024-01-12')) // 5
256
+ *
257
+ * @example
258
+ * // Same day that is a working day
259
+ * netWorkDays(new Date('2024-01-08'), new Date('2024-01-08')) // 1
260
+ *
261
+ * @example
262
+ * // Same day that is a weekend
263
+ * netWorkDays(new Date('2024-01-06'), new Date('2024-01-06')) // 0 (Saturday)
264
+ *
265
+ * @example
266
+ * // With holidays
267
+ * netWorkDays(
268
+ * new Date('2024-01-08'),
269
+ * new Date('2024-01-12'),
270
+ * [new Date('2024-01-10')] // Wednesday is a holiday
271
+ * ) // 4
272
+ *
273
+ * @example
274
+ * // End date before start date (returns negative)
275
+ * netWorkDays(new Date('2024-01-12'), new Date('2024-01-08')) // -5
276
+ */
277
+ function netWorkDays(startDate, endDate, holidays = []) {
278
+ if (!isDate(startDate) || !isDate(endDate)) return 0;
279
+ const normalizedStart = toUTCDate(startDate);
280
+ const normalizedEnd = toUTCDate(endDate);
281
+ const isReversed = normalizedStart > normalizedEnd;
282
+ const [from, to] = isReversed ? [normalizedEnd, normalizedStart] : [normalizedStart, normalizedEnd];
283
+ const totalDays = Math.floor((to.getTime() - from.getTime()) / MS_PER_DAY) + 1;
284
+ const startDay = from.getUTCDay();
285
+ const fullWeeks = Math.floor(totalDays / 7);
286
+ const remainingDays = totalDays % 7;
287
+ let weekendDays = fullWeeks * 2;
288
+ for (let i = 0; i < remainingDays; i++) {
289
+ const dayOfWeek = (startDay + i) % 7;
290
+ if (dayOfWeek === 0 || dayOfWeek === 6) weekendDays++;
291
+ }
292
+ let workDays = totalDays - weekendDays;
293
+ const fromKey = toDateKey(from);
294
+ const toKey = toDateKey(to);
295
+ const countedHolidays = new Set();
296
+ for (const holiday of holidays) {
297
+ if (!isDate(holiday)) continue;
298
+ const normalizedHoliday = toUTCDate(holiday);
299
+ const holidayKey = toDateKey(normalizedHoliday);
300
+ if (holidayKey >= fromKey && holidayKey <= toKey && !isWeekend(normalizedHoliday) && !countedHolidays.has(holidayKey)) {
301
+ countedHolidays.add(holidayKey);
302
+ workDays--;
303
+ }
304
+ }
305
+ return isReversed ? -workDays : workDays;
306
+ }
207
307
 
208
308
  //#endregion
209
309
  //#region src/dictionary.ts
@@ -1024,12 +1124,12 @@ function pipeZodTransformers(initialValue, ctx, fns) {
1024
1124
  let result = initialValue;
1025
1125
  for (const fn of fns) {
1026
1126
  result = fn(result, ctx);
1027
- if (result === z.NEVER) return z.NEVER;
1127
+ if (result === z.NEVER || result.status === "aborted") return z.NEVER;
1028
1128
  }
1029
1129
  return result;
1030
1130
  }
1031
1131
  /**
1032
- * Returns a Zod error map that returns the given message for union errors.
1132
+ * Returns a Zod error callback that returns the given message for union errors.
1033
1133
  *
1034
1134
  * This is useful for generating meaningful error messages for unions, e.g.
1035
1135
  * ```
@@ -1049,12 +1149,9 @@ function pipeZodTransformers(initialValue, ctx, fns) {
1049
1149
  * ```
1050
1150
  */
1051
1151
  function unionErrorMessage(param) {
1052
- return { errorMap: (issue, ctx) => {
1053
- let message;
1054
- if (typeof param === "string") message = param;
1055
- else message = param(ctx.data);
1056
- if (issue.code === z.ZodIssueCode.invalid_union) return { message };
1057
- return { message: ctx.defaultError };
1152
+ return { error: (issue) => {
1153
+ if (typeof param === "string") return param;
1154
+ return param(issue.input);
1058
1155
  } };
1059
1156
  }
1060
1157
 
@@ -1121,20 +1218,13 @@ const excelStringStrictDecoder = z$1.union([
1121
1218
  *
1122
1219
  * Null handling: Null values/blank cells will be converted to a blank string.
1123
1220
  */
1124
- const excelStringDecoder = z$1.union([
1125
- z$1.string(),
1126
- z$1.number(),
1127
- z$1.boolean(),
1128
- z$1.null(),
1129
- z$1.undefined(),
1130
- z$1.any()
1131
- ]).transform((x) => {
1221
+ const excelStringDecoder = z$1.preprocess((x) => {
1132
1222
  if (x === null || x === void 0) return "";
1133
1223
  if (typeof x === "number") return x.toString();
1134
1224
  if (typeof x === "boolean") return x ? "true" : "false";
1135
1225
  if (typeof x === "string") return x;
1136
1226
  return "";
1137
- });
1227
+ }, z$1.string());
1138
1228
  /**
1139
1229
  * A decoder that transforms Excel strings to JS strings, also handling numbers and null
1140
1230
  *
@@ -1152,14 +1242,7 @@ const excelStringDecoder = z$1.union([
1152
1242
  * Null handling: Blank strings will be converted to null. This is to reflect that in Excel a formula
1153
1243
  * cannot return null. As a workaround, one often returns a blank string to represent null.
1154
1244
  */
1155
- const excelStringNullableDecoder = z$1.union([
1156
- z$1.string(),
1157
- z$1.number(),
1158
- z$1.boolean(),
1159
- z$1.null(),
1160
- z$1.undefined(),
1161
- z$1.any()
1162
- ]).transform((x) => {
1245
+ const excelStringNullableDecoder = z$1.preprocess((x) => {
1163
1246
  if (x === null || x === void 0) return null;
1164
1247
  if (typeof x === "number") return x.toString();
1165
1248
  if (typeof x === "boolean") return x ? "true" : "false";
@@ -1168,7 +1251,7 @@ const excelStringNullableDecoder = z$1.union([
1168
1251
  return x;
1169
1252
  }
1170
1253
  return null;
1171
- });
1254
+ }, z$1.string().nullable());
1172
1255
  const excelNumberTransformer = (x) => {
1173
1256
  if (typeof x === "string") {
1174
1257
  if (x.trim() === "") return null;
@@ -1216,18 +1299,11 @@ const excelNumberStrictDecoder = z$1.union([
1216
1299
  *
1217
1300
  * Null handling: Null values/blank cells will be converted to blank strings.
1218
1301
  */
1219
- const excelNumberDecoder = z$1.union([
1220
- z$1.string(),
1221
- z$1.number(),
1222
- z$1.boolean(),
1223
- z$1.null(),
1224
- z$1.undefined(),
1225
- z$1.any()
1226
- ]).transform((x) => {
1302
+ const excelNumberDecoder = z$1.preprocess((x) => {
1227
1303
  const result = excelNumberTransformer(x);
1228
1304
  if (result === null) return 0;
1229
1305
  return result;
1230
- });
1306
+ }, z$1.number());
1231
1307
  /**
1232
1308
  * A decoder that transforms Excel numbers to JS numbers, also handling strings, boolean and other types.
1233
1309
 
@@ -1236,17 +1312,11 @@ const excelNumberDecoder = z$1.union([
1236
1312
  * - If the value is a string, it'll try to parse it to a number. Non-numerical and blank strings will be converted to null
1237
1313
  * - If the value is boolean, it'll return 1 or 0
1238
1314
  * - If the value is any other type, it'll return null
1239
- *
1315
+ *
1240
1316
  * Null handling: Blank strings will be converted to null. This is to reflect that in Excel a formula
1241
1317
  * cannot return null. As a workaround, one often returns a blank string to represent null.
1242
1318
  */
1243
- const excelNumberNullableDecoder = z$1.union([
1244
- z$1.string(),
1245
- z$1.null(),
1246
- z$1.number(),
1247
- z$1.undefined(),
1248
- z$1.any()
1249
- ]).transform(excelNumberTransformer);
1319
+ const excelNumberNullableDecoder = z$1.preprocess(excelNumberTransformer, z$1.number().nullable());
1250
1320
  /**
1251
1321
  * A decoder that transforms Excel numbers to JS integers, also handling strings and boolean. Other types will throw an error.
1252
1322
  *
@@ -1338,18 +1408,11 @@ const excelBooleanStrictDecoder = z$1.union([
1338
1408
  * - If the value is boolean, it'll return it as-is
1339
1409
  * - If the value is any other type, it'll return false
1340
1410
  */
1341
- const excelBooleanDecoder = z$1.union([
1342
- z$1.boolean(),
1343
- z$1.number(),
1344
- z$1.null(),
1345
- z$1.string(),
1346
- z$1.undefined(),
1347
- z$1.any()
1348
- ]).transform((x) => {
1411
+ const excelBooleanDecoder = z$1.preprocess((x) => {
1349
1412
  const result = excelBooleanNullableTransformer(x);
1350
1413
  if (result === null) return false;
1351
1414
  return result;
1352
- });
1415
+ }, z$1.boolean());
1353
1416
  /**
1354
1417
  * A decoder that transforms Excel booleans to JS booleans, also handling numbers and strings.
1355
1418
  *
@@ -1359,14 +1422,7 @@ const excelBooleanDecoder = z$1.union([
1359
1422
  * - If the value is boolean, it'll return it as-is
1360
1423
  * - If the value is any other type, it'll return null
1361
1424
  */
1362
- const excelBooleanNullableDecoder = z$1.union([
1363
- z$1.boolean(),
1364
- z$1.number(),
1365
- z$1.null(),
1366
- z$1.string(),
1367
- z$1.undefined(),
1368
- z$1.any()
1369
- ]).transform(excelBooleanNullableTransformer);
1425
+ const excelBooleanNullableDecoder = z$1.preprocess(excelBooleanNullableTransformer, z$1.boolean().nullable());
1370
1426
  const excelDateNullableTransformer = (x, ctx) => {
1371
1427
  if (x === null || x === void 0) return null;
1372
1428
  if (isDate(x)) return x;
@@ -1412,15 +1468,8 @@ const excelDateDecoder = z$1.union([
1412
1468
  /**
1413
1469
  * A decoder that transforms nullable Excel dates to JS Dates
1414
1470
  */
1415
- const excelDateNullableDecoder = z$1.union([
1416
- z$1.date(),
1417
- z$1.string(),
1418
- z$1.number(),
1419
- z$1.null(),
1420
- z$1.undefined(),
1421
- z$1.any()
1422
- ]).transform(excelDateNullableTransformer);
1471
+ const excelDateNullableDecoder = z$1.preprocess((x, ctx) => excelDateNullableTransformer(x, ctx), z$1.date().nullable());
1423
1472
 
1424
1473
  //#endregion
1425
- export { DefaultMap, ExhaustiveSwitchCheck, NestedMap, Result, TypedMapping, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow };
1426
- //# sourceMappingURL=zod-excel.decoders-BJliEI1Y.js.map
1474
+ export { DefaultMap, ExhaustiveSwitchCheck, NestedMap, Result, TypedMapping, addAndSort, assertArray, assertType, blue, bold, booleanCode, capitalize, capitalizeKeys, commentLines, compare, compareBooleans, compareDates, compareFields, compareNumbers, compareStrings, compareValues, conjugateNames, cyan, dictGetAndAssert, ensureUnique, equals, err, excelBigIntDecoder, excelBigIntNullableDecoder, excelBigIntStrictDecoder, excelBooleanDecoder, excelBooleanNullableDecoder, excelBooleanStrictDecoder, excelDateDecoder, excelDateNullableDecoder, excelIntDecoder, excelIntNullableDecoder, excelIntStrictDecoder, excelNumberDecoder, excelNumberNullableDecoder, excelNumberStrictDecoder, excelStringDecoder, excelStringNullableDecoder, excelStringStrictDecoder, filterDict, filterMap, format, generateRandomAlphanumericString, gray, green, groupBy, groupByCurried, groupByToDict, groupByToMap, idToDict, inverse, isCamelCase, isDate, isKebabCase, isPascalCase, isPlural, isSlug, isSnakeCase, italic, keyGetter, lowerFirst, mapDict, mapGetAndAssert, mapLimit, mapMap, mapMapKeyValues, mapMapKeys, mapMapValues, mapToDict, netWorkDays, ok, omit, pipeZodTransformers, pluralize, randomInt, red, removeSecrets, removeUndefinedProperties, setDirection, slice, slugify, sort, timeStamp, toCamelCase, toDict, toExcelColumnName, toExcelTableName, toHumanReadable, toKebabCase, toPascalCase, toSnakeCase, uncapitalize, uncapitalizeKeys, underline, unionErrorMessage, uniq, upperFirst, yellow };
1475
+ //# sourceMappingURL=zod-excel.decoders-RJhEcAm0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-excel.decoders-RJhEcAm0.js","names":["_default: () => Value","key: Key","getKey1: (item: Item) => Key1","getKey2: (item: Item) => Key2","items: Item[]","key1: Key1","key2: Key2","item: Item","values: Item[]","entries: [Key1, Key2, Item][]","mappings: {\n [Model in keyof Identifiers]?: Mapping<Identifiers[Model]>\n }","newId: Identifiers[Model]","arr: T[]","value: T","predicate: (t: T) => number","arr: T[]","iterator: AsyncMapFn<T, R>","result: (R | undefined)[]","array: T[]","id: number | string","gen: ArrayGen<T>","mapFn: AsyncMapFn<T, R>","a: string | Buffer","b: string | Buffer","value: unknown","date: Date","startDate: Date","endDate: Date","holidays: Date[]","data: Value[]","keyFn: (item: Value) => Key","result: Dictionary<Value, Key>","data: T[]","result: Dictionary<T>","dict: Dictionary<S>","predicate: (item: S) => T","dict: Dictionary<T>","predicate: (item: T) => boolean","dict: Dictionary<Value>","key: Key","n: number","predicate: (x: T) => U","items: T[]","result: Partial<Record<U, T[]>>","predicate: (x: WithId) => GroupId","items: WithId[]","result: Partial<Record<GroupId, Record<Id, WithId>>>","getGroupId: (x: T) => GroupID","map: Map<Key, ValueFrom>","predicate: (item: ValueFrom, key: Key) => ValueTo","result: ValueTo[]","map: Map<KeyFrom, ValueFrom>","keyPredicate: (key: KeyFrom, value: ValueFrom) => KeyTo","valuePredicate: (item: ValueFrom, key: KeyFrom) => ValueTo","map: Map<KeyFrom, Value>","keyPredicate: (key: KeyFrom, value: Value) => KeyTo","map: Map<Key, Value>","predicate: (item: Value, key: Key) => boolean","key: Key","obj: T","key: string","items: Item[]","skip?: number","take?: number","max: number","value: number","length: number","value: unknown","config: T","newConfig: Record<string, unknown>","key: string","value: unknown","value: string","connection: string","password: string","obj: T","value: A","value: E","f: () => A","handleError: (error: Error) => E","result: SerializedResult<A, E>","promise: () => Promise<A>","#tag","#value","#error","tag: 'ok' | 'err'","value: A | E","f: (a: A) => B","f: (e: E) => X","f: (a: A) => Result<B, E>","fallback: A","items: Item[]","dir: Direction","compareFn: CompareFn<Item>","key: keyof T","getter: Getter<T>","data: T","compareValues: CompareFn<unknown>","compareDates: CompareFn<Date>","compareStrings: CompareFn<string>","compareNumbers: CompareFn<number>","compareBooleans: CompareFn<boolean>","bool: boolean","input: string","s: string","IRREGULAR_PLURALS: [singular: string, plural: string][]","obj: T","str: string","lines: string","input: string","name: string","value: string","existingValues: string[]","val: never","value: unknown","obj: I[]","fn: (i: I) => asserts i is O","items: T[]","predicate: (item: T) => number","result: T[]","seen: Record<string, true>","initialValue: Initial","ctx: z.RefinementCtx","fns: Fns","result: any","param: string | ((data: unknown) => string)","issue: any","x: number","ctx: z.RefinementCtx","transformer: (x: I, ctx: z.RefinementCtx) => O","x: I | undefined | null","x: string | number | boolean","x: any"],"sources":["../src/DefaultMap.ts","../src/NestedMap.ts","../src/TypedMapping.ts","../src/array.ts","../src/async.ts","../src/buffer.ts","../src/datetime.ts","../src/dictionary.ts","../src/format.ts","../src/group-by.ts","../src/map.ts","../src/omit.ts","../src/pagination.ts","../src/random.ts","../src/is-object.ts","../src/remove-secrets.ts","../src/remove-undefined.ts","../src/result.ts","../src/sort.ts","../src/string-colors.ts","../src/string.ts","../src/types.ts","../src/uniq.ts","../src/zod.ts","../src/zod-excel.decoders.ts"],"sourcesContent":["/**\n * A map extension that returns a default value if the key is not found.\n */\nexport class DefaultMap<Key, Value> extends Map<Key, Value> {\n /**\n * A function that returns the default value for the map.\n */\n\n constructor(private readonly _default: () => Value) {\n super()\n }\n\n override get(key: Key): Value {\n const value = super.get(key)\n if (value) {\n return value\n }\n\n const defaultValue = this._default()\n this.set(key, defaultValue)\n\n return defaultValue\n }\n}\n","export class NestedMap<Key1, Key2, Item> {\n private readonly _map = new Map<Key1, Map<Key2, Item>>()\n\n constructor(\n private readonly getKey1: (item: Item) => Key1,\n private readonly getKey2: (item: Item) => Key2,\n items: Item[] = [],\n ) {\n for (const item of items) {\n this.set(item)\n }\n }\n get(key1: Key1, key2: Key2): Item | undefined {\n const map = this._map.get(key1)\n if (!map) {\n return undefined\n }\n return map.get(key2)\n }\n\n private getKeys(item: Item): [Key1, Key2] {\n return [this.getKey1(item), this.getKey2(item)]\n }\n set(item: Item): void {\n const [key1, key2] = this.getKeys(item)\n\n let map = this._map.get(key1)\n if (!map) {\n map = new Map<Key2, Item>()\n this._map.set(key1, map)\n }\n map.set(key2, item)\n }\n\n delete(item: Item): void {\n const [key1, key2] = this.getKeys(item)\n const map = this._map.get(key1)\n if (!map) {\n return\n }\n map.delete(key2)\n }\n\n clear(): void {\n this._map.clear()\n }\n\n get size(): number {\n return Array.from(this._map.values()).reduce((sum, map) => sum + map.size, 0)\n }\n\n get keys(): Iterable<Key1> {\n return this._map.keys()\n }\n\n get values(): Iterable<Item> {\n const values: Item[] = []\n for (const map of this._map.values()) {\n for (const value of map.values()) {\n values.push(value)\n }\n }\n return values\n }\n\n get entries(): Iterable<[Key1, Key2, Item]> {\n const entries: [Key1, Key2, Item][] = []\n for (const [key1, map] of this._map.entries()) {\n for (const [key2, value] of map.entries()) {\n entries.push([key1, key2, value])\n }\n }\n return entries\n }\n\n get [Symbol.iterator](): Iterable<[Key1, Key2, Item]> {\n return this.entries\n }\n}\n","type IdentifiersBase = Record<string, string>\n\ntype Mapping<T> = Map<T, T>\n\n/**\n * A map of typed mappings.\n */\nexport class TypedMapping<Identifiers extends IdentifiersBase> {\n private mappings: {\n [Model in keyof Identifiers]?: Mapping<Identifiers[Model]>\n }\n\n constructor(\n mappings: {\n [Model in keyof Identifiers]?: Mapping<Identifiers[Model]>\n } = {},\n ) {\n this.mappings = mappings\n }\n\n /**\n * Creates a new mapping from the original id to the new id.\n */\n public set<Model extends keyof Identifiers>(\n { model, id }: { model: Model; id: Identifiers[Model] },\n newId: Identifiers[Model],\n ): this {\n if (!this.mappings[model]) {\n this.mappings[model] = new Map()\n }\n\n this.mappings[model]!.set(id, newId)\n\n return this\n }\n\n /**\n * Returns the id if there exists a mapping, otherwise returns the original id.\n */\n public get<Model extends keyof Identifiers>({\n model,\n id,\n }: {\n model: Model\n id: Identifiers[Model]\n }): Identifiers[Model] {\n const mapping = this.mappings[model]?.get(id)\n if (!mapping) {\n return id\n }\n return mapping\n }\n}\n","/**\n * Adds a value to a sorted array and keeps the array sorted.\n *\n * O(n)\n */\nexport function addAndSort<T>(arr: T[], value: T, predicate: (t: T) => number): T[] {\n arr.push(value)\n\n let i = arr.length - 1\n const item = arr[i] as T\n const order = predicate(item)\n\n while (i > 0 && order < predicate(arr[i - 1] as T)) {\n arr[i] = arr[i - 1] as T\n i -= 1\n }\n arr[i] = item\n\n return arr\n}\n","//Credit: https://codeburst.io/async-map-with-limited-parallelism-in-node-js-2b91bd47af70\n\nconst defaultConcurrency = 5\ntype AsyncMapFn<T, R> = (item: T, index: number) => Promise<R>\ntype ArrayGen<T> = Generator<[T | undefined, number], void, void>\n\n// async maps over all values of an array but limits the number of concurrent operations\nexport async function mapLimit<T, R>(\n arr: T[],\n iterator: AsyncMapFn<T, R>,\n limit = defaultConcurrency,\n): Promise<(R | undefined)[]> {\n const result: (R | undefined)[] = []\n if (arr.length === 0) {\n return result\n }\n\n const generator = arrayGenerator(arr)\n\n limit = Math.min(limit, arr.length)\n const workers = new Array(limit)\n\n for (let i = 0; i < limit; i++) {\n workers.push(worker(i, generator, iterator, result))\n }\n\n await Promise.all(workers)\n\n return result\n}\n\nfunction* arrayGenerator<T>(array: T[]): ArrayGen<T> {\n for (let index = 0; index < array.length; index++) {\n const currentValue = array[index]\n yield [currentValue, index]\n }\n}\n\nasync function worker<T, R>(\n id: number | string,\n gen: ArrayGen<T>,\n mapFn: AsyncMapFn<T, R>,\n result: (R | undefined)[],\n): Promise<void> {\n for (const [currentValue, index] of gen) {\n result[index] = undefined\n if (currentValue === undefined) {\n return\n }\n try {\n result[index] = await mapFn(currentValue, index)\n } catch (e) {\n console.error(`Worker ${id} --- index ${index} item ${JSON.stringify(currentValue)} failed`, e)\n }\n }\n}\n","/**\n * Compares two string or buffer values for equality.\n */\nexport function equals(a: string | Buffer, b: string | Buffer): boolean {\n if (typeof a === 'string' && typeof b === 'string') {\n return a === b\n }\n\n if (Buffer.isBuffer(a) && Buffer.isBuffer(b)) {\n return a.equals(b)\n }\n\n return false\n}\n","/**\n * Milliseconds in one day (24 hours × 60 minutes × 60 seconds × 1000 milliseconds)\n */\nconst MS_PER_DAY = 86400000\n\n/**\n * returns the default time stamp in format YYMMDD HHMM\n */\nexport function timeStamp(): string {\n const date = new Date()\n const year = date.getFullYear().toString().slice(-2)\n const month = (date.getMonth() + 1).toString().padStart(2, '0')\n const day = date.getDate().toString().padStart(2, '0')\n const hour = date.getHours().toString().padStart(2, '0')\n const minute = date.getMinutes().toString().padStart(2, '0')\n return `${year}${month}${day} ${hour}${minute}`\n}\n\n/**\n * Checks if a value is a valid Date object.\n * Returns true only for Date instances that are not Invalid Date.\n * This function is isomorphic and works in both Node.js and browser environments.\n *\n * @param value - The value to check\n * @returns true if the value is a valid Date object, false otherwise\n *\n * @example\n * isDate(new Date()) // true\n * isDate(new Date('2023-01-01')) // true\n * isDate(new Date('invalid')) // false (Invalid Date)\n * isDate('2023-01-01') // false\n * isDate(1234567890) // false\n * isDate(null) // false\n * isDate(undefined) // false\n */\nexport function isDate(value: unknown): value is Date {\n return value instanceof Date && !Number.isNaN(value.getTime())\n}\n\n/**\n * Converts a Date to a normalized date string (YYYY-MM-DD) based on UTC.\n * This is used for consistent date comparisons across timezones.\n *\n * The function extracts the date portion from the ISO 8601 format:\n * - Input: \"2024-01-15T12:34:56.789Z\" (ISO string)\n * - Output: \"2024-01-15\" (first 10 characters: YYYY-MM-DD)\n */\nfunction toDateKey(date: Date): string {\n return date.toISOString().slice(0, 10)\n}\n\n/**\n * Checks if a given date falls on a weekend (Saturday or Sunday) using UTC.\n */\nfunction isWeekend(date: Date): boolean {\n const day = date.getUTCDay()\n return day === 0 || day === 6 // Sunday = 0, Saturday = 6\n}\n\n/**\n * Creates a new Date representing the start of the UTC day for a given date.\n * This normalizes dates to avoid timezone and time-of-day issues.\n */\nfunction toUTCDate(date: Date): Date {\n return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()))\n}\n\n/**\n * Calculates the number of working days between two dates, excluding weekends\n * and optionally excluding specified holidays. Similar to Excel's NETWORKDAYS function.\n *\n * Working days are Monday through Friday. Both the start date and end date are\n * included in the count if they are working days.\n *\n * The function uses UTC-based date comparisons to ensure consistent behavior\n * across different timezones.\n *\n * @param startDate - The start date of the period\n * @param endDate - The end date of the period\n * @param holidays - Optional array of dates to exclude as holidays\n * @returns The number of working days between the dates (inclusive).\n * Returns a negative number if endDate is before startDate.\n * Returns 0 if either date is invalid.\n *\n * @example\n * // Count working days in a week (Monday to Friday)\n * netWorkDays(new Date('2024-01-08'), new Date('2024-01-12')) // 5\n *\n * @example\n * // Same day that is a working day\n * netWorkDays(new Date('2024-01-08'), new Date('2024-01-08')) // 1\n *\n * @example\n * // Same day that is a weekend\n * netWorkDays(new Date('2024-01-06'), new Date('2024-01-06')) // 0 (Saturday)\n *\n * @example\n * // With holidays\n * netWorkDays(\n * new Date('2024-01-08'),\n * new Date('2024-01-12'),\n * [new Date('2024-01-10')] // Wednesday is a holiday\n * ) // 4\n *\n * @example\n * // End date before start date (returns negative)\n * netWorkDays(new Date('2024-01-12'), new Date('2024-01-08')) // -5\n */\nexport function netWorkDays(startDate: Date, endDate: Date, holidays: Date[] = []): number {\n // Validate input dates\n if (!isDate(startDate) || !isDate(endDate)) {\n return 0\n }\n\n // Normalize dates to UTC to avoid timezone issues\n const normalizedStart = toUTCDate(startDate)\n const normalizedEnd = toUTCDate(endDate)\n\n // Handle reversed date range\n const isReversed = normalizedStart > normalizedEnd\n const [from, to] = isReversed ? [normalizedEnd, normalizedStart] : [normalizedStart, normalizedEnd]\n\n // Calculate total days in range (inclusive)\n const totalDays = Math.floor((to.getTime() - from.getTime()) / MS_PER_DAY) + 1\n\n // Calculate number of weekend days mathematically\n const startDay = from.getUTCDay()\n const fullWeeks = Math.floor(totalDays / 7)\n const remainingDays = totalDays % 7\n\n // Each full week has 2 weekend days\n let weekendDays = fullWeeks * 2\n\n // Count weekend days in the remaining partial week\n for (let i = 0; i < remainingDays; i++) {\n const dayOfWeek = (startDay + i) % 7\n if (dayOfWeek === 0 || dayOfWeek === 6) {\n weekendDays++\n }\n }\n\n // Calculate working days before considering holidays\n let workDays = totalDays - weekendDays\n\n // Subtract holidays that fall on weekdays within the range\n const fromKey = toDateKey(from)\n const toKey = toDateKey(to)\n const countedHolidays = new Set<string>()\n\n for (const holiday of holidays) {\n if (!isDate(holiday)) {\n continue\n }\n\n const normalizedHoliday = toUTCDate(holiday)\n const holidayKey = toDateKey(normalizedHoliday)\n\n // Check if holiday is within range, on a weekday, and not already counted\n if (\n holidayKey >= fromKey &&\n holidayKey <= toKey &&\n !isWeekend(normalizedHoliday) &&\n !countedHolidays.has(holidayKey)\n ) {\n countedHolidays.add(holidayKey)\n workDays--\n }\n }\n\n return isReversed ? -workDays : workDays\n}\n","export type Dictionary<Value, Key extends string = string> = Record<Key, Value>\n\nexport function toDict<Value, Key extends string = string>(\n data: Value[],\n keyFn: (item: Value) => Key,\n): Dictionary<Value, Key> {\n const result: Dictionary<Value, Key> = {} as Dictionary<Value, Key>\n\n for (const item of data) {\n result[keyFn(item)] = item\n }\n return result\n}\n\nexport function idToDict<T extends { id: string | number }>(data: T[]): Dictionary<T> {\n const result: Dictionary<T> = {}\n\n for (const item of data) {\n result[item.id.toString()] = item\n }\n return result\n}\n\nexport function mapDict<S, T>(dict: Dictionary<S>, predicate: (item: S) => T): Dictionary<T> {\n const result: Dictionary<T> = {}\n\n for (const [key, value] of Object.entries(dict)) {\n result[key] = predicate(value)\n }\n return result\n}\n\nexport function filterDict<T>(dict: Dictionary<T>, predicate: (item: T) => boolean): Dictionary<T> {\n const result: Dictionary<T> = {}\n\n for (const [key, value] of Object.entries(dict)) {\n if (predicate(value)) {\n result[key] = value\n }\n }\n return result\n}\n\nexport function dictGetAndAssert<Key extends string, Value>(dict: Dictionary<Value>, key: Key): NonNullable<Value> {\n const value = dict[key]\n if (value === null || value === undefined) {\n throw new Error(`Key ${key} not found`)\n }\n return value as NonNullable<Value>\n}\n","export function format(n: number, locale = 'en-US'): string {\n return new Intl.NumberFormat(locale).format(n)\n}\n","export const groupBy = <T, U extends string | number>(predicate: (x: T) => U, items: T[]): Partial<Record<U, T[]>> => {\n const result: Partial<Record<U, T[]>> = {}\n for (const item of items) {\n const key = predicate(item)\n\n const group = result[key]\n\n if (group === undefined) {\n result[key] = [item]\n } else {\n group.push(item)\n }\n }\n return result\n}\n\nexport const groupByCurried = <T, U extends string | number>(\n predicate: (x: T) => U,\n): ((items: T[]) => Partial<Record<U, T[]>>) => {\n const result: Partial<Record<U, T[]>> = {}\n return (items: T[]) => {\n for (const item of items) {\n const key = predicate(item)\n\n const group = result[key]\n\n if (group === undefined) {\n result[key] = [item]\n } else {\n group.push(item)\n }\n }\n return result\n }\n}\n\nexport const groupByToDict = <Id extends string | number, WithId extends { id: Id }, GroupId extends string | number>(\n predicate: (x: WithId) => GroupId,\n items: WithId[],\n): Partial<Record<GroupId, Record<Id, WithId>>> => {\n const result: Partial<Record<GroupId, Record<Id, WithId>>> = {}\n for (const item of items) {\n const key = predicate(item)\n\n const group = result[key]\n\n if (group === undefined) {\n result[key] = { [item.id]: item } as Record<Id, WithId>\n } else {\n group[item.id] = item\n }\n }\n return result\n}\n\nexport const groupByToMap = <T extends { id: ItemID }, ItemID extends string | number, GroupID extends string | number>(\n getGroupId: (x: T) => GroupID,\n items: T[],\n): Map<GroupID, Map<ItemID, T>> => {\n const result = new Map<GroupID, Map<ItemID, T>>()\n for (const item of items) {\n const groupId = getGroupId(item)\n\n if (!result.has(groupId)) {\n result.set(groupId, new Map())\n }\n\n const group = result.get(groupId)\n if (group !== undefined) {\n group.set(item.id, item)\n }\n }\n return result\n}\n","export function mapMap<Key, ValueFrom, ValueTo>(\n map: Map<Key, ValueFrom>,\n predicate: (item: ValueFrom, key: Key) => ValueTo,\n): Map<Key, ValueTo> {\n const result = new Map<Key, ValueTo>()\n\n for (const [key, value] of map.entries()) {\n result.set(key, predicate(value, key))\n }\n return result\n}\n\nexport function mapMapValues<Key, ValueFrom, ValueTo>(\n map: Map<Key, ValueFrom>,\n predicate: (item: ValueFrom, key: Key) => ValueTo,\n): ValueTo[] {\n const result: ValueTo[] = []\n\n for (const [key, value] of map.entries()) {\n result.push(predicate(value, key))\n }\n return result\n}\n\n/**\n *\n */\nexport function mapMapKeyValues<KeyFrom, KeyTo, ValueFrom, ValueTo>(\n map: Map<KeyFrom, ValueFrom>,\n keyPredicate: (key: KeyFrom, value: ValueFrom) => KeyTo,\n valuePredicate: (item: ValueFrom, key: KeyFrom) => ValueTo,\n): Map<KeyTo, ValueTo> {\n const result = new Map<KeyTo, ValueTo>()\n\n for (const [key, value] of map.entries()) {\n result.set(keyPredicate(key, value), valuePredicate(value, key))\n }\n return result\n}\n\n/**\n * Maps keys of a map.\n */\nexport function mapMapKeys<KeyFrom, KeyTo, Value>(\n map: Map<KeyFrom, Value>,\n keyPredicate: (key: KeyFrom, value: Value) => KeyTo,\n): Map<KeyTo, Value> {\n const result = new Map<KeyTo, Value>()\n\n for (const [key, value] of map.entries()) {\n result.set(keyPredicate(key, value), value)\n }\n return result\n}\n\n/**\n * Filters values from a map.\n */\nexport function filterMap<Key, Value>(\n map: Map<Key, Value>,\n predicate: (item: Value, key: Key) => boolean,\n): Map<Key, Value> {\n const result = new Map<Key, Value>()\n\n for (const [key, value] of map.entries()) {\n if (predicate(value, key)) {\n result.set(key, value)\n }\n }\n\n return result\n}\n\n/**\n * Gets a value from a map and asserts that it exists.\n */\nexport function mapGetAndAssert<Key, Value>(map: Map<Key, Value>, key: Key): Value {\n const value = map.get(key)\n if (!value) {\n throw new Error(`Key ${JSON.stringify(key)} not found`)\n }\n return value\n}\n\n/**\n * Converts a map to a dictionary.\n */\nexport function mapToDict<Key extends string | number, Value>(map: Map<Key, Value>): Record<Key, Value> {\n const result = {} as Record<Key, Value>\n for (const [key, value] of map.entries()) {\n result[key] = value\n }\n return result\n}\n","/**\n * Omits a key from an object\n */\nexport function omit<T extends Record<string, unknown>>(obj: T, key: string): Omit<T, typeof key> {\n const { [key]: _, ...rest } = obj\n return rest\n}\n","export type Page<Item> = { total: number; offset: number; items: Item[] }\n\nexport const slice = <Item>(items: Item[], skip?: number, take?: number): Page<Item> => {\n const start = skip ?? 0\n const end = take ? start + take : undefined\n return {\n total: items.length,\n offset: start,\n items: items.slice(start, end),\n }\n}\n","/**\n * Returns a random integer between 0 (inclusive) and max (exclusive).\n *\n * Isomorphic implementation for Node.js, Deno, Bun, and browser environments.\n * Uses Web Crypto API which is available in all modern JavaScript runtimes.\n */\nexport function randomInt(max: number): number {\n // All modern environments (Node.js 15+, Deno, Bun, browsers) have Web Crypto API\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n return browserRandomInt(max)\n }\n\n throw new Error('No suitable random number generator available')\n}\n\nfunction browserRandomInt(max: number): number {\n // Browser - use rejection sampling to avoid modulo bias\n const randomMax = 0x100000000 // 2^32\n const range = randomMax - (randomMax % max)\n\n let value: number\n do {\n const array = new Uint32Array(1)\n crypto.getRandomValues(array)\n value = array[0]!\n } while (value >= range)\n\n return value % max\n}\n\nconst CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'\n\n/**\n * Returns a randomly generated alphanumeric string.\n */\nexport function generateRandomAlphanumericString(length: number): string {\n let result = ''\n for (let i = 0; i < length; i++) {\n result += CHARS[randomInt(CHARS.length)]\n }\n return result\n}\n","/**\n * Returns true if the value is an object, false otherwise.\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\n/**\n * Only returns true for plain objects, not for classes or functions\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && value.constructor === Object\n}\n\n/**\n * Returns true if the value is a function, false otherwise.\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport function isFunction(value: unknown): value is Function {\n return typeof value === 'function'\n}\n","import { isPlainObject } from './is-object'\n\n/**\n * Removes secrets from the given configuration object.\n *\n * Recursively checks all properties of the object for keys that end with\n * `key`, `secret`, `password`, `token` and replaces them with '***'.\n *\n * Also checks for keys the end with `connection` or `connectionString` and\n * replaces the connection string with the same string but with the password\n * replaced with '***'.\n */\nexport function removeSecrets<T extends Record<string, unknown>>(config: T): T {\n const newConfig: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(config)) {\n newConfig[key] = processValue(key, value)\n }\n return newConfig as T\n}\n\nfunction processValue(key: string, value: unknown): unknown {\n if (typeof value === 'string') {\n return processString(key, value)\n } else if (Array.isArray(value)) {\n return value.map((item) => removeSecrets(item))\n } else if (typeof value === 'object' && isPlainObject(value)) {\n return removeSecrets(value)\n }\n return value\n}\n\nfunction processString(key: string, value: string): string {\n if (key.endsWith('key') || key.endsWith('secret') || key.endsWith('password') || key.endsWith('token')) {\n return hidePassword(value)\n } else if (key.endsWith('connection') || key.endsWith('connectionString')) {\n return hidePasswordInConnectionString(value)\n } else {\n return value\n }\n}\n\nfunction hidePasswordInConnectionString(connection: string): string {\n return (\n connection\n // e.g. postgresql://user:password@host\n .replace(/^(.*):\\/\\/(.*):(.*)@(.*)$/, '$1://$2:***@$4') //NOSONAR - this is only used to parse environment variables, so no risk of external DOS attacks\n // e.g. user:password@host\n .replace(/^(.*):(.*)@(.*)$/, '$1:***@$3') //NOSONAR - this is only used to parse environment variables, so no risk of external DOS attacks\n )\n}\n\nfunction hidePassword(password: string): string {\n if (password === '') {\n return 'nothing provided!'\n }\n if (password === 'secret') {\n return 'default provided!'\n }\n return '***'\n}\n","/**\n * Removes all undefined properties from an object.\n *\n * NOTE: This is useful when using the `Partial<T>` type modifier in combination with the spread operator to prevent\n * overriding with undefined values.\n */\nexport function removeUndefinedProperties<T extends Record<string, unknown>>(\n obj: T,\n): { [K in keyof T]: T[K] extends undefined ? never : T[K] } {\n const newObj = {} as {\n [K in keyof T]: T[K] extends undefined ? never : T[K]\n }\n\n for (const key in obj) {\n const value = obj[key]\n\n if (value !== undefined) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n newObj[key] = value\n }\n }\n\n return newObj\n}\n","export type SerializedResult<A, E> = { tag: 'ok'; value: A } | { tag: 'err'; err: E }\n\nexport class Result<A, E> {\n static ok<A, E>(value: A): Result<A, E> {\n return new Result<A, E>('ok', value)\n }\n\n static err<A, E>(value: E): Result<A, E> {\n return new Result<A, E>('err', value)\n }\n\n static fromThrowable<A, E>(f: () => A, handleError: (error: Error) => E): Result<A, E> {\n try {\n return Result.ok(f())\n } catch (error) {\n return Result.err(handleError(error as Error))\n }\n }\n\n static fromObject<A, E>(result: SerializedResult<A, E>): Result<A, E> {\n if (result.tag === 'ok') {\n return Result.ok(result.value)\n } else {\n return Result.err(result.err)\n }\n }\n\n static async fromPromise<A, E>(promise: () => Promise<A>, handleError: (error: Error) => E): Promise<Result<A, E>> {\n try {\n return Result.ok(await promise())\n } catch (error) {\n return Result.err(handleError(error as Error))\n }\n }\n\n // We track the tag separately from the value and error to allow for us to use\n // `null` as a valid value.\n\n readonly #tag: 'ok' | 'err'\n readonly #value: A | null\n readonly #error: E | null\n\n private constructor(tag: 'ok', value: A)\n private constructor(tag: 'err', value: E)\n private constructor(tag: 'ok' | 'err', value: A | E) {\n this.#tag = tag\n this.#value = tag === 'ok' ? (value as A) : null\n this.#error = tag === 'err' ? (value as E) : null\n }\n\n isOk(): this is Result<A, never> {\n return this.#tag === 'ok'\n }\n\n isErr(): this is Result<never, E> {\n return this.#tag === 'err'\n }\n\n map<B>(f: (a: A) => B): Result<B, E> {\n if (this.#tag === 'ok') {\n return Result.ok(f(this.#value!))\n } else {\n return this as unknown as Result<B, E>\n }\n }\n\n mapErr<X>(f: (e: E) => X): Result<A, X> {\n if (this.#tag === 'err') {\n return Result.err(f(this.#error!))\n } else {\n return this as unknown as Result<A, X>\n }\n }\n\n andThen<B>(f: (a: A) => Result<B, E>): Result<B, E> {\n if (this.#tag === 'ok') {\n return f(this.#value!)\n } else {\n return this as unknown as Result<B, E>\n }\n }\n\n withDefault(fallback: A): A {\n return this.#tag === 'ok' ? this.#value! : fallback\n }\n\n unwrap(): A {\n if (this.#tag === 'ok') {\n return this.#value!\n } else {\n throw new Error(typeof this.#error === 'string' ? this.#error : JSON.stringify(this.#error))\n }\n }\n\n unwrapErr(): E {\n if (this.#tag === 'err') {\n return this.#error!\n } else {\n throw new Error('tried to unwrap an ok result')\n }\n }\n\n toJSON(): SerializedResult<A, E> {\n if (this.#tag === 'ok') {\n return { tag: 'ok', value: this.#value! }\n } else {\n return { tag: 'err', err: this.#error! }\n }\n }\n}\n\nexport const ok = Result.ok\nexport const err = Result.err\n\nexport type TypedError<T extends string> = {\n type: T\n message: string\n error: Error\n}\n\nexport default Result\n","export type CompareFn<T> = (a: T, b: T) => number\n\nexport type Direction = 'asc' | 'desc'\n\nexport const sort = <Item>(items: Item[], dir: Direction = 'asc', compareFn: CompareFn<Item> = compareValues): Item[] =>\n setDirection(items.toSorted(compareFn), dir)\n\n/**\n * Compare fields of an object.\n */\nexport const compareFields = <T>(key: keyof T): CompareFn<T> => {\n return (a, b) => compareValues(a[key], b[key])\n}\n\nexport type Getter<T> = (data: T) => unknown\n\nexport const compare = <T>(getter: Getter<T>): CompareFn<T> => {\n return (a, b) => compareValues(getter(a), getter(b))\n}\n\nexport const keyGetter = <T>(key: keyof T): Getter<T> => {\n return (data: T) => data[key]\n}\n\nexport const compareValues: CompareFn<unknown> = (a, b) => {\n switch (true) {\n // In case one item is undefined or null and the other is not, we place the non-null item first.\n case (a === undefined || a === null) && b !== undefined && b !== null:\n return 1\n\n case (b === undefined || b === null) && a !== undefined && a !== null:\n return -1\n\n case (a === undefined || a === null) && (b === undefined || b === null):\n return 0\n\n case a instanceof Date && b instanceof Date:\n return compareDates(a, b)\n\n case typeof a === 'string' && typeof b === 'string':\n return compareStrings(a, b)\n\n case typeof a === 'number' && typeof b === 'number':\n return compareNumbers(a, b)\n\n case typeof a === 'boolean' && typeof b === 'boolean':\n return compareBooleans(a, b)\n\n default:\n return 0\n }\n}\n\nexport const compareDates: CompareFn<Date> = (a, b) => compareStrings(a.toISOString(), b.toISOString())\n\nexport const compareStrings: CompareFn<string> = (a, b) => {\n const aLower = a.trim().toLowerCase()\n const bLower = b.trim().toLowerCase()\n if (aLower === bLower) {\n return 0\n }\n return aLower > bLower ? 1 : -1\n}\n\nexport const compareNumbers: CompareFn<number> = (a, b) => a - b\n\nexport const compareBooleans: CompareFn<boolean> = (a, b) => booleanCode(a) - booleanCode(b)\n\nexport const booleanCode = (bool: boolean): number => (bool ? 1 : 0)\n\nexport const setDirection = <Item>(items: Item[], dir: Direction): Item[] => {\n return dir === 'desc' ? items.toReversed() : items\n}\n","/**\n * A function that returns a string with a specific color.\n */\nexport type ColorFn = (input: string) => string\n\n/**\n * Colors a string in red color (using ANSI escape codes).\n */\nexport function red(input: string): string {\n return `\\u001b[31m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in green color (using ANSI escape codes).\n */\nexport function green(input: string): string {\n return `\\u001b[32m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in yellow color (using ANSI escape codes).\n */\nexport function yellow(input: string): string {\n return `\\u001b[33m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in blue color (using ANSI escape codes).\n */\nexport function blue(input: string): string {\n return `\\u001b[34m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in cyan color (using ANSI escape codes).\n */\nexport function cyan(input: string): string {\n return `\\u001b[36m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in gray color (using ANSI escape codes).\n */\nexport function gray(input: string): string {\n return `\\u001b[90m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in bold color (using ANSI escape codes).\n */\nexport function bold(input: string): string {\n return `\\u001b[1m${input}\\u001b[22m`\n}\n\n/**\n * Colors a string in underline color (using ANSI escape codes).\n */\nexport function underline(input: string): string {\n return `\\u001b[4m${input}\\u001b[24m`\n}\n\n/**\n * Colors a string in italic color (using ANSI escape codes).\n */\nexport function italic(input: string): string {\n return `\\u001b[3m${input}\\u001b[23m`\n}\n\n/**\n * Inverts the color of a string (using ANSI escape codes).\n */\nexport function inverse(input: string): string {\n return `\\u001b[7m${input}\\u001b[27m`\n}\n","export function upperFirst(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nexport function lowerFirst(s: string): string {\n return s.charAt(0).toLowerCase() + s.slice(1)\n}\n\nconst IRREGULAR_PLURALS: [singular: string, plural: string][] = Object.entries({\n abyss: 'abysses',\n aegis: 'aegises',\n alias: 'aliases',\n alumnus: 'alumni',\n amends: 'amends',\n analysis: 'analyses',\n apparatus: 'apparatuses',\n appendix: 'appendices',\n asbestos: 'asbestoses',\n atlas: 'atlases',\n axis: 'axes',\n basis: 'bases',\n biceps: 'bicepses',\n bus: 'buses',\n caress: 'caresses',\n child: 'children',\n children: 'children',\n circus: 'circuses',\n citrus: 'citruses',\n compass: 'compasses',\n crisis: 'crises',\n criterion: 'criteria',\n crocus: 'crocuses',\n data: 'data',\n datum: 'data',\n diabetes: 'diabetes',\n diagnosis: 'diagnoses',\n dross: 'drosses',\n egress: 'egresses',\n elvis: 'elvises',\n emboss: 'embosses',\n fiss: 'fisses',\n focus: 'foci',\n glass: 'glasses',\n hippocampus: 'hippocampi',\n // While `histories` is the plural of `history`, in a model context, `history` makes more sense:\n // If you have a model called `UserHistory`, calling the table `UserHistories` would be confusing.\n history: 'history',\n hypothesis: 'hypotheses',\n ignis: 'ignises',\n index: 'indices',\n iris: 'irises',\n jesus: 'jesuses',\n kudos: 'kudos',\n lens: 'lenses',\n man: 'men',\n matrix: 'matrices',\n medium: 'media',\n news: 'news',\n oasis: 'oases',\n parenthesis: 'parentheses',\n pass: 'passes',\n phenomenon: 'phenomena',\n prognosis: 'prognoses',\n radius: 'radii',\n ras: 'rasses',\n sepsis: 'sepses',\n species: 'species',\n status: 'statuses',\n suffix: 'suffixes',\n syllabus: 'syllabi',\n synopsis: 'synopses',\n thesis: 'theses',\n tress: 'tresses',\n virus: 'viruses',\n vortex: 'vortices',\n woman: 'women',\n})\n\n/**\n * Returns a pluralized version of the given string based on the count.\n */\nexport function pluralize(s: string, count = 2): string {\n // If there's one of something we simply use the singular form.\n if (count === 1) {\n return s\n }\n\n // For plural forms, we first check whether a word is irregular.\n const lower = s.toLowerCase()\n for (const [singular, plural] of IRREGULAR_PLURALS) {\n // We check that items *end with* a given word because we use combined words\n // like `UserHistory` as input values of this function.\n if (lower.endsWith(singular)) {\n return s.slice(0, -singular.length + 1) + plural.slice(1)\n }\n }\n\n if (lower.endsWith('ss')) {\n return s.slice(0, -2) + 'sses'\n }\n if (\n // e.g. index\n lower.endsWith('x') ||\n // e.g. buzz\n lower.endsWith('z') ||\n // e.g. wish\n lower.endsWith('sh') ||\n // e.g. match\n lower.endsWith('ch')\n ) {\n return s + 'es'\n }\n\n if (\n s.endsWith('y') &&\n !s.endsWith('ay') &&\n !s.endsWith('ey') &&\n !s.endsWith('iy') &&\n !s.endsWith('oy') &&\n !s.endsWith('uy')\n ) {\n return s.slice(0, -1) + 'ies'\n }\n\n if (s.endsWith('s')) {\n return s\n }\n\n return s + 's'\n}\n\n/**\n * Returns true if the given string is already pluralized.\n */\nexport function isPlural(s: string): boolean {\n const plural = pluralize(s)\n return plural === s\n}\n\n/**\n * Type modifier that converts all keys of an object to capitalized versions.\n */\nexport type CapitalizedKeys<T extends Record<string, unknown>> = {\n [K in keyof T as CapitalizeFirstLetter<string & K>]: T[K]\n}\n\n/**\n * Type modifier that converts the first letter of a string to a capital letter.\n */\ntype CapitalizeFirstLetter<S extends string> = `${Capitalize<Extract<S, string>>}`\n\n/**\n * Converts all keys of an object to capitalized versions in a type-safe way.\n */\nexport function capitalizeKeys<T extends Record<string, unknown>>(obj: T): CapitalizedKeys<T> {\n const result = {} as CapitalizedKeys<T>\n\n for (const key in obj) {\n const cKey = `${key.charAt(0).toUpperCase()}${key.slice(1)}`\n const cVal = obj[key]\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n result[cKey] = cVal\n }\n\n return result\n}\n\n/**\n * Type modifier that converts all keys of an object to uncapitalized versions.\n */\nexport type UncapitalizedKeys<T extends Record<string, unknown>> = {\n [K in keyof T as UncapitalizeFirstLetter<string & K>]: T[K]\n}\n\n/**\n * Type modifier that converts the first letter of a string to an uncapitalized letter.\n */\ntype UncapitalizeFirstLetter<S extends string> = `${Uncapitalize<Extract<S, string>>}`\n\n/**\n * Converts all keys of an object to uncapitalized versions in a type-safe way.\n */\nexport function uncapitalizeKeys<T extends Record<string, unknown>>(obj: T): UncapitalizedKeys<T> {\n const result = {} as UncapitalizedKeys<T>\n\n for (const key in obj) {\n const unKey = `${key.charAt(0).toLowerCase()}${key.slice(1)}`\n const unVal = obj[key]\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n result[unKey] = unVal\n }\n\n return result\n}\n\n/**\n * Returns the same string with a lowercase first letter.\n */\nexport function uncapitalize(str: string): string {\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n\n/**\n * Returns the same string with an uppercase first letter.\n */\nexport function capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\n/**\n * Returns the camelCase version of the given string.\n *\n * Camel case examples:\n * `toCamelCase('hello world')` -> 'helloWorld',\n * `toCamelCase('hello_world')` -> 'helloWorld',\n * `toCamelCase('helloWorld')` -> 'helloWorld'\n * `toCamelCase('HelloWorld')` -> 'helloWorld'\n * `toCamelCase('hello_world')` -> 'helloWorld'\n */\nexport function toCamelCase(str: string): string {\n if (/^[a-z]+(?:[A-Z][a-z]*)*$/.test(str)) {\n return str\n }\n\n // Split the string into an array of words\n // We split on spaces, underscores, and hyphens.\n // We also split on single uppercase letters, though not on consecutive uppercase letters.\n const words = str.split(/(?<![A-Z])(?=[A-Z])|[\\s_-]+/)\n\n // Convert the first word to lowercase and capitalize the rest\n const camelCasedWords = words\n .map((word) => (word.toUpperCase() === word ? word.toLowerCase() : word))\n .map((word, index) => (index === 0 ? lowerFirst(word) : upperFirst(word)))\n\n // Join the words back together into a single string\n const camelCasedStr = camelCasedWords.join('')\n\n return camelCasedStr\n}\n\n/**\n * Validates if a string is in camelCase format\n */\nexport function isCamelCase(str: string): boolean {\n return str === toCamelCase(str)\n}\n\n/**\n * Returns the PascalCase version of the given string.\n *\n * Examples:\n * `toPascalCase('hello world')` -> 'HelloWorld'\n * `toPascalCase('hello_world')` -> 'HelloWorld'\n * `toPascalCase('helloWorld')` -> 'HelloWorld'\n * `toPascalCase('Hello-World')` -> 'HelloWorld'\n * `toPascalCase('HELLO_WORLD')` -> 'HelloWorld'\n */\nexport function toPascalCase(str: string): string {\n const s = toCamelCase(str)\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\n/**\n * Validates if a string is in PascalCase format\n */\nexport function isPascalCase(str: string): boolean {\n return str === toPascalCase(str)\n}\n\n/**\n * Returns the snake_case version of the given string.\n *\n * Examples:\n * `toSnakeCase('hello world')` -> 'hello_world'\n * `toSnakeCase('helloWorld')` -> 'hello_world'\n * `toSnakeCase('HelloWorld')` -> 'hello_world'\n * `toSnakeCase('HELLO_WORLD')` -> 'hello_world'\n */\nexport function toSnakeCase(str: string): string {\n const camelCase = toCamelCase(str)\n return camelCase.replace(/([A-Z])/g, '_$1').toLowerCase()\n}\n\n/**\n * Validates if a string is in snake_case format\n */\nexport function isSnakeCase(str: string): boolean {\n return str === toSnakeCase(str)\n}\n\n/**\n * Returns the kebab-case version of the given string.\n *\n * Examples:\n * `toKebabCase('hello world')` -> 'hello-world'\n * `toKebabCase('helloWorld')` -> 'hello-world'\n * `toKebabCase('HelloWorld')` -> 'hello-world'\n * `toKebabCase('HELLO_WORLD')` -> 'hello-world'\n */\nexport function toKebabCase(str: string): string {\n const camelCase = toCamelCase(str)\n return camelCase.replaceAll(/([A-Z])/g, '-$1').toLowerCase()\n}\n\n/**\n * Validates if a string is in kebab-case format\n */\nexport function isKebabCase(str: string): boolean {\n return str === toKebabCase(str)\n}\n\n/**\n * Converts each line of a string to a commented line\n */\nexport function commentLines(lines: string): string {\n return lines\n .split('\\n')\n .map((l) => `// ${l}`)\n .join('\\n')\n}\n\nexport function toHumanReadable(input: string): string {\n // Replace underscores and hyphens with spaces\n let result = input.replace(/[_-]/g, ' ')\n\n // Add spaces before capital letters\n result = result.replace(/([a-z])([A-Z])/g, '$1 $2')\n\n //In case the string was already human readable, return it\n if (result === input) {\n return input\n }\n\n //lowercase the first letter of every word\n result = result\n .split(' ')\n .map((s) => s.toLowerCase())\n .join(' ')\n\n // Capitalize the first letter of the resulting string\n result = upperFirst(result)\n\n return result\n}\n\n/**\n * Sanitizes a string to be a valid Excel ListObject (table) column name.\n * - Removes illegal characters: [ ] : ? * / \\\n * - Trims leading/trailing spaces\n * - Replaces multiple spaces with a single space\n * - If the result is empty, returns a default name\n */\nexport function toExcelColumnName(input: string, defaultName = 'Column1'): string {\n // Remove illegal characters: [ ] : ? * / \\\n let result = input.replace(/[[\\]:?*/\\\\]/g, '')\n\n // Replace multiple spaces with a single space\n result = result.replace(/\\s+/g, ' ')\n\n // Trim leading/trailing spaces\n result = result.trim()\n\n // If the result is empty, return the default name\n if (!result) {\n return toExcelColumnName(defaultName, 'Column1')\n }\n\n return result\n}\n\n/**\n * Sanitizes a string to be a valid Excel ListObject (table) name.\n * - Must start with a letter, underscore, or backslash\n * - Only letters, numbers, and underscores allowed (no spaces or punctuation)\n * - Cannot be a cell reference (e.g., \"A1\")\n * - Max 255 characters\n * - If invalid or empty, returns a default name\n */\nexport function toExcelTableName(input: string, defaultName = 'Table1'): string {\n // Remove all characters except letters, numbers, and underscores\n let result = input.replace(/[^A-Za-z0-9_\\\\]/g, '')\n\n // Ensure the name starts with a letter, underscore, or backslash\n if (!/^[A-Za-z_\\\\]/.test(result)) {\n result = '_' + result\n }\n\n // Truncate to 255 characters\n result = result.slice(0, 255)\n\n // Avoid names that look like cell references (e.g., \"A1\", \"AA100\")\n if (/^[A-Za-z]{1,3}[1-9][0-9]{0,6}$/.test(result)) {\n result = '_' + result\n }\n\n // If the result is empty, use the default name\n if (!result || result === '_') {\n return toExcelTableName(defaultName, 'Table1')\n }\n\n return result\n}\n\nexport type Conjugated = {\n camelCase: string\n camelCasePlural: string\n capitalized: string\n capitalizedPlural: string\n kebabCase: string\n kebabCasePlural: string\n PascalCase: string\n PascalCasePlural: string\n pluralized: string\n snake_case_plural: string\n snake_case: string\n uncapitalized: string\n uncapitalizedPlural: string\n}\n\n/**\n * Provide all relevant conjugation of a name\n */\nexport function conjugateNames(name: string): Conjugated {\n const plural = pluralize(name)\n return {\n camelCase: toCamelCase(name),\n camelCasePlural: toCamelCase(plural),\n capitalized: capitalize(name),\n capitalizedPlural: capitalize(plural),\n kebabCase: toKebabCase(name),\n kebabCasePlural: toKebabCase(plural),\n PascalCase: toPascalCase(name),\n PascalCasePlural: toPascalCase(plural),\n pluralized: capitalize(plural),\n snake_case_plural: toSnakeCase(plural),\n snake_case: toSnakeCase(name),\n uncapitalized: uncapitalize(name),\n uncapitalizedPlural: uncapitalize(plural),\n }\n}\n\nexport function slugify(str: string): string {\n return (\n str\n // replace uppercase letters with hyphens and letter (will be lowercased later)\n .replace(/([A-Z])/g, '-$1')\n .toLowerCase()\n // replace letter followed by number with letter-number\n .replace(/([a-z])(\\d)/g, '$1-$2')\n // replace non-alphanumeric characters with hyphens\n .replace(/[^a-z0-9]+/g, '-')\n // remove leading hyphens\n .replace(/^-/g, '')\n // remove trailing hyphens\n .replace(/-$/g, '')\n // replace multiple hyphens with a single hyphen\n .replace(/-+/g, '-')\n )\n}\n\nexport function isSlug(str: string): boolean {\n return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(str)\n}\n\n/**\n * Ensures that a string is unique within a list of existing values by appending a sequential number if necessary.\n *\n * If the base string is not in the list, it is returned as is.\n * If it is, the function looks for existing strings in the format \"base (n)\" where n is a number,\n * and returns the next available sequential string.\n *\n * @param value - The base string to ensure uniqueness for.\n * @param existingValues - An array of existing strings to check against.\n * @param maxChecks - Maximum number of checks to be performed. An error is thrown if this limit is exceeded. Default is 100\n * @returns A unique string based on the base string.\n */\nexport const ensureUnique = (value: string, existingValues: string[], maxChecks = 100): string => {\n // convert existingValues to a Set for faster lookup\n const values = new Set(existingValues)\n\n // if the base itself (without a number) is not in the list, return it\n if (!values.has(value)) {\n return value\n }\n\n let base = value.trim()\n let num = 0\n\n // Regex to match a numeric suffix like \" (n)\" at the end of the string.\n // Using a targeted pattern avoids catastrophic backtracking for inputs without such a suffix.\n const m = /\\((\\d{1,5})\\)$/.exec(value)\n if (m && /\\s$/.test(value.slice(0, m.index))) {\n base = value.slice(0, m.index).trimEnd()\n }\n\n while (num < maxChecks) {\n const newValue = num === 0 ? base : `${base} (${num})`\n if (!values.has(newValue)) {\n return newValue\n }\n num++\n }\n throw new Error(`Could not find a unique name for \"${value}\" after ${maxChecks} checks`)\n}\n","// Source: https://stackoverflow.com/a/53229857/1867581\ntype Without<T, U> = Partial<Record<Exclude<keyof T, keyof U>, never>>\nexport type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U\n\n// Source: see workaround in https://github.com/Microsoft/TypeScript/issues/12936#issuecomment-1061725873\nexport type Exact<T, I> = T extends I ? (Exclude<keyof T, keyof I> extends never ? T : never) : never\n\nexport type UncapitalizeObjectKeys<T> = {\n [key in keyof T as Uncapitalize<key & string>]: T[key]\n}\n// Source: https://twitter.com/mattpocockuk/status/1622730173446557697\nexport type Prettify<T> = {\n [K in keyof T]: T[K]\n}\n\n/**\n * Distributive Pick - does not collapse unions into a \"shared type\" only to\n * run Pick on it. Instead, it \"picks\" from each union item separately.\n *\n * See https://github.com/klimashkin/css-modules-theme/pull/8\n *\n * Example:\n * Pick<{ type: \"pick\" } | { type: \"omit\" }, \"type\">\n * produces { type: \"pick\" | \"omit\" }\n *\n * UnionPick<{ type: \"pick\" } | { type: \"omit\" }, \"type\">\n * produces { type: \"pick\" } | { type: \"omit\" }\n */\nexport type UnionPick<T, K extends keyof T> = T extends unknown ? Pick<T, K> : never\n\n/**\n * Like UnionPick, but for Omit\n */\nexport type UnionOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never\n\n/**\n * Makes a type check that is only valid when all cases of a switch\n * statement have been covered.\n */\nexport class ExhaustiveSwitchCheck extends Error {\n constructor(val: never) {\n super(`Unreachable case: ${JSON.stringify(val)}`)\n }\n}\n\n/**\n * A type that represents an array that is guaranteed to have at least one element.\n */\nexport type NonEmptyArray<T> = [T, ...T[]]\n\n/**\n * Converts a nested object to a nested object where all properties are optional.\n */\nexport type DeepPartial<T> = T extends object\n ? {\n [P in keyof T]?: DeepPartial<T[P]>\n }\n : T\n\n/**\n * Changes properties of an object type to optional.\n *\n * Example:\n * type Foo = { a: string, b: number, c: boolean }\n * type Bar = Optional<Foo, 'a' | 'b'>\n * // Bar is { a?: string, b?: number, c: boolean }\n */\nexport type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\n\n/**\n * Allows inline type assertions.\n *\n * Example:\n * ```\n * type Original = { a: number }\n * type WithExtra = Original & { b: string }\n *\n * function addExtra(obj: Original): asserts obj is WithExtra {\n * assertType(obj)\n * obj.b = 'new value' // ✅ No TypeScript error!\n * }\n * ```\n */\nexport function assertType<T>(value: unknown): asserts value is T {\n return value as any\n}\n\n/**\n * Applies a type assertion to an entire array and hence asserts the array.\n *\n * Type assertions are especially useful when you want to modify and object in place - a function\n * with a type assertion lets TypeScript know that the object was modified.\n *\n * Example:\n * ```\n * type Original = { a: number }\n * type WithExtra = Original & { b: string }\n *\n * function addExtra(obj: Original): asserts obj is WithExtra {\n * obj.b = 'new value'\n * }\n *\n * const myObj: Original[] = [{ a: 1 }]\n * console.log(myObj[0].b) // ❌ TypeScript error!\n * assertArray(myObj, addExtra)\n * console.log(myObj[0].b) // ✅ No TypeScript error!\n * ```\n */\nexport function assertArray<I, O extends I>(obj: I[], fn: (i: I) => asserts i is O): asserts obj is O[] {\n obj.forEach(fn)\n}\n\n/**\n * Converts any branded string type to its underlying string type.\n */\nexport type Debrand<T> = T extends string & infer _U ? string : T extends object ? { [K in keyof T]: Debrand<T[K]> } : T\n","export function uniq<T>(items: T[], predicate: (item: T) => number): T[] {\n const result: T[] = []\n const seen: Record<string, true> = {}\n\n for (const item of items) {\n const key = predicate(item)\n\n if (!seen[key]) {\n seen[key] = true\n result.push(item)\n }\n }\n\n return result\n}\n","import { z } from 'zod'\n\nexport type Transformer<Input, Output> = (value: Input, ctx: z.RefinementCtx) => Output | z.ZodNever\n\ntype ReturnTypeOfLast<T extends any[]> = T extends [...any, infer L]\n ? L extends (...args: any) => any\n ? ReturnType<L>\n : never\n : never\n\n/**\n * Pipes a list of Zod transformers together in a type-safe way. Returns early if any of the transformers returns `z.NEVER`.\n */\nexport function pipeZodTransformers<Initial, Fns extends [Transformer<any, any>, ...Transformer<any, any>[]]>(\n initialValue: Initial,\n ctx: z.RefinementCtx,\n fns: Fns,\n): ReturnTypeOfLast<Fns> {\n let result: any = initialValue\n for (const fn of fns) {\n result = fn(result, ctx)\n if (result === z.NEVER || result.status === 'aborted') {\n return z.NEVER\n }\n }\n return result\n}\n\n/**\n * Returns a Zod error callback that returns the given message for union errors.\n *\n * This is useful for generating meaningful error messages for unions, e.g.\n * ```\n * z.union(\n * [z.constant('foo'), z.constant('bar')],\n * unionErrorMessage('Value must be either \"foo\" or \"bar\"!')\n * )\n * ```\n *\n * In addition to a static message, you can also pass a function that takes the\n * invalid data as input and returns a string. Example:\n * ```\n * z.union(\n * [z.constant('foo'), z.constant('bar')],\n * unionErrorMessage((data) => `Value must be either \"foo\" or \"bar\" - received ${JSON.stringify(data)} instead!`)\n * )\n * ```\n */\nexport function unionErrorMessage(param: string | ((data: unknown) => string)) {\n return {\n error: (issue: any): string => {\n if (typeof param === 'string') {\n return param\n }\n return param(issue.input)\n },\n }\n}\n","import z from 'zod'\n\nimport { isDate } from './datetime'\n\n/**\n * Transformer that verifies that the number is an integer\n */\nconst intValidator = (x: number, ctx: z.RefinementCtx): number => {\n if (x % 1 !== 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not an integer: ${x}`,\n })\n return z.NEVER\n }\n return x\n}\n\n/**\n * Converts any transformer to a nullable transformer, i.e. if the input is\n * null or undefined, the output will be nullable. Else the original transformer\n * is applied\n */\nconst nullableTransformer =\n <I, O>(transformer: (x: I, ctx: z.RefinementCtx) => O) =>\n (x: I | undefined | null, ctx: z.RefinementCtx): O | null => {\n if (x === null || x === undefined || (typeof x === 'string' && x === '')) {\n return null\n }\n return transformer(x, ctx)\n }\n\n/**\n * A decoder that transforms Excel strings to JS strings, also handling numbers and boolean. Will not parse any other type!\n *\n * Background: In Excel, entering a number in a cell will automatically convert it to a number -\n * and xlPort will return it as a number. However, often we want to treat it as a string - this decoder\n * hence accepts both strings and numbers, and converts numbers to strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be converted to a string\n * - If the value is a string, it'll be returned as-is\n * - If the value is boolean, it'll return 'true' or 'false'\n *\n * Any other type will throw an error!\n */\nexport const excelStringStrictDecoder = z\n .union([z.string(), z.number(), z.boolean()])\n .transform((x: string | number | boolean): string => {\n if (typeof x === 'number') {\n return x.toString()\n }\n if (typeof x === 'boolean') {\n return x ? 'true' : 'false'\n }\n return x\n })\n\n/**\n * A decoder that transforms Excel strings to JS strings, also handling numbers and any other potential type\n *\n * Background: In Excel, entering a number in a cell will automatically convert it to a number -\n * and xlPort will return it as a number. However, often we want to treat it as a string - this decoder\n * hence accepts both strings and numbers, and converts numbers to strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be converted to a string\n * - If the value is a string, it'll be returned as-is\n * - If the value is boolean, it'll return 'true' or 'false'\n * - If the value is null or undefined, it'll return an empty string\n * - If the value is any other type, it'll return an empty string\n *\n * Null handling: Null values/blank cells will be converted to a blank string.\n */\nexport const excelStringDecoder = z.preprocess((x): string => {\n if (x === null || x === undefined) {\n return ''\n }\n if (typeof x === 'number') {\n return x.toString()\n }\n if (typeof x === 'boolean') {\n return x ? 'true' : 'false'\n }\n if (typeof x === 'string') {\n return x\n }\n return ''\n}, z.string())\n\n/**\n * A decoder that transforms Excel strings to JS strings, also handling numbers and null\n *\n * Background: In Excel, entering a number in a cell will automatically convert it to a number -\n * and xlPort will return it as a number. However, often we want to treat it as a string - this decoder\n * hence accepts both strings and numbers, and converts numbers to strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be converted to a string\n * - If the value is a string, it'll be returned as-is - except blank strings, which will be converted to null\n * - If the value is boolean, it'll return 'true' or 'false'\n * - If the value is null or undefined, it'll return null\n * - If the value is any other type, it'll return null\n *\n * Null handling: Blank strings will be converted to null. This is to reflect that in Excel a formula\n * cannot return null. As a workaround, one often returns a blank string to represent null.\n */\nexport const excelStringNullableDecoder = z.preprocess((x): string | null => {\n if (x === null || x === undefined) {\n return null\n }\n if (typeof x === 'number') {\n return x.toString()\n }\n if (typeof x === 'boolean') {\n return x ? 'true' : 'false'\n }\n if (typeof x === 'string') {\n if (x === '') {\n return null\n }\n return x\n }\n return null\n}, z.string().nullable())\n\nconst excelNumberTransformer = (x: any): number | null => {\n if (typeof x === 'string') {\n if (x.trim() === '') {\n return null\n }\n const parsed = parseFloat(x)\n if (Number.isNaN(parsed)) {\n return null\n }\n return parsed\n }\n if (typeof x === 'boolean') {\n return x ? 1 : 0\n }\n if (typeof x === 'number') {\n return x\n }\n\n return null\n}\n/**\n * A decoder that transforms Excel numbers to JS numbers, also handling strings and boolean. Will not parse any other type!\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be returned as-is\n * - If the value is a string, it'll try to parse it to a number. Blank strings will be converted to 0. Non-numeric strings will throw an error.\n * - If the value is boolean, it'll return 1 or 0\n * - If the value is any other type, it'll throw an error\n *\n */\nexport const excelNumberStrictDecoder = z.union([z.string(), z.number(), z.boolean()]).transform((x, ctx): number => {\n const result = excelNumberTransformer(x)\n if (result === null) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not a number: ${x}`,\n })\n return z.NEVER\n }\n return result\n})\n\n/**\n * A decoder that transforms Excel numbers to JS numbers, also handling strings, boolean and other types.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be returned as-is\n * - If the value is a string, it'll try to parse it to a number. Blank strings and non-numerical strings will be converted to 0.\n * - If the value is boolean, it'll return 1 or 0\n * - If the value is any other type, it'll return 0\n *\n * Null handling: Null values/blank cells will be converted to blank strings.\n */\nexport const excelNumberDecoder = z.preprocess((x): number => {\n const result = excelNumberTransformer(x)\n if (result === null) {\n return 0\n }\n return result\n}, z.number())\n\n/**\n * A decoder that transforms Excel numbers to JS numbers, also handling strings, boolean and other types.\n\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be returned as-is\n * - If the value is a string, it'll try to parse it to a number. Non-numerical and blank strings will be converted to null\n * - If the value is boolean, it'll return 1 or 0\n * - If the value is any other type, it'll return null\n *\n * Null handling: Blank strings will be converted to null. This is to reflect that in Excel a formula\n * cannot return null. As a workaround, one often returns a blank string to represent null.\n */\nexport const excelNumberNullableDecoder = z.preprocess(excelNumberTransformer, z.number().nullable())\n\n/**\n * A decoder that transforms Excel numbers to JS integers, also handling strings and boolean. Other types will throw an error.\n *\n * If the number is not an integer, an error will be thrown.\n */\nexport const excelIntStrictDecoder = excelNumberStrictDecoder.transform(intValidator)\n\n/**\n * A decoder that transforms Excel numbers to JS integers, also handling strings and boolean. Other types will be converted to 0.\n *\n * If the number is not an integer, an error will be thrown.\n */\nexport const excelIntDecoder = excelNumberDecoder.transform(intValidator)\n\n/**\n * A decoder that transforms Excel numbers to JS integers, also handling strings and boolean. Other types will be converted to null.\n *\n * If the number is not an integer, an error will be thrown.\n */\nexport const excelIntNullableDecoder = excelNumberNullableDecoder.transform(nullableTransformer(intValidator))\n\n// TODO: Add BigInt tests (to be investigated, how Excel handles BigInts)\nconst bigIntTransformer = (x: number, ctx: z.RefinementCtx): bigint => {\n if (x % 1 !== 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not an integer: ${x}`,\n })\n return z.NEVER\n }\n return BigInt(x)\n}\n\n/**\n * A decoder that transforms Excel numbers to JS BigInts, also handling strings and boolean. Other types will throw an error.\n *\n * If the number is not a (big) integer, an error will be thrown.\n */\nexport const excelBigIntStrictDecoder = excelNumberStrictDecoder.transform(bigIntTransformer)\n\n/**\n * A decoder that transforms Excel numbers to JS BigInts, also handling strings and boolean. Other types will be converted to 0.\n *\n * If the number is not a (big) integer, an error will be thrown.\n */\nexport const excelBigIntDecoder = excelNumberDecoder.transform(bigIntTransformer)\n\n/**\n * A decoder that transforms Excel numbers to JS BigInts, also handling strings and boolean. Other types will be converted to null.\n *\n * If the number is not a (big) integer, an error will be thrown.\n */\nexport const excelBigIntNullableDecoder = excelNumberNullableDecoder.transform(nullableTransformer(bigIntTransformer))\n\nconst excelBooleanNullableTransformer = (x: any): boolean | null => {\n if (typeof x === 'number') {\n return x !== 0\n }\n\n if (typeof x === 'string') {\n switch (x.toLowerCase()) {\n case 'true':\n case '1':\n return true\n case 'false':\n case '0':\n return false\n default:\n return null\n }\n }\n\n if (typeof x === 'boolean') {\n return x\n }\n\n return null\n}\n\n/**\n * A decoder that transforms Excel booleans to JS booleans, also handling numbers and strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll return true if it's not 0\n * - If the value is a string, it'll return true if it's 'true' or '1', false if it's 'false' or '0', and throw an error otherwise\n * - If the value is boolean, it'll return it as-is\n * - If the value is any other type, it'll throw an error\n */\nexport const excelBooleanStrictDecoder = z.union([z.boolean(), z.number(), z.string()]).transform((x, ctx): boolean => {\n const result = excelBooleanNullableTransformer(x)\n if (result === null) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not a boolean: ${x}`,\n })\n return z.NEVER\n }\n\n return result\n})\n\n/**\n * A decoder that transforms Excel booleans to JS booleans, also handling numbers and strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll return true if it's not 0\n * - If the value is a string, it'll return true if it's 'true' or '1', false otherwise\n * - If the value is boolean, it'll return it as-is\n * - If the value is any other type, it'll return false\n */\nexport const excelBooleanDecoder = z.preprocess((x): boolean => {\n const result = excelBooleanNullableTransformer(x)\n if (result === null) {\n return false\n }\n\n return result\n}, z.boolean())\n\n/**\n * A decoder that transforms Excel booleans to JS booleans, also handling numbers and strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll return true if it's not 0\n * - If the value is a string, it'll return true if it's 'true' or '1', false if it's 'false' or '0', and null otherwise\n * - If the value is boolean, it'll return it as-is\n * - If the value is any other type, it'll return null\n */\nexport const excelBooleanNullableDecoder = z.preprocess(excelBooleanNullableTransformer, z.boolean().nullable())\n\nconst excelDateNullableTransformer = (x: any, ctx: z.RefinementCtx): Date | null => {\n if (x === null || x === undefined) {\n return null\n }\n\n if (isDate(x)) {\n return x\n }\n\n if (typeof x === 'number') {\n // Excel number is a float with 1 representing Jan 1, 1900. Each increment is a day.\n // As Excel incorrectly ignores the 1900 leap year, we need to correct for that\n const date = new Date(Date.UTC(1900, 0, 1))\n date.setUTCDate(date.getDate() + x - 2)\n\n const fractionalDay = x - Math.floor(x)\n date.setMilliseconds(date.getMilliseconds() + fractionalDay * 24 * 60 * 60 * 1000)\n\n return date\n }\n\n if (typeof x === 'string') {\n if (typeof x === 'string' && x.trim() === '') {\n return null\n }\n const result = new Date(x)\n if (Number.isNaN(result.getTime())) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not a date: ${x}`,\n })\n return z.NEVER\n }\n return result\n }\n return null\n}\n\n/**\n * A decoder that transforms Excel dates to JS Dates\n */\nexport const excelDateDecoder = z.union([z.date(), z.number(), z.string()]).transform((x, ctx): Date => {\n const result = excelDateNullableTransformer(x, ctx)\n if (result === null) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not a date: ${x.toString()}`,\n })\n return z.NEVER\n }\n return result\n})\n\n/**\n * A decoder that transforms nullable Excel dates to JS Dates\n */\nexport const excelDateNullableDecoder = z.preprocess(\n (x, ctx) => excelDateNullableTransformer(x, ctx as z.RefinementCtx),\n z.date().nullable(),\n)\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postxl/utils",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Shared utility functions for PostXL code generation framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -42,7 +42,7 @@
42
42
  "dist"
43
43
  ],
44
44
  "dependencies": {
45
- "zod": "3.25.76"
45
+ "zod": "4.3.5"
46
46
  },
47
47
  "devDependencies": {
48
48
  "tsconfig-paths": "4.2.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"zod-excel.decoders-BJliEI1Y.js","names":["_default: () => Value","key: Key","getKey1: (item: Item) => Key1","getKey2: (item: Item) => Key2","items: Item[]","key1: Key1","key2: Key2","item: Item","values: Item[]","entries: [Key1, Key2, Item][]","mappings: {\n [Model in keyof Identifiers]?: Mapping<Identifiers[Model]>\n }","newId: Identifiers[Model]","arr: T[]","value: T","predicate: (t: T) => number","arr: T[]","iterator: AsyncMapFn<T, R>","result: (R | undefined)[]","array: T[]","id: number | string","gen: ArrayGen<T>","mapFn: AsyncMapFn<T, R>","a: string | Buffer","b: string | Buffer","value: unknown","data: Value[]","keyFn: (item: Value) => Key","result: Dictionary<Value, Key>","data: T[]","result: Dictionary<T>","dict: Dictionary<S>","predicate: (item: S) => T","dict: Dictionary<T>","predicate: (item: T) => boolean","dict: Dictionary<Value>","key: Key","n: number","predicate: (x: T) => U","items: T[]","result: Partial<Record<U, T[]>>","predicate: (x: WithId) => GroupId","items: WithId[]","result: Partial<Record<GroupId, Record<Id, WithId>>>","getGroupId: (x: T) => GroupID","map: Map<Key, ValueFrom>","predicate: (item: ValueFrom, key: Key) => ValueTo","result: ValueTo[]","map: Map<KeyFrom, ValueFrom>","keyPredicate: (key: KeyFrom, value: ValueFrom) => KeyTo","valuePredicate: (item: ValueFrom, key: KeyFrom) => ValueTo","map: Map<KeyFrom, Value>","keyPredicate: (key: KeyFrom, value: Value) => KeyTo","map: Map<Key, Value>","predicate: (item: Value, key: Key) => boolean","key: Key","obj: T","key: string","items: Item[]","skip?: number","take?: number","max: number","value: number","length: number","value: unknown","config: T","newConfig: Record<string, unknown>","key: string","value: unknown","value: string","connection: string","password: string","obj: T","value: A","value: E","f: () => A","handleError: (error: Error) => E","result: SerializedResult<A, E>","promise: () => Promise<A>","#tag","#value","#error","tag: 'ok' | 'err'","value: A | E","f: (a: A) => B","f: (e: E) => X","f: (a: A) => Result<B, E>","fallback: A","items: Item[]","dir: Direction","compareFn: CompareFn<Item>","key: keyof T","getter: Getter<T>","data: T","compareValues: CompareFn<unknown>","compareDates: CompareFn<Date>","compareStrings: CompareFn<string>","compareNumbers: CompareFn<number>","compareBooleans: CompareFn<boolean>","bool: boolean","input: string","s: string","IRREGULAR_PLURALS: [singular: string, plural: string][]","obj: T","str: string","lines: string","input: string","name: string","value: string","existingValues: string[]","val: never","value: unknown","obj: I[]","fn: (i: I) => asserts i is O","items: T[]","predicate: (item: T) => number","result: T[]","seen: Record<string, true>","initialValue: Initial","ctx: z.RefinementCtx","fns: Fns","result: any","param: string | ((data: any) => string)","message: string","x: number","ctx: z.RefinementCtx","transformer: (x: I, ctx: z.RefinementCtx) => O","x: I | undefined | null","excelStringStrictDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>,\n string,\n string | number | boolean // NOSONAR\n>","x: string | number | boolean","excelStringDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodAny]>,\n string,\n any\n>","excelStringNullableDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodAny]>,\n string | null,\n any\n>","x: any","excelNumberStrictDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>,\n number,\n string | number | boolean\n>","excelNumberDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodAny]>,\n number,\n any\n>","excelNumberNullableDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNull, z.ZodNumber, z.ZodUndefined, z.ZodAny]>,\n number | null,\n any\n>","excelIntStrictDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>, number, string | number | boolean>,\n number,\n string | number | boolean\n>","excelIntDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodAny]>, number, any>,\n number,\n any\n>","excelIntNullableDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNull, z.ZodNumber, z.ZodUndefined, z.ZodAny]>, number | null, any>,\n number | null,\n any\n>","excelBigIntStrictDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>, number, string | number | boolean>,\n bigint,\n string | number | boolean\n>","excelBigIntDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodAny]>, number, any>,\n bigint,\n any\n>","excelBigIntNullableDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNull, z.ZodNumber, z.ZodUndefined, z.ZodAny]>, number | null, any>,\n bigint | null,\n any\n>","excelBooleanStrictDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodBoolean, z.ZodNumber, z.ZodString]>,\n boolean,\n string | number | boolean\n>","excelBooleanDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodBoolean, z.ZodNumber, z.ZodNull, z.ZodString, z.ZodUndefined, z.ZodAny]>,\n boolean,\n any\n>","excelBooleanNullableDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodBoolean, z.ZodNumber, z.ZodNull, z.ZodString, z.ZodUndefined, z.ZodAny]>,\n boolean | null,\n any\n>","excelDateDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodDate, z.ZodNumber, z.ZodString]>,\n Date,\n string | number | Date\n>","excelDateNullableDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodDate, z.ZodString, z.ZodNumber, z.ZodNull, z.ZodUndefined, z.ZodAny]>,\n Date | null,\n any\n>"],"sources":["../src/DefaultMap.ts","../src/NestedMap.ts","../src/TypedMapping.ts","../src/array.ts","../src/async.ts","../src/buffer.ts","../src/datetime.ts","../src/dictionary.ts","../src/format.ts","../src/group-by.ts","../src/map.ts","../src/omit.ts","../src/pagination.ts","../src/random.ts","../src/is-object.ts","../src/remove-secrets.ts","../src/remove-undefined.ts","../src/result.ts","../src/sort.ts","../src/string-colors.ts","../src/string.ts","../src/types.ts","../src/uniq.ts","../src/zod.ts","../src/zod-excel.decoders.ts"],"sourcesContent":["/**\n * A map extension that returns a default value if the key is not found.\n */\nexport class DefaultMap<Key, Value> extends Map<Key, Value> {\n /**\n * A function that returns the default value for the map.\n */\n\n constructor(private readonly _default: () => Value) {\n super()\n }\n\n override get(key: Key): Value {\n const value = super.get(key)\n if (value) {\n return value\n }\n\n const defaultValue = this._default()\n this.set(key, defaultValue)\n\n return defaultValue\n }\n}\n","export class NestedMap<Key1, Key2, Item> {\n private readonly _map = new Map<Key1, Map<Key2, Item>>()\n\n constructor(\n private readonly getKey1: (item: Item) => Key1,\n private readonly getKey2: (item: Item) => Key2,\n items: Item[] = [],\n ) {\n for (const item of items) {\n this.set(item)\n }\n }\n get(key1: Key1, key2: Key2): Item | undefined {\n const map = this._map.get(key1)\n if (!map) {\n return undefined\n }\n return map.get(key2)\n }\n\n private getKeys(item: Item): [Key1, Key2] {\n return [this.getKey1(item), this.getKey2(item)]\n }\n set(item: Item): void {\n const [key1, key2] = this.getKeys(item)\n\n let map = this._map.get(key1)\n if (!map) {\n map = new Map<Key2, Item>()\n this._map.set(key1, map)\n }\n map.set(key2, item)\n }\n\n delete(item: Item): void {\n const [key1, key2] = this.getKeys(item)\n const map = this._map.get(key1)\n if (!map) {\n return\n }\n map.delete(key2)\n }\n\n clear(): void {\n this._map.clear()\n }\n\n get size(): number {\n return Array.from(this._map.values()).reduce((sum, map) => sum + map.size, 0)\n }\n\n get keys(): Iterable<Key1> {\n return this._map.keys()\n }\n\n get values(): Iterable<Item> {\n const values: Item[] = []\n for (const map of this._map.values()) {\n for (const value of map.values()) {\n values.push(value)\n }\n }\n return values\n }\n\n get entries(): Iterable<[Key1, Key2, Item]> {\n const entries: [Key1, Key2, Item][] = []\n for (const [key1, map] of this._map.entries()) {\n for (const [key2, value] of map.entries()) {\n entries.push([key1, key2, value])\n }\n }\n return entries\n }\n\n get [Symbol.iterator](): Iterable<[Key1, Key2, Item]> {\n return this.entries\n }\n}\n","type IdentifiersBase = Record<string, string>\n\ntype Mapping<T> = Map<T, T>\n\n/**\n * A map of typed mappings.\n */\nexport class TypedMapping<Identifiers extends IdentifiersBase> {\n private mappings: {\n [Model in keyof Identifiers]?: Mapping<Identifiers[Model]>\n }\n\n constructor(\n mappings: {\n [Model in keyof Identifiers]?: Mapping<Identifiers[Model]>\n } = {},\n ) {\n this.mappings = mappings\n }\n\n /**\n * Creates a new mapping from the original id to the new id.\n */\n public set<Model extends keyof Identifiers>(\n { model, id }: { model: Model; id: Identifiers[Model] },\n newId: Identifiers[Model],\n ): this {\n if (!this.mappings[model]) {\n this.mappings[model] = new Map()\n }\n\n this.mappings[model]!.set(id, newId)\n\n return this\n }\n\n /**\n * Returns the id if there exists a mapping, otherwise returns the original id.\n */\n public get<Model extends keyof Identifiers>({\n model,\n id,\n }: {\n model: Model\n id: Identifiers[Model]\n }): Identifiers[Model] {\n const mapping = this.mappings[model]?.get(id)\n if (!mapping) {\n return id\n }\n return mapping\n }\n}\n","/**\n * Adds a value to a sorted array and keeps the array sorted.\n *\n * O(n)\n */\nexport function addAndSort<T>(arr: T[], value: T, predicate: (t: T) => number): T[] {\n arr.push(value)\n\n let i = arr.length - 1\n const item = arr[i] as T\n const order = predicate(item)\n\n while (i > 0 && order < predicate(arr[i - 1] as T)) {\n arr[i] = arr[i - 1] as T\n i -= 1\n }\n arr[i] = item\n\n return arr\n}\n","//Credit: https://codeburst.io/async-map-with-limited-parallelism-in-node-js-2b91bd47af70\n\nconst defaultConcurrency = 5\ntype AsyncMapFn<T, R> = (item: T, index: number) => Promise<R>\ntype ArrayGen<T> = Generator<[T | undefined, number], void, void>\n\n// async maps over all values of an array but limits the number of concurrent operations\nexport async function mapLimit<T, R>(\n arr: T[],\n iterator: AsyncMapFn<T, R>,\n limit = defaultConcurrency,\n): Promise<(R | undefined)[]> {\n const result: (R | undefined)[] = []\n if (arr.length === 0) {\n return result\n }\n\n const generator = arrayGenerator(arr)\n\n limit = Math.min(limit, arr.length)\n const workers = new Array(limit)\n\n for (let i = 0; i < limit; i++) {\n workers.push(worker(i, generator, iterator, result))\n }\n\n await Promise.all(workers)\n\n return result\n}\n\nfunction* arrayGenerator<T>(array: T[]): ArrayGen<T> {\n for (let index = 0; index < array.length; index++) {\n const currentValue = array[index]\n yield [currentValue, index]\n }\n}\n\nasync function worker<T, R>(\n id: number | string,\n gen: ArrayGen<T>,\n mapFn: AsyncMapFn<T, R>,\n result: (R | undefined)[],\n): Promise<void> {\n for (const [currentValue, index] of gen) {\n result[index] = undefined\n if (currentValue === undefined) {\n return\n }\n try {\n result[index] = await mapFn(currentValue, index)\n } catch (e) {\n console.error(`Worker ${id} --- index ${index} item ${JSON.stringify(currentValue)} failed`, e)\n }\n }\n}\n","/**\n * Compares two string or buffer values for equality.\n */\nexport function equals(a: string | Buffer, b: string | Buffer): boolean {\n if (typeof a === 'string' && typeof b === 'string') {\n return a === b\n }\n\n if (Buffer.isBuffer(a) && Buffer.isBuffer(b)) {\n return a.equals(b)\n }\n\n return false\n}\n","/**\n * returns the default time stamp in format YYMMDD HHMM\n */\nexport function timeStamp(): string {\n const date = new Date()\n const year = date.getFullYear().toString().slice(-2)\n const month = (date.getMonth() + 1).toString().padStart(2, '0')\n const day = date.getDate().toString().padStart(2, '0')\n const hour = date.getHours().toString().padStart(2, '0')\n const minute = date.getMinutes().toString().padStart(2, '0')\n return `${year}${month}${day} ${hour}${minute}`\n}\n\n/**\n * Checks if a value is a valid Date object.\n * Returns true only for Date instances that are not Invalid Date.\n * This function is isomorphic and works in both Node.js and browser environments.\n *\n * @param value - The value to check\n * @returns true if the value is a valid Date object, false otherwise\n *\n * @example\n * isDate(new Date()) // true\n * isDate(new Date('2023-01-01')) // true\n * isDate(new Date('invalid')) // false (Invalid Date)\n * isDate('2023-01-01') // false\n * isDate(1234567890) // false\n * isDate(null) // false\n * isDate(undefined) // false\n */\nexport function isDate(value: unknown): value is Date {\n return value instanceof Date && !Number.isNaN(value.getTime())\n}\n","export type Dictionary<Value, Key extends string = string> = Record<Key, Value>\n\nexport function toDict<Value, Key extends string = string>(\n data: Value[],\n keyFn: (item: Value) => Key,\n): Dictionary<Value, Key> {\n const result: Dictionary<Value, Key> = {} as Dictionary<Value, Key>\n\n for (const item of data) {\n result[keyFn(item)] = item\n }\n return result\n}\n\nexport function idToDict<T extends { id: string | number }>(data: T[]): Dictionary<T> {\n const result: Dictionary<T> = {}\n\n for (const item of data) {\n result[item.id.toString()] = item\n }\n return result\n}\n\nexport function mapDict<S, T>(dict: Dictionary<S>, predicate: (item: S) => T): Dictionary<T> {\n const result: Dictionary<T> = {}\n\n for (const [key, value] of Object.entries(dict)) {\n result[key] = predicate(value)\n }\n return result\n}\n\nexport function filterDict<T>(dict: Dictionary<T>, predicate: (item: T) => boolean): Dictionary<T> {\n const result: Dictionary<T> = {}\n\n for (const [key, value] of Object.entries(dict)) {\n if (predicate(value)) {\n result[key] = value\n }\n }\n return result\n}\n\nexport function dictGetAndAssert<Key extends string, Value>(dict: Dictionary<Value>, key: Key): NonNullable<Value> {\n const value = dict[key]\n if (value === null || value === undefined) {\n throw new Error(`Key ${key} not found`)\n }\n return value as NonNullable<Value>\n}\n","export function format(n: number, locale = 'en-US'): string {\n return new Intl.NumberFormat(locale).format(n)\n}\n","export const groupBy = <T, U extends string | number>(predicate: (x: T) => U, items: T[]): Partial<Record<U, T[]>> => {\n const result: Partial<Record<U, T[]>> = {}\n for (const item of items) {\n const key = predicate(item)\n\n const group = result[key]\n\n if (group === undefined) {\n result[key] = [item]\n } else {\n group.push(item)\n }\n }\n return result\n}\n\nexport const groupByCurried = <T, U extends string | number>(\n predicate: (x: T) => U,\n): ((items: T[]) => Partial<Record<U, T[]>>) => {\n const result: Partial<Record<U, T[]>> = {}\n return (items: T[]) => {\n for (const item of items) {\n const key = predicate(item)\n\n const group = result[key]\n\n if (group === undefined) {\n result[key] = [item]\n } else {\n group.push(item)\n }\n }\n return result\n }\n}\n\nexport const groupByToDict = <Id extends string | number, WithId extends { id: Id }, GroupId extends string | number>(\n predicate: (x: WithId) => GroupId,\n items: WithId[],\n): Partial<Record<GroupId, Record<Id, WithId>>> => {\n const result: Partial<Record<GroupId, Record<Id, WithId>>> = {}\n for (const item of items) {\n const key = predicate(item)\n\n const group = result[key]\n\n if (group === undefined) {\n result[key] = { [item.id]: item } as Record<Id, WithId>\n } else {\n group[item.id] = item\n }\n }\n return result\n}\n\nexport const groupByToMap = <T extends { id: ItemID }, ItemID extends string | number, GroupID extends string | number>(\n getGroupId: (x: T) => GroupID,\n items: T[],\n): Map<GroupID, Map<ItemID, T>> => {\n const result = new Map<GroupID, Map<ItemID, T>>()\n for (const item of items) {\n const groupId = getGroupId(item)\n\n if (!result.has(groupId)) {\n result.set(groupId, new Map())\n }\n\n const group = result.get(groupId)\n if (group !== undefined) {\n group.set(item.id, item)\n }\n }\n return result\n}\n","export function mapMap<Key, ValueFrom, ValueTo>(\n map: Map<Key, ValueFrom>,\n predicate: (item: ValueFrom, key: Key) => ValueTo,\n): Map<Key, ValueTo> {\n const result = new Map<Key, ValueTo>()\n\n for (const [key, value] of map.entries()) {\n result.set(key, predicate(value, key))\n }\n return result\n}\n\nexport function mapMapValues<Key, ValueFrom, ValueTo>(\n map: Map<Key, ValueFrom>,\n predicate: (item: ValueFrom, key: Key) => ValueTo,\n): ValueTo[] {\n const result: ValueTo[] = []\n\n for (const [key, value] of map.entries()) {\n result.push(predicate(value, key))\n }\n return result\n}\n\n/**\n *\n */\nexport function mapMapKeyValues<KeyFrom, KeyTo, ValueFrom, ValueTo>(\n map: Map<KeyFrom, ValueFrom>,\n keyPredicate: (key: KeyFrom, value: ValueFrom) => KeyTo,\n valuePredicate: (item: ValueFrom, key: KeyFrom) => ValueTo,\n): Map<KeyTo, ValueTo> {\n const result = new Map<KeyTo, ValueTo>()\n\n for (const [key, value] of map.entries()) {\n result.set(keyPredicate(key, value), valuePredicate(value, key))\n }\n return result\n}\n\n/**\n * Maps keys of a map.\n */\nexport function mapMapKeys<KeyFrom, KeyTo, Value>(\n map: Map<KeyFrom, Value>,\n keyPredicate: (key: KeyFrom, value: Value) => KeyTo,\n): Map<KeyTo, Value> {\n const result = new Map<KeyTo, Value>()\n\n for (const [key, value] of map.entries()) {\n result.set(keyPredicate(key, value), value)\n }\n return result\n}\n\n/**\n * Filters values from a map.\n */\nexport function filterMap<Key, Value>(\n map: Map<Key, Value>,\n predicate: (item: Value, key: Key) => boolean,\n): Map<Key, Value> {\n const result = new Map<Key, Value>()\n\n for (const [key, value] of map.entries()) {\n if (predicate(value, key)) {\n result.set(key, value)\n }\n }\n\n return result\n}\n\n/**\n * Gets a value from a map and asserts that it exists.\n */\nexport function mapGetAndAssert<Key, Value>(map: Map<Key, Value>, key: Key): Value {\n const value = map.get(key)\n if (!value) {\n throw new Error(`Key ${JSON.stringify(key)} not found`)\n }\n return value\n}\n\n/**\n * Converts a map to a dictionary.\n */\nexport function mapToDict<Key extends string | number, Value>(map: Map<Key, Value>): Record<Key, Value> {\n const result = {} as Record<Key, Value>\n for (const [key, value] of map.entries()) {\n result[key] = value\n }\n return result\n}\n","/**\n * Omits a key from an object\n */\nexport function omit<T extends Record<string, unknown>>(obj: T, key: string): Omit<T, typeof key> {\n const { [key]: _, ...rest } = obj\n return rest\n}\n","export type Page<Item> = { total: number; offset: number; items: Item[] }\n\nexport const slice = <Item>(items: Item[], skip?: number, take?: number): Page<Item> => {\n const start = skip ?? 0\n const end = take ? start + take : undefined\n return {\n total: items.length,\n offset: start,\n items: items.slice(start, end),\n }\n}\n","/**\n * Returns a random integer between 0 (inclusive) and max (exclusive).\n *\n * Isomorphic implementation for Node.js, Deno, Bun, and browser environments.\n * Uses Web Crypto API which is available in all modern JavaScript runtimes.\n */\nexport function randomInt(max: number): number {\n // All modern environments (Node.js 15+, Deno, Bun, browsers) have Web Crypto API\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n return browserRandomInt(max)\n }\n\n throw new Error('No suitable random number generator available')\n}\n\nfunction browserRandomInt(max: number): number {\n // Browser - use rejection sampling to avoid modulo bias\n const randomMax = 0x100000000 // 2^32\n const range = randomMax - (randomMax % max)\n\n let value: number\n do {\n const array = new Uint32Array(1)\n crypto.getRandomValues(array)\n value = array[0]!\n } while (value >= range)\n\n return value % max\n}\n\nconst CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'\n\n/**\n * Returns a randomly generated alphanumeric string.\n */\nexport function generateRandomAlphanumericString(length: number): string {\n let result = ''\n for (let i = 0; i < length; i++) {\n result += CHARS[randomInt(CHARS.length)]\n }\n return result\n}\n","/**\n * Returns true if the value is an object, false otherwise.\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null\n}\n\n/**\n * Only returns true for plain objects, not for classes or functions\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && value.constructor === Object\n}\n\n/**\n * Returns true if the value is a function, false otherwise.\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport function isFunction(value: unknown): value is Function {\n return typeof value === 'function'\n}\n","import { isPlainObject } from './is-object'\n\n/**\n * Removes secrets from the given configuration object.\n *\n * Recursively checks all properties of the object for keys that end with\n * `key`, `secret`, `password`, `token` and replaces them with '***'.\n *\n * Also checks for keys the end with `connection` or `connectionString` and\n * replaces the connection string with the same string but with the password\n * replaced with '***'.\n */\nexport function removeSecrets<T extends Record<string, unknown>>(config: T): T {\n const newConfig: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(config)) {\n newConfig[key] = processValue(key, value)\n }\n return newConfig as T\n}\n\nfunction processValue(key: string, value: unknown): unknown {\n if (typeof value === 'string') {\n return processString(key, value)\n } else if (Array.isArray(value)) {\n return value.map((item) => removeSecrets(item))\n } else if (typeof value === 'object' && isPlainObject(value)) {\n return removeSecrets(value)\n }\n return value\n}\n\nfunction processString(key: string, value: string): string {\n if (key.endsWith('key') || key.endsWith('secret') || key.endsWith('password') || key.endsWith('token')) {\n return hidePassword(value)\n } else if (key.endsWith('connection') || key.endsWith('connectionString')) {\n return hidePasswordInConnectionString(value)\n } else {\n return value\n }\n}\n\nfunction hidePasswordInConnectionString(connection: string): string {\n return (\n connection\n // e.g. postgresql://user:password@host\n .replace(/^(.*):\\/\\/(.*):(.*)@(.*)$/, '$1://$2:***@$4') //NOSONAR - this is only used to parse environment variables, so no risk of external DOS attacks\n // e.g. user:password@host\n .replace(/^(.*):(.*)@(.*)$/, '$1:***@$3') //NOSONAR - this is only used to parse environment variables, so no risk of external DOS attacks\n )\n}\n\nfunction hidePassword(password: string): string {\n if (password === '') {\n return 'nothing provided!'\n }\n if (password === 'secret') {\n return 'default provided!'\n }\n return '***'\n}\n","/**\n * Removes all undefined properties from an object.\n *\n * NOTE: This is useful when using the `Partial<T>` type modifier in combination with the spread operator to prevent\n * overriding with undefined values.\n */\nexport function removeUndefinedProperties<T extends Record<string, unknown>>(\n obj: T,\n): { [K in keyof T]: T[K] extends undefined ? never : T[K] } {\n const newObj = {} as {\n [K in keyof T]: T[K] extends undefined ? never : T[K]\n }\n\n for (const key in obj) {\n const value = obj[key]\n\n if (value !== undefined) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n newObj[key] = value\n }\n }\n\n return newObj\n}\n","export type SerializedResult<A, E> = { tag: 'ok'; value: A } | { tag: 'err'; err: E }\n\nexport class Result<A, E> {\n static ok<A, E>(value: A): Result<A, E> {\n return new Result<A, E>('ok', value)\n }\n\n static err<A, E>(value: E): Result<A, E> {\n return new Result<A, E>('err', value)\n }\n\n static fromThrowable<A, E>(f: () => A, handleError: (error: Error) => E): Result<A, E> {\n try {\n return Result.ok(f())\n } catch (error) {\n return Result.err(handleError(error as Error))\n }\n }\n\n static fromObject<A, E>(result: SerializedResult<A, E>): Result<A, E> {\n if (result.tag === 'ok') {\n return Result.ok(result.value)\n } else {\n return Result.err(result.err)\n }\n }\n\n static async fromPromise<A, E>(promise: () => Promise<A>, handleError: (error: Error) => E): Promise<Result<A, E>> {\n try {\n return Result.ok(await promise())\n } catch (error) {\n return Result.err(handleError(error as Error))\n }\n }\n\n // We track the tag separately from the value and error to allow for us to use\n // `null` as a valid value.\n\n readonly #tag: 'ok' | 'err'\n readonly #value: A | null\n readonly #error: E | null\n\n private constructor(tag: 'ok', value: A)\n private constructor(tag: 'err', value: E)\n private constructor(tag: 'ok' | 'err', value: A | E) {\n this.#tag = tag\n this.#value = tag === 'ok' ? (value as A) : null\n this.#error = tag === 'err' ? (value as E) : null\n }\n\n isOk(): this is Result<A, never> {\n return this.#tag === 'ok'\n }\n\n isErr(): this is Result<never, E> {\n return this.#tag === 'err'\n }\n\n map<B>(f: (a: A) => B): Result<B, E> {\n if (this.#tag === 'ok') {\n return Result.ok(f(this.#value!))\n } else {\n return this as unknown as Result<B, E>\n }\n }\n\n mapErr<X>(f: (e: E) => X): Result<A, X> {\n if (this.#tag === 'err') {\n return Result.err(f(this.#error!))\n } else {\n return this as unknown as Result<A, X>\n }\n }\n\n andThen<B>(f: (a: A) => Result<B, E>): Result<B, E> {\n if (this.#tag === 'ok') {\n return f(this.#value!)\n } else {\n return this as unknown as Result<B, E>\n }\n }\n\n withDefault(fallback: A): A {\n return this.#tag === 'ok' ? this.#value! : fallback\n }\n\n unwrap(): A {\n if (this.#tag === 'ok') {\n return this.#value!\n } else {\n throw new Error(typeof this.#error === 'string' ? this.#error : JSON.stringify(this.#error))\n }\n }\n\n unwrapErr(): E {\n if (this.#tag === 'err') {\n return this.#error!\n } else {\n throw new Error('tried to unwrap an ok result')\n }\n }\n\n toJSON(): SerializedResult<A, E> {\n if (this.#tag === 'ok') {\n return { tag: 'ok', value: this.#value! }\n } else {\n return { tag: 'err', err: this.#error! }\n }\n }\n}\n\nexport const ok = Result.ok\nexport const err = Result.err\n\nexport type TypedError<T extends string> = {\n type: T\n message: string\n error: Error\n}\n\nexport default Result\n","export type CompareFn<T> = (a: T, b: T) => number\n\nexport type Direction = 'asc' | 'desc'\n\nexport const sort = <Item>(items: Item[], dir: Direction = 'asc', compareFn: CompareFn<Item> = compareValues): Item[] =>\n setDirection(items.toSorted(compareFn), dir)\n\n/**\n * Compare fields of an object.\n */\nexport const compareFields = <T>(key: keyof T): CompareFn<T> => {\n return (a, b) => compareValues(a[key], b[key])\n}\n\nexport type Getter<T> = (data: T) => unknown\n\nexport const compare = <T>(getter: Getter<T>): CompareFn<T> => {\n return (a, b) => compareValues(getter(a), getter(b))\n}\n\nexport const keyGetter = <T>(key: keyof T): Getter<T> => {\n return (data: T) => data[key]\n}\n\nexport const compareValues: CompareFn<unknown> = (a, b) => {\n switch (true) {\n // In case one item is undefined or null and the other is not, we place the non-null item first.\n case (a === undefined || a === null) && b !== undefined && b !== null:\n return 1\n\n case (b === undefined || b === null) && a !== undefined && a !== null:\n return -1\n\n case (a === undefined || a === null) && (b === undefined || b === null):\n return 0\n\n case a instanceof Date && b instanceof Date:\n return compareDates(a, b)\n\n case typeof a === 'string' && typeof b === 'string':\n return compareStrings(a, b)\n\n case typeof a === 'number' && typeof b === 'number':\n return compareNumbers(a, b)\n\n case typeof a === 'boolean' && typeof b === 'boolean':\n return compareBooleans(a, b)\n\n default:\n return 0\n }\n}\n\nexport const compareDates: CompareFn<Date> = (a, b) => compareStrings(a.toISOString(), b.toISOString())\n\nexport const compareStrings: CompareFn<string> = (a, b) => {\n const aLower = a.trim().toLowerCase()\n const bLower = b.trim().toLowerCase()\n if (aLower === bLower) {\n return 0\n }\n return aLower > bLower ? 1 : -1\n}\n\nexport const compareNumbers: CompareFn<number> = (a, b) => a - b\n\nexport const compareBooleans: CompareFn<boolean> = (a, b) => booleanCode(a) - booleanCode(b)\n\nexport const booleanCode = (bool: boolean): number => (bool ? 1 : 0)\n\nexport const setDirection = <Item>(items: Item[], dir: Direction): Item[] => {\n return dir === 'desc' ? items.toReversed() : items\n}\n","/**\n * A function that returns a string with a specific color.\n */\nexport type ColorFn = (input: string) => string\n\n/**\n * Colors a string in red color (using ANSI escape codes).\n */\nexport function red(input: string): string {\n return `\\u001b[31m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in green color (using ANSI escape codes).\n */\nexport function green(input: string): string {\n return `\\u001b[32m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in yellow color (using ANSI escape codes).\n */\nexport function yellow(input: string): string {\n return `\\u001b[33m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in blue color (using ANSI escape codes).\n */\nexport function blue(input: string): string {\n return `\\u001b[34m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in cyan color (using ANSI escape codes).\n */\nexport function cyan(input: string): string {\n return `\\u001b[36m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in gray color (using ANSI escape codes).\n */\nexport function gray(input: string): string {\n return `\\u001b[90m${input}\\u001b[39m`\n}\n\n/**\n * Colors a string in bold color (using ANSI escape codes).\n */\nexport function bold(input: string): string {\n return `\\u001b[1m${input}\\u001b[22m`\n}\n\n/**\n * Colors a string in underline color (using ANSI escape codes).\n */\nexport function underline(input: string): string {\n return `\\u001b[4m${input}\\u001b[24m`\n}\n\n/**\n * Colors a string in italic color (using ANSI escape codes).\n */\nexport function italic(input: string): string {\n return `\\u001b[3m${input}\\u001b[23m`\n}\n\n/**\n * Inverts the color of a string (using ANSI escape codes).\n */\nexport function inverse(input: string): string {\n return `\\u001b[7m${input}\\u001b[27m`\n}\n","export function upperFirst(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nexport function lowerFirst(s: string): string {\n return s.charAt(0).toLowerCase() + s.slice(1)\n}\n\nconst IRREGULAR_PLURALS: [singular: string, plural: string][] = Object.entries({\n abyss: 'abysses',\n aegis: 'aegises',\n alias: 'aliases',\n alumnus: 'alumni',\n amends: 'amends',\n analysis: 'analyses',\n apparatus: 'apparatuses',\n appendix: 'appendices',\n asbestos: 'asbestoses',\n atlas: 'atlases',\n axis: 'axes',\n basis: 'bases',\n biceps: 'bicepses',\n bus: 'buses',\n caress: 'caresses',\n child: 'children',\n children: 'children',\n circus: 'circuses',\n citrus: 'citruses',\n compass: 'compasses',\n crisis: 'crises',\n criterion: 'criteria',\n crocus: 'crocuses',\n data: 'data',\n datum: 'data',\n diabetes: 'diabetes',\n diagnosis: 'diagnoses',\n dross: 'drosses',\n egress: 'egresses',\n elvis: 'elvises',\n emboss: 'embosses',\n fiss: 'fisses',\n focus: 'foci',\n glass: 'glasses',\n hippocampus: 'hippocampi',\n // While `histories` is the plural of `history`, in a model context, `history` makes more sense:\n // If you have a model called `UserHistory`, calling the table `UserHistories` would be confusing.\n history: 'history',\n hypothesis: 'hypotheses',\n ignis: 'ignises',\n index: 'indices',\n iris: 'irises',\n jesus: 'jesuses',\n kudos: 'kudos',\n lens: 'lenses',\n man: 'men',\n matrix: 'matrices',\n medium: 'media',\n news: 'news',\n oasis: 'oases',\n parenthesis: 'parentheses',\n pass: 'passes',\n phenomenon: 'phenomena',\n prognosis: 'prognoses',\n radius: 'radii',\n ras: 'rasses',\n sepsis: 'sepses',\n species: 'species',\n status: 'statuses',\n suffix: 'suffixes',\n syllabus: 'syllabi',\n synopsis: 'synopses',\n thesis: 'theses',\n tress: 'tresses',\n virus: 'viruses',\n vortex: 'vortices',\n woman: 'women',\n})\n\n/**\n * Returns a pluralized version of the given string based on the count.\n */\nexport function pluralize(s: string, count = 2): string {\n // If there's one of something we simply use the singular form.\n if (count === 1) {\n return s\n }\n\n // For plural forms, we first check whether a word is irregular.\n const lower = s.toLowerCase()\n for (const [singular, plural] of IRREGULAR_PLURALS) {\n // We check that items *end with* a given word because we use combined words\n // like `UserHistory` as input values of this function.\n if (lower.endsWith(singular)) {\n return s.slice(0, -singular.length + 1) + plural.slice(1)\n }\n }\n\n if (lower.endsWith('ss')) {\n return s.slice(0, -2) + 'sses'\n }\n if (\n // e.g. index\n lower.endsWith('x') ||\n // e.g. buzz\n lower.endsWith('z') ||\n // e.g. wish\n lower.endsWith('sh') ||\n // e.g. match\n lower.endsWith('ch')\n ) {\n return s + 'es'\n }\n\n if (\n s.endsWith('y') &&\n !s.endsWith('ay') &&\n !s.endsWith('ey') &&\n !s.endsWith('iy') &&\n !s.endsWith('oy') &&\n !s.endsWith('uy')\n ) {\n return s.slice(0, -1) + 'ies'\n }\n\n if (s.endsWith('s')) {\n return s\n }\n\n return s + 's'\n}\n\n/**\n * Returns true if the given string is already pluralized.\n */\nexport function isPlural(s: string): boolean {\n const plural = pluralize(s)\n return plural === s\n}\n\n/**\n * Type modifier that converts all keys of an object to capitalized versions.\n */\nexport type CapitalizedKeys<T extends Record<string, unknown>> = {\n [K in keyof T as CapitalizeFirstLetter<string & K>]: T[K]\n}\n\n/**\n * Type modifier that converts the first letter of a string to a capital letter.\n */\ntype CapitalizeFirstLetter<S extends string> = `${Capitalize<Extract<S, string>>}`\n\n/**\n * Converts all keys of an object to capitalized versions in a type-safe way.\n */\nexport function capitalizeKeys<T extends Record<string, unknown>>(obj: T): CapitalizedKeys<T> {\n const result = {} as CapitalizedKeys<T>\n\n for (const key in obj) {\n const cKey = `${key.charAt(0).toUpperCase()}${key.slice(1)}`\n const cVal = obj[key]\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n result[cKey] = cVal\n }\n\n return result\n}\n\n/**\n * Type modifier that converts all keys of an object to uncapitalized versions.\n */\nexport type UncapitalizedKeys<T extends Record<string, unknown>> = {\n [K in keyof T as UncapitalizeFirstLetter<string & K>]: T[K]\n}\n\n/**\n * Type modifier that converts the first letter of a string to an uncapitalized letter.\n */\ntype UncapitalizeFirstLetter<S extends string> = `${Uncapitalize<Extract<S, string>>}`\n\n/**\n * Converts all keys of an object to uncapitalized versions in a type-safe way.\n */\nexport function uncapitalizeKeys<T extends Record<string, unknown>>(obj: T): UncapitalizedKeys<T> {\n const result = {} as UncapitalizedKeys<T>\n\n for (const key in obj) {\n const unKey = `${key.charAt(0).toLowerCase()}${key.slice(1)}`\n const unVal = obj[key]\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n result[unKey] = unVal\n }\n\n return result\n}\n\n/**\n * Returns the same string with a lowercase first letter.\n */\nexport function uncapitalize(str: string): string {\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n\n/**\n * Returns the same string with an uppercase first letter.\n */\nexport function capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\n/**\n * Returns the camelCase version of the given string.\n *\n * Camel case examples:\n * `toCamelCase('hello world')` -> 'helloWorld',\n * `toCamelCase('hello_world')` -> 'helloWorld',\n * `toCamelCase('helloWorld')` -> 'helloWorld'\n * `toCamelCase('HelloWorld')` -> 'helloWorld'\n * `toCamelCase('hello_world')` -> 'helloWorld'\n */\nexport function toCamelCase(str: string): string {\n if (/^[a-z]+(?:[A-Z][a-z]*)*$/.test(str)) {\n return str\n }\n\n // Split the string into an array of words\n // We split on spaces, underscores, and hyphens.\n // We also split on single uppercase letters, though not on consecutive uppercase letters.\n const words = str.split(/(?<![A-Z])(?=[A-Z])|[\\s_-]+/)\n\n // Convert the first word to lowercase and capitalize the rest\n const camelCasedWords = words\n .map((word) => (word.toUpperCase() === word ? word.toLowerCase() : word))\n .map((word, index) => (index === 0 ? lowerFirst(word) : upperFirst(word)))\n\n // Join the words back together into a single string\n const camelCasedStr = camelCasedWords.join('')\n\n return camelCasedStr\n}\n\n/**\n * Validates if a string is in camelCase format\n */\nexport function isCamelCase(str: string): boolean {\n return str === toCamelCase(str)\n}\n\n/**\n * Returns the PascalCase version of the given string.\n *\n * Examples:\n * `toPascalCase('hello world')` -> 'HelloWorld'\n * `toPascalCase('hello_world')` -> 'HelloWorld'\n * `toPascalCase('helloWorld')` -> 'HelloWorld'\n * `toPascalCase('Hello-World')` -> 'HelloWorld'\n * `toPascalCase('HELLO_WORLD')` -> 'HelloWorld'\n */\nexport function toPascalCase(str: string): string {\n const s = toCamelCase(str)\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\n/**\n * Validates if a string is in PascalCase format\n */\nexport function isPascalCase(str: string): boolean {\n return str === toPascalCase(str)\n}\n\n/**\n * Returns the snake_case version of the given string.\n *\n * Examples:\n * `toSnakeCase('hello world')` -> 'hello_world'\n * `toSnakeCase('helloWorld')` -> 'hello_world'\n * `toSnakeCase('HelloWorld')` -> 'hello_world'\n * `toSnakeCase('HELLO_WORLD')` -> 'hello_world'\n */\nexport function toSnakeCase(str: string): string {\n const camelCase = toCamelCase(str)\n return camelCase.replace(/([A-Z])/g, '_$1').toLowerCase()\n}\n\n/**\n * Validates if a string is in snake_case format\n */\nexport function isSnakeCase(str: string): boolean {\n return str === toSnakeCase(str)\n}\n\n/**\n * Returns the kebab-case version of the given string.\n *\n * Examples:\n * `toKebabCase('hello world')` -> 'hello-world'\n * `toKebabCase('helloWorld')` -> 'hello-world'\n * `toKebabCase('HelloWorld')` -> 'hello-world'\n * `toKebabCase('HELLO_WORLD')` -> 'hello-world'\n */\nexport function toKebabCase(str: string): string {\n const camelCase = toCamelCase(str)\n return camelCase.replaceAll(/([A-Z])/g, '-$1').toLowerCase()\n}\n\n/**\n * Validates if a string is in kebab-case format\n */\nexport function isKebabCase(str: string): boolean {\n return str === toKebabCase(str)\n}\n\n/**\n * Converts each line of a string to a commented line\n */\nexport function commentLines(lines: string): string {\n return lines\n .split('\\n')\n .map((l) => `// ${l}`)\n .join('\\n')\n}\n\nexport function toHumanReadable(input: string): string {\n // Replace underscores and hyphens with spaces\n let result = input.replace(/[_-]/g, ' ')\n\n // Add spaces before capital letters\n result = result.replace(/([a-z])([A-Z])/g, '$1 $2')\n\n //In case the string was already human readable, return it\n if (result === input) {\n return input\n }\n\n //lowercase the first letter of every word\n result = result\n .split(' ')\n .map((s) => s.toLowerCase())\n .join(' ')\n\n // Capitalize the first letter of the resulting string\n result = upperFirst(result)\n\n return result\n}\n\n/**\n * Sanitizes a string to be a valid Excel ListObject (table) column name.\n * - Removes illegal characters: [ ] : ? * / \\\n * - Trims leading/trailing spaces\n * - Replaces multiple spaces with a single space\n * - If the result is empty, returns a default name\n */\nexport function toExcelColumnName(input: string, defaultName = 'Column1'): string {\n // Remove illegal characters: [ ] : ? * / \\\n let result = input.replace(/[[\\]:?*/\\\\]/g, '')\n\n // Replace multiple spaces with a single space\n result = result.replace(/\\s+/g, ' ')\n\n // Trim leading/trailing spaces\n result = result.trim()\n\n // If the result is empty, return the default name\n if (!result) {\n return toExcelColumnName(defaultName, 'Column1')\n }\n\n return result\n}\n\n/**\n * Sanitizes a string to be a valid Excel ListObject (table) name.\n * - Must start with a letter, underscore, or backslash\n * - Only letters, numbers, and underscores allowed (no spaces or punctuation)\n * - Cannot be a cell reference (e.g., \"A1\")\n * - Max 255 characters\n * - If invalid or empty, returns a default name\n */\nexport function toExcelTableName(input: string, defaultName = 'Table1'): string {\n // Remove all characters except letters, numbers, and underscores\n let result = input.replace(/[^A-Za-z0-9_\\\\]/g, '')\n\n // Ensure the name starts with a letter, underscore, or backslash\n if (!/^[A-Za-z_\\\\]/.test(result)) {\n result = '_' + result\n }\n\n // Truncate to 255 characters\n result = result.slice(0, 255)\n\n // Avoid names that look like cell references (e.g., \"A1\", \"AA100\")\n if (/^[A-Za-z]{1,3}[1-9][0-9]{0,6}$/.test(result)) {\n result = '_' + result\n }\n\n // If the result is empty, use the default name\n if (!result || result === '_') {\n return toExcelTableName(defaultName, 'Table1')\n }\n\n return result\n}\n\nexport type Conjugated = {\n camelCase: string\n camelCasePlural: string\n capitalized: string\n capitalizedPlural: string\n kebabCase: string\n kebabCasePlural: string\n PascalCase: string\n PascalCasePlural: string\n pluralized: string\n snake_case_plural: string\n snake_case: string\n uncapitalized: string\n uncapitalizedPlural: string\n}\n\n/**\n * Provide all relevant conjugation of a name\n */\nexport function conjugateNames(name: string): Conjugated {\n const plural = pluralize(name)\n return {\n camelCase: toCamelCase(name),\n camelCasePlural: toCamelCase(plural),\n capitalized: capitalize(name),\n capitalizedPlural: capitalize(plural),\n kebabCase: toKebabCase(name),\n kebabCasePlural: toKebabCase(plural),\n PascalCase: toPascalCase(name),\n PascalCasePlural: toPascalCase(plural),\n pluralized: capitalize(plural),\n snake_case_plural: toSnakeCase(plural),\n snake_case: toSnakeCase(name),\n uncapitalized: uncapitalize(name),\n uncapitalizedPlural: uncapitalize(plural),\n }\n}\n\nexport function slugify(str: string): string {\n return (\n str\n // replace uppercase letters with hyphens and letter (will be lowercased later)\n .replace(/([A-Z])/g, '-$1')\n .toLowerCase()\n // replace letter followed by number with letter-number\n .replace(/([a-z])(\\d)/g, '$1-$2')\n // replace non-alphanumeric characters with hyphens\n .replace(/[^a-z0-9]+/g, '-')\n // remove leading hyphens\n .replace(/^-/g, '')\n // remove trailing hyphens\n .replace(/-$/g, '')\n // replace multiple hyphens with a single hyphen\n .replace(/-+/g, '-')\n )\n}\n\nexport function isSlug(str: string): boolean {\n return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(str)\n}\n\n/**\n * Ensures that a string is unique within a list of existing values by appending a sequential number if necessary.\n *\n * If the base string is not in the list, it is returned as is.\n * If it is, the function looks for existing strings in the format \"base (n)\" where n is a number,\n * and returns the next available sequential string.\n *\n * @param value - The base string to ensure uniqueness for.\n * @param existingValues - An array of existing strings to check against.\n * @param maxChecks - Maximum number of checks to be performed. An error is thrown if this limit is exceeded. Default is 100\n * @returns A unique string based on the base string.\n */\nexport const ensureUnique = (value: string, existingValues: string[], maxChecks = 100): string => {\n // convert existingValues to a Set for faster lookup\n const values = new Set(existingValues)\n\n // if the base itself (without a number) is not in the list, return it\n if (!values.has(value)) {\n return value\n }\n\n let base = value.trim()\n let num = 0\n\n // Regex to match a numeric suffix like \" (n)\" at the end of the string.\n // Using a targeted pattern avoids catastrophic backtracking for inputs without such a suffix.\n const m = /\\((\\d{1,5})\\)$/.exec(value)\n if (m && /\\s$/.test(value.slice(0, m.index))) {\n base = value.slice(0, m.index).trimEnd()\n }\n\n while (num < maxChecks) {\n const newValue = num === 0 ? base : `${base} (${num})`\n if (!values.has(newValue)) {\n return newValue\n }\n num++\n }\n throw new Error(`Could not find a unique name for \"${value}\" after ${maxChecks} checks`)\n}\n","// Source: https://stackoverflow.com/a/53229857/1867581\ntype Without<T, U> = Partial<Record<Exclude<keyof T, keyof U>, never>>\nexport type XOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U\n\n// Source: see workaround in https://github.com/Microsoft/TypeScript/issues/12936#issuecomment-1061725873\nexport type Exact<T, I> = T extends I ? (Exclude<keyof T, keyof I> extends never ? T : never) : never\n\nexport type UncapitalizeObjectKeys<T> = {\n [key in keyof T as Uncapitalize<key & string>]: T[key]\n}\n// Source: https://twitter.com/mattpocockuk/status/1622730173446557697\nexport type Prettify<T> = {\n [K in keyof T]: T[K]\n}\n\n/**\n * Distributive Pick - does not collapse unions into a \"shared type\" only to\n * run Pick on it. Instead, it \"picks\" from each union item separately.\n *\n * See https://github.com/klimashkin/css-modules-theme/pull/8\n *\n * Example:\n * Pick<{ type: \"pick\" } | { type: \"omit\" }, \"type\">\n * produces { type: \"pick\" | \"omit\" }\n *\n * UnionPick<{ type: \"pick\" } | { type: \"omit\" }, \"type\">\n * produces { type: \"pick\" } | { type: \"omit\" }\n */\nexport type UnionPick<T, K extends keyof T> = T extends unknown ? Pick<T, K> : never\n\n/**\n * Like UnionPick, but for Omit\n */\nexport type UnionOmit<T, K extends keyof T> = T extends unknown ? Omit<T, K> : never\n\n/**\n * Makes a type check that is only valid when all cases of a switch\n * statement have been covered.\n */\nexport class ExhaustiveSwitchCheck extends Error {\n constructor(val: never) {\n super(`Unreachable case: ${JSON.stringify(val)}`)\n }\n}\n\n/**\n * A type that represents an array that is guaranteed to have at least one element.\n */\nexport type NonEmptyArray<T> = [T, ...T[]]\n\n/**\n * Converts a nested object to a nested object where all properties are optional.\n */\nexport type DeepPartial<T> = T extends object\n ? {\n [P in keyof T]?: DeepPartial<T[P]>\n }\n : T\n\n/**\n * Changes properties of an object type to optional.\n *\n * Example:\n * type Foo = { a: string, b: number, c: boolean }\n * type Bar = Optional<Foo, 'a' | 'b'>\n * // Bar is { a?: string, b?: number, c: boolean }\n */\nexport type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\n\n/**\n * Allows inline type assertions.\n *\n * Example:\n * ```\n * type Original = { a: number }\n * type WithExtra = Original & { b: string }\n *\n * function addExtra(obj: Original): asserts obj is WithExtra {\n * assertType(obj)\n * obj.b = 'new value' // ✅ No TypeScript error!\n * }\n * ```\n */\nexport function assertType<T>(value: unknown): asserts value is T {\n return value as any\n}\n\n/**\n * Applies a type assertion to an entire array and hence asserts the array.\n *\n * Type assertions are especially useful when you want to modify and object in place - a function\n * with a type assertion lets TypeScript know that the object was modified.\n *\n * Example:\n * ```\n * type Original = { a: number }\n * type WithExtra = Original & { b: string }\n *\n * function addExtra(obj: Original): asserts obj is WithExtra {\n * obj.b = 'new value'\n * }\n *\n * const myObj: Original[] = [{ a: 1 }]\n * console.log(myObj[0].b) // ❌ TypeScript error!\n * assertArray(myObj, addExtra)\n * console.log(myObj[0].b) // ✅ No TypeScript error!\n * ```\n */\nexport function assertArray<I, O extends I>(obj: I[], fn: (i: I) => asserts i is O): asserts obj is O[] {\n obj.forEach(fn)\n}\n\n/**\n * Converts any branded string type to its underlying string type.\n */\nexport type Debrand<T> = T extends string & infer _U ? string : T extends object ? { [K in keyof T]: Debrand<T[K]> } : T\n","export function uniq<T>(items: T[], predicate: (item: T) => number): T[] {\n const result: T[] = []\n const seen: Record<string, true> = {}\n\n for (const item of items) {\n const key = predicate(item)\n\n if (!seen[key]) {\n seen[key] = true\n result.push(item)\n }\n }\n\n return result\n}\n","import { z } from 'zod'\n\nexport type Transformer<Input, Output> = (value: Input, ctx: z.RefinementCtx) => Output | z.ZodNever\n\ntype ReturnTypeOfLast<T extends any[]> = T extends [...any, infer L]\n ? L extends (...args: any) => any\n ? ReturnType<L>\n : never\n : never\n\n/**\n * Pipes a list of Zod transformers together in a type-safe way. Returns early if any of the transformers returns `z.NEVER`.\n */\nexport function pipeZodTransformers<Initial, Fns extends [Transformer<any, any>, ...Transformer<any, any>[]]>(\n initialValue: Initial,\n ctx: z.RefinementCtx,\n fns: Fns,\n): ReturnTypeOfLast<Fns> {\n let result: any = initialValue\n for (const fn of fns) {\n result = fn(result, ctx)\n if (result === z.NEVER) {\n return z.NEVER\n }\n }\n return result\n}\n\n/**\n * Returns a Zod error map that returns the given message for union errors.\n *\n * This is useful for generating meaningful error messages for unions, e.g.\n * ```\n * z.union(\n * [z.constant('foo'), z.constant('bar')],\n * unionErrorMessage('Value must be either \"foo\" or \"bar\"!')\n * )\n * ```\n *\n * In addition to a static message, you can also pass a function that takes the\n * invalid data as input and returns a string. Example:\n * ```\n * z.union(\n * [z.constant('foo'), z.constant('bar')],\n * unionErrorMessage((data) => `Value must be either \"foo\" or \"bar\" - received ${JSON.stringify(data)} instead!`)\n * )\n * ```\n */\nexport function unionErrorMessage(param: string | ((data: any) => string)): z.RawCreateParams {\n return {\n errorMap: (issue, ctx) => {\n let message: string\n if (typeof param === 'string') {\n message = param\n } else {\n message = param(ctx.data)\n }\n\n if (issue.code === z.ZodIssueCode.invalid_union) {\n return { message }\n }\n return { message: ctx.defaultError }\n },\n }\n}\n","import z from 'zod'\n\nimport { isDate } from './datetime'\n\n/**\n * Transformer that verifies that the number is an integer\n */\nconst intValidator = (x: number, ctx: z.RefinementCtx): number => {\n if (x % 1 !== 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not an integer: ${x}`,\n })\n return z.NEVER\n }\n return x\n}\n\n/**\n * Converts any transformer to a nullable transformer, i.e. if the input is\n * null or undefined, the output will be nullable. Else the original transformer\n * is applied\n */\nconst nullableTransformer =\n <I, O>(transformer: (x: I, ctx: z.RefinementCtx) => O) =>\n (x: I | undefined | null, ctx: z.RefinementCtx): O | null => {\n if (x === null || x === undefined || (typeof x === 'string' && x === '')) {\n return null\n }\n return transformer(x, ctx)\n }\n\n/**\n * A decoder that transforms Excel strings to JS strings, also handling numbers and boolean. Will not parse any other type!\n *\n * Background: In Excel, entering a number in a cell will automatically convert it to a number -\n * and xlPort will return it as a number. However, often we want to treat it as a string - this decoder\n * hence accepts both strings and numbers, and converts numbers to strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be converted to a string\n * - If the value is a string, it'll be returned as-is\n * - If the value is boolean, it'll return 'true' or 'false'\n *\n * Any other type will throw an error!\n */\nexport const excelStringStrictDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>,\n string,\n string | number | boolean // NOSONAR\n> = z.union([z.string(), z.number(), z.boolean()]).transform((x: string | number | boolean): string => {\n if (typeof x === 'number') {\n return x.toString()\n }\n if (typeof x === 'boolean') {\n return x ? 'true' : 'false'\n }\n return x\n})\n\n/**\n * A decoder that transforms Excel strings to JS strings, also handling numbers and any other potential type\n *\n * Background: In Excel, entering a number in a cell will automatically convert it to a number -\n * and xlPort will return it as a number. However, often we want to treat it as a string - this decoder\n * hence accepts both strings and numbers, and converts numbers to strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be converted to a string\n * - If the value is a string, it'll be returned as-is\n * - If the value is boolean, it'll return 'true' or 'false'\n * - If the value is null or undefined, it'll return an empty string\n * - If the value is any other type, it'll return an empty string\n *\n * Null handling: Null values/blank cells will be converted to a blank string.\n */\nexport const excelStringDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodAny]>,\n string,\n any\n> = z.union([z.string(), z.number(), z.boolean(), z.null(), z.undefined(), z.any()]).transform((x): string => {\n if (x === null || x === undefined) {\n return ''\n }\n if (typeof x === 'number') {\n return x.toString()\n }\n if (typeof x === 'boolean') {\n return x ? 'true' : 'false'\n }\n if (typeof x === 'string') {\n return x\n }\n return ''\n})\n\n/**\n * A decoder that transforms Excel strings to JS strings, also handling numbers and null\n *\n * Background: In Excel, entering a number in a cell will automatically convert it to a number -\n * and xlPort will return it as a number. However, often we want to treat it as a string - this decoder\n * hence accepts both strings and numbers, and converts numbers to strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be converted to a string\n * - If the value is a string, it'll be returned as-is - except blank strings, which will be converted to null\n * - If the value is boolean, it'll return 'true' or 'false'\n * - If the value is null or undefined, it'll return null\n * - If the value is any other type, it'll return null\n *\n * Null handling: Blank strings will be converted to null. This is to reflect that in Excel a formula\n * cannot return null. As a workaround, one often returns a blank string to represent null.\n */\nexport const excelStringNullableDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodAny]>,\n string | null,\n any\n> = z.union([z.string(), z.number(), z.boolean(), z.null(), z.undefined(), z.any()]).transform((x) => {\n if (x === null || x === undefined) {\n return null\n }\n if (typeof x === 'number') {\n return x.toString()\n }\n if (typeof x === 'boolean') {\n return x ? 'true' : 'false'\n }\n if (typeof x === 'string') {\n if (x === '') {\n return null\n }\n return x\n }\n return null\n})\n\nconst excelNumberTransformer = (x: any): number | null => {\n if (typeof x === 'string') {\n if (x.trim() === '') {\n return null\n }\n const parsed = parseFloat(x)\n if (Number.isNaN(parsed)) {\n return null\n }\n return parsed\n }\n if (typeof x === 'boolean') {\n return x ? 1 : 0\n }\n if (typeof x === 'number') {\n return x\n }\n\n return null\n}\n/**\n * A decoder that transforms Excel numbers to JS numbers, also handling strings and boolean. Will not parse any other type!\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be returned as-is\n * - If the value is a string, it'll try to parse it to a number. Blank strings will be converted to 0. Non-numeric strings will throw an error.\n * - If the value is boolean, it'll return 1 or 0\n * - If the value is any other type, it'll throw an error\n *\n */\nexport const excelNumberStrictDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>,\n number,\n string | number | boolean\n> = z.union([z.string(), z.number(), z.boolean()]).transform((x, ctx): number => {\n const result = excelNumberTransformer(x)\n if (result === null) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not a number: ${x}`,\n })\n return z.NEVER\n }\n return result\n})\n\n/**\n * A decoder that transforms Excel numbers to JS numbers, also handling strings, boolean and other types.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be returned as-is\n * - If the value is a string, it'll try to parse it to a number. Blank strings and non-numerical strings will be converted to 0.\n * - If the value is boolean, it'll return 1 or 0\n * - If the value is any other type, it'll return 0\n *\n * Null handling: Null values/blank cells will be converted to blank strings.\n */\nexport const excelNumberDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodAny]>,\n number,\n any\n> = z.union([z.string(), z.number(), z.boolean(), z.null(), z.undefined(), z.any()]).transform((x): number => {\n const result = excelNumberTransformer(x)\n if (result === null) {\n return 0\n }\n return result\n})\n\n/**\n * A decoder that transforms Excel numbers to JS numbers, also handling strings, boolean and other types.\n \n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll be returned as-is\n * - If the value is a string, it'll try to parse it to a number. Non-numerical and blank strings will be converted to null\n * - If the value is boolean, it'll return 1 or 0\n * - If the value is any other type, it'll return null\n * \n * Null handling: Blank strings will be converted to null. This is to reflect that in Excel a formula\n * cannot return null. As a workaround, one often returns a blank string to represent null.\n */\nexport const excelNumberNullableDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodString, z.ZodNull, z.ZodNumber, z.ZodUndefined, z.ZodAny]>,\n number | null,\n any\n> = z.union([z.string(), z.null(), z.number(), z.undefined(), z.any()]).transform(excelNumberTransformer)\n\n/**\n * A decoder that transforms Excel numbers to JS integers, also handling strings and boolean. Other types will throw an error.\n *\n * If the number is not an integer, an error will be thrown.\n */\nexport const excelIntStrictDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>, number, string | number | boolean>,\n number,\n string | number | boolean\n> = excelNumberStrictDecoder.transform(intValidator)\n\n/**\n * A decoder that transforms Excel numbers to JS integers, also handling strings and boolean. Other types will be converted to 0.\n *\n * If the number is not an integer, an error will be thrown.\n */\nexport const excelIntDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodAny]>, number, any>,\n number,\n any\n> = excelNumberDecoder.transform(intValidator)\n\n/**\n * A decoder that transforms Excel numbers to JS integers, also handling strings and boolean. Other types will be converted to null.\n *\n * If the number is not an integer, an error will be thrown.\n */\nexport const excelIntNullableDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNull, z.ZodNumber, z.ZodUndefined, z.ZodAny]>, number | null, any>,\n number | null,\n any\n> = excelNumberNullableDecoder.transform(nullableTransformer(intValidator))\n\n// TODO: Add BigInt tests (to be investigated, how Excel handles BigInts)\nconst bigIntTransformer = (x: number, ctx: z.RefinementCtx): bigint => {\n if (x % 1 !== 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not an integer: ${x}`,\n })\n return z.NEVER\n }\n return BigInt(x)\n}\n\n/**\n * A decoder that transforms Excel numbers to JS BigInts, also handling strings and boolean. Other types will throw an error.\n *\n * If the number is not a (big) integer, an error will be thrown.\n */\nexport const excelBigIntStrictDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>, number, string | number | boolean>,\n bigint,\n string | number | boolean\n> = excelNumberStrictDecoder.transform(bigIntTransformer)\n\n/**\n * A decoder that transforms Excel numbers to JS BigInts, also handling strings and boolean. Other types will be converted to 0.\n *\n * If the number is not a (big) integer, an error will be thrown.\n */\nexport const excelBigIntDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull, z.ZodUndefined, z.ZodAny]>, number, any>,\n bigint,\n any\n> = excelNumberDecoder.transform(bigIntTransformer)\n\n/**\n * A decoder that transforms Excel numbers to JS BigInts, also handling strings and boolean. Other types will be converted to null.\n *\n * If the number is not a (big) integer, an error will be thrown.\n */\nexport const excelBigIntNullableDecoder: z.ZodEffects<\n z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodNull, z.ZodNumber, z.ZodUndefined, z.ZodAny]>, number | null, any>,\n bigint | null,\n any\n> = excelNumberNullableDecoder.transform(nullableTransformer(bigIntTransformer))\n\nconst excelBooleanNullableTransformer = (x: any): boolean | null => {\n if (typeof x === 'number') {\n return x !== 0\n }\n\n if (typeof x === 'string') {\n switch (x.toLowerCase()) {\n case 'true':\n case '1':\n return true\n case 'false':\n case '0':\n return false\n default:\n return null\n }\n }\n\n if (typeof x === 'boolean') {\n return x\n }\n\n return null\n}\n\n/**\n * A decoder that transforms Excel booleans to JS booleans, also handling numbers and strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll return true if it's not 0\n * - If the value is a string, it'll return true if it's 'true' or '1', false if it's 'false' or '0', and throw an error otherwise\n * - If the value is boolean, it'll return it as-is\n * - If the value is any other type, it'll throw an error\n */\nexport const excelBooleanStrictDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodBoolean, z.ZodNumber, z.ZodString]>,\n boolean,\n string | number | boolean\n> = z.union([z.boolean(), z.number(), z.string()]).transform((x, ctx): boolean => {\n const result = excelBooleanNullableTransformer(x)\n if (result === null) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not a boolean: ${x}`,\n })\n return z.NEVER\n }\n\n return result\n})\n\n/**\n * A decoder that transforms Excel booleans to JS booleans, also handling numbers and strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll return true if it's not 0\n * - If the value is a string, it'll return true if it's 'true' or '1', false otherwise\n * - If the value is boolean, it'll return it as-is\n * - If the value is any other type, it'll return false\n */\nexport const excelBooleanDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodBoolean, z.ZodNumber, z.ZodNull, z.ZodString, z.ZodUndefined, z.ZodAny]>,\n boolean,\n any\n> = z.union([z.boolean(), z.number(), z.null(), z.string(), z.undefined(), z.any()]).transform((x) => {\n const result = excelBooleanNullableTransformer(x)\n if (result === null) {\n return false\n }\n\n return result\n})\n\n/**\n * A decoder that transforms Excel booleans to JS booleans, also handling numbers and strings.\n *\n * It'll perform casting based on the following rules:\n * - If the value is a number, it'll return true if it's not 0\n * - If the value is a string, it'll return true if it's 'true' or '1', false if it's 'false' or '0', and null otherwise\n * - If the value is boolean, it'll return it as-is\n * - If the value is any other type, it'll return null\n */\nexport const excelBooleanNullableDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodBoolean, z.ZodNumber, z.ZodNull, z.ZodString, z.ZodUndefined, z.ZodAny]>,\n boolean | null,\n any\n> = z\n .union([z.boolean(), z.number(), z.null(), z.string(), z.undefined(), z.any()])\n .transform(excelBooleanNullableTransformer)\n\nconst excelDateNullableTransformer = (x: any, ctx: z.RefinementCtx): Date | null => {\n if (x === null || x === undefined) {\n return null\n }\n\n if (isDate(x)) {\n return x\n }\n\n if (typeof x === 'number') {\n // Excel number is a float with 1 representing Jan 1, 1900. Each increment is a day.\n // As Excel incorrectly ignores the 1900 leap year, we need to correct for that\n const date = new Date(Date.UTC(1900, 0, 1))\n date.setUTCDate(date.getDate() + x - 2)\n\n const fractionalDay = x - Math.floor(x)\n date.setMilliseconds(date.getMilliseconds() + fractionalDay * 24 * 60 * 60 * 1000)\n\n return date\n }\n\n if (typeof x === 'string') {\n if (typeof x === 'string' && x.trim() === '') {\n return null\n }\n const result = new Date(x)\n if (Number.isNaN(result.getTime())) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not a date: ${x}`,\n })\n return z.NEVER\n }\n return result\n }\n return null\n}\n\n/**\n * A decoder that transforms Excel dates to JS Dates\n */\nexport const excelDateDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodDate, z.ZodNumber, z.ZodString]>,\n Date,\n string | number | Date\n> = z.union([z.date(), z.number(), z.string()]).transform((x, ctx) => {\n const result = excelDateNullableTransformer(x, ctx)\n if (result === null) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Not a date: ${x.toString()}`,\n })\n return z.NEVER\n }\n return result\n})\n\n/**\n * A decoder that transforms nullable Excel dates to JS Dates\n */\nexport const excelDateNullableDecoder: z.ZodEffects<\n z.ZodUnion<[z.ZodDate, z.ZodString, z.ZodNumber, z.ZodNull, z.ZodUndefined, z.ZodAny]>,\n Date | null,\n any\n> = z\n .union([z.date(), z.string(), z.number(), z.null(), z.undefined(), z.any()])\n .transform(excelDateNullableTransformer)\n"],"mappings":"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"}