@zudojs/types 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,8 @@
1
1
  /**
2
- * Runtime type conversion helpers: JSON parsing, string/number/boolean conversion, case transforms.
2
+ * Runtime type conversion helpers: JSON parsing, string/number/boolean conversion, case transforms, count formatting.
3
3
  *
4
4
  * @module typeConverters
5
5
  */
6
6
  export { safeJsonParse, toString, toNumber, toBoolean, toArray, mapToObject, objectToMap, snakeToCamel, camelToSnake, kebabToCamel, camelToKebab, } from "./typeConverters.core.js";
7
+ export { formatCount } from "./typeConverters.count.js";
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1,7 +1,8 @@
1
1
  /**
2
- * Runtime type conversion helpers: JSON parsing, string/number/boolean conversion, case transforms.
2
+ * Runtime type conversion helpers: JSON parsing, string/number/boolean conversion, case transforms, count formatting.
3
3
  *
4
4
  * @module typeConverters
5
5
  */
6
6
  export { safeJsonParse, toString, toNumber, toBoolean, toArray, mapToObject, objectToMap, snakeToCamel, camelToSnake, kebabToCamel, camelToKebab, } from "./typeConverters.core.js";
7
+ export { formatCount } from "./typeConverters.count.js";
7
8
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Count-and-noun formatting for human-readable messages.
3
+ *
4
+ * @module typeConverters/count
5
+ */
6
+ /**
7
+ * Formats a count with the singular or plural form of a noun, so messages
8
+ * read "at least 1 character" rather than "at least 1 characters".
9
+ *
10
+ * Only an exact count of 1 (or -1) is singular; 0, fractions and everything
11
+ * else take the plural. The plural defaults to the singular plus "s"; pass it
12
+ * explicitly for irregular nouns.
13
+ *
14
+ * @example
15
+ * formatCount(1, "character"); // "1 character"
16
+ * formatCount(3, "item"); // "3 items"
17
+ * formatCount(2, "entry", "entries"); // "2 entries"
18
+ */
19
+ export declare function formatCount(count: number, singular: string, plural?: string): string;
20
+ //# sourceMappingURL=typeConverters.count.d.ts.map
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Count-and-noun formatting for human-readable messages.
3
+ *
4
+ * @module typeConverters/count
5
+ */
6
+ /**
7
+ * Formats a count with the singular or plural form of a noun, so messages
8
+ * read "at least 1 character" rather than "at least 1 characters".
9
+ *
10
+ * Only an exact count of 1 (or -1) is singular; 0, fractions and everything
11
+ * else take the plural. The plural defaults to the singular plus "s"; pass it
12
+ * explicitly for irregular nouns.
13
+ *
14
+ * @example
15
+ * formatCount(1, "character"); // "1 character"
16
+ * formatCount(3, "item"); // "3 items"
17
+ * formatCount(2, "entry", "entries"); // "2 entries"
18
+ */
19
+ export function formatCount(count, singular, plural = `${singular}s`) {
20
+ return `${count} ${Math.abs(count) === 1 ? singular : plural}`;
21
+ }
22
+ //# sourceMappingURL=typeConverters.count.js.map
@@ -52,9 +52,8 @@ export declare const MAX_EMAIL_LENGTH = 254;
52
52
  * This is the monorepo's reference email check. `ValidationPattern.EMAIL`
53
53
  * in `@zudojs/constants` (and therefore `createEmailAddress` and the schema
54
54
  * `email` format) encodes the same acceptance set, including the 254
55
- * character bound. `@zudojs/validation`'s `email` constraint still carries
56
- * its own copy of the pattern without the length bound; until it delegates
57
- * here, an address over 254 characters passes that constraint only.
55
+ * character bound, and `@zudojs/validation`'s `email` constraint uses that
56
+ * pattern, so all three accept exactly the same addresses.
58
57
  */
59
58
  export declare function isEmail(value: unknown): value is string;
60
59
  /**
@@ -86,6 +85,10 @@ export declare function isIsoDateString(value: unknown): value is string;
86
85
  export declare function isIsoDateTimeString(value: unknown): value is string;
87
86
  /**
88
87
  * Check if a value is an array of a specific element type.
88
+ *
89
+ * Every index in `0..length-1` is read, so a hole is tested as `undefined`
90
+ * rather than skipped. `Array.prototype.every` skips holes, which made
91
+ * `new Array(3)` satisfy every guard and narrow three holes to `T[]`.
89
92
  */
90
93
  export declare function isArrayOfType<T>(value: unknown, guard: (item: unknown) => item is T): value is T[];
91
94
  /**
@@ -79,9 +79,8 @@ export const MAX_EMAIL_LENGTH = 254;
79
79
  * This is the monorepo's reference email check. `ValidationPattern.EMAIL`
80
80
  * in `@zudojs/constants` (and therefore `createEmailAddress` and the schema
81
81
  * `email` format) encodes the same acceptance set, including the 254
82
- * character bound. `@zudojs/validation`'s `email` constraint still carries
83
- * its own copy of the pattern without the length bound; until it delegates
84
- * here, an address over 254 characters passes that constraint only.
82
+ * character bound, and `@zudojs/validation`'s `email` constraint uses that
83
+ * pattern, so all three accept exactly the same addresses.
85
84
  */
86
85
  export function isEmail(value) {
87
86
  if (typeof value !== "string")
@@ -170,11 +169,19 @@ export function isIsoDateTimeString(value) {
170
169
  }
171
170
  /**
172
171
  * Check if a value is an array of a specific element type.
172
+ *
173
+ * Every index in `0..length-1` is read, so a hole is tested as `undefined`
174
+ * rather than skipped. `Array.prototype.every` skips holes, which made
175
+ * `new Array(3)` satisfy every guard and narrow three holes to `T[]`.
173
176
  */
174
177
  export function isArrayOfType(value, guard) {
175
178
  if (!Array.isArray(value))
176
179
  return false;
177
- return value.every(guard);
180
+ for (let index = 0; index < value.length; index++) {
181
+ if (!guard(value[index]))
182
+ return false;
183
+ }
184
+ return true;
178
185
  }
179
186
  /**
180
187
  * Check if a value is defined (not null or undefined).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zudojs/types",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Shared type guards, utility types, and type converters for the Zudojs framework.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -29,9 +29,9 @@
29
29
  "node": ">=24.0.0"
30
30
  },
31
31
  "devDependencies": {
32
- "@types/node": "^26.4.1",
32
+ "@types/node": "^26.6.2",
33
33
  "typescript": "7.0.2",
34
- "vitest": "^4.1.11"
34
+ "vitest": "^5.0.1"
35
35
  },
36
36
  "publishConfig": {
37
37
  "access": "public"
@@ -42,7 +42,7 @@
42
42
  "type-guards",
43
43
  "utilities"
44
44
  ],
45
- "homepage": "https://github.com/oyinlola-tech/zudo#readme",
45
+ "homepage": "https://zudojs.oyinlola.site/docs/packages-types",
46
46
  "bugs": {
47
47
  "url": "https://github.com/oyinlola-tech/zudo/issues"
48
48
  },