@naturalcycles/js-lib 15.5.2 → 15.6.1

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,11 +1,10 @@
1
1
  declare global {
2
- interface Window {
3
- dataLayer: any[];
4
- gtag: (...args: any[]) => void;
5
- }
2
+ var dataLayer: any[];
3
+ var gtag: (...args: any[]) => void;
4
+ var hj: (...args: any[]) => void;
6
5
  }
7
6
  /**
8
- * Pass enabled = false to only init window.gtag, but not load actual gtag script (e.g in dev mode).
7
+ * Pass enabled = false to only init globalThis.gtag, but not load actual gtag script (e.g in dev mode).
9
8
  */
10
9
  export declare function loadGTag(gtagId: string, enabled?: boolean): Promise<void>;
11
10
  export declare function loadGTM(gtmId: string, enabled?: boolean): Promise<void>;
@@ -1,20 +1,19 @@
1
1
  import { isServerSide } from '../index.js';
2
2
  import { loadScript } from './script.util.js';
3
- /* eslint-disable unicorn/prefer-global-this */
4
3
  /**
5
- * Pass enabled = false to only init window.gtag, but not load actual gtag script (e.g in dev mode).
4
+ * Pass enabled = false to only init globalThis.gtag, but not load actual gtag script (e.g in dev mode).
6
5
  */
7
6
  export async function loadGTag(gtagId, enabled = true) {
8
7
  if (isServerSide())
9
8
  return;
10
- window.dataLayer ||= [];
11
- window.gtag ||= function gtag() {
9
+ globalThis.dataLayer ||= [];
10
+ globalThis.gtag ||= function gtag() {
12
11
  // biome-ignore lint/complexity/useArrowFunction: ok
13
12
  // biome-ignore lint/complexity/noArguments: ok
14
- window.dataLayer.push(arguments);
13
+ globalThis.dataLayer.push(arguments);
15
14
  };
16
- window.gtag('js', new Date());
17
- window.gtag('config', gtagId);
15
+ globalThis.gtag('js', new Date());
16
+ globalThis.gtag('config', gtagId);
18
17
  if (!enabled)
19
18
  return;
20
19
  await loadScript(`https://www.googletagmanager.com/gtag/js?id=${gtagId}`);
@@ -22,8 +21,8 @@ export async function loadGTag(gtagId, enabled = true) {
22
21
  export async function loadGTM(gtmId, enabled = true) {
23
22
  if (isServerSide())
24
23
  return;
25
- window.dataLayer ||= [];
26
- window.dataLayer.push({
24
+ globalThis.dataLayer ||= [];
25
+ globalThis.dataLayer.push({
27
26
  'gtm.start': Date.now(),
28
27
  event: 'gtm.js',
29
28
  });
@@ -49,6 +48,6 @@ export function loadHotjar(hjid) {
49
48
  r.async = 1;
50
49
  r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv;
51
50
  a.append(r);
52
- })(window, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=');
51
+ })(globalThis, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=');
53
52
  /* eslint-enable */
54
53
  }
@@ -0,0 +1,6 @@
1
+ import { z as z4, ZodType } from 'zod/v4';
2
+ import { customZodSchemas } from './zod.shared.schemas.js';
3
+ type ExtendedZod = Omit<typeof z4, keyof typeof customZodSchemas | 'iso'> & typeof customZodSchemas;
4
+ declare const z: ExtendedZod;
5
+ type zInfer<T> = z4.infer<T>;
6
+ export { z, type zInfer, ZodType };
@@ -0,0 +1,4 @@
1
+ import { z as z4, ZodType } from 'zod/v4';
2
+ import { customZodSchemas } from './zod.shared.schemas.js';
3
+ const z = { ...z4, ...customZodSchemas };
4
+ export { z, ZodType };
@@ -1,4 +1,3 @@
1
+ export * from './customZod.js';
1
2
  export * from './zod.shared.schemas.js';
2
3
  export * from './zod.util.js';
3
- import { z, ZodType } from 'zod/v4';
4
- export { z, ZodType };
package/dist/zod/index.js CHANGED
@@ -1,4 +1,3 @@
1
+ export * from './customZod.js';
1
2
  export * from './zod.shared.schemas.js';
2
3
  export * from './zod.util.js';
3
- import { z, ZodType } from 'zod/v4';
4
- export { z, ZodType };
@@ -1,32 +1,38 @@
1
1
  import { z } from 'zod/v4';
2
2
  export declare const TS_2500 = 16725225600;
3
3
  export declare const TS_2000 = 946684800;
4
- export declare const zUnixTimestamp: z.ZodNumber;
5
- export declare const zUnixTimestamp2000: z.ZodNumber;
6
- export declare const zUnixTimestampMillis: z.ZodNumber;
7
- export declare const zUnixTimestampMillis2000: z.ZodNumber;
8
- export declare const zSemVer: z.ZodString;
9
- export declare const zIsoDate: z.ZodString;
10
- export declare const zEmail: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
11
- export declare const zEmailNoLowercase: z.ZodString;
4
+ export declare const zUnixTimestamp: () => z.ZodNumber;
5
+ export declare const zUnixTimestamp2000: () => z.ZodNumber;
6
+ export declare const zUnixTimestampMillis: () => z.ZodNumber;
7
+ export declare const zUnixTimestampMillis2000: () => z.ZodNumber;
8
+ export declare const zSemVer: () => z.ZodString;
9
+ export declare const zIsoDate: () => z.ZodString;
10
+ export declare const zEmail: () => z.ZodEmail;
12
11
  export declare const BASE62_REGEX: RegExp;
13
12
  export declare const BASE64_REGEX: RegExp;
14
13
  export declare const BASE64URL_REGEX: RegExp;
15
- export declare const zBase62: z.ZodString;
16
- export declare const zBase64: z.ZodString;
17
- export declare const zBase64Url: z.ZodString;
14
+ export declare const zBase62: () => z.ZodString;
15
+ export declare const zBase64: () => z.ZodString;
16
+ export declare const zBase64Url: () => z.ZodString;
18
17
  export declare const JWT_REGEX: RegExp;
19
- export declare const zJwt: z.ZodString;
20
- export declare const zId: z.ZodString;
21
- export declare const zIdBase62: z.ZodString;
22
- export declare const zIdBase64: z.ZodString;
23
- export declare const zIdBase64Url: z.ZodString;
18
+ export declare const zJwt: () => z.ZodString;
24
19
  /**
25
20
  * "Slug" - a valid URL, filename, etc.
26
21
  */
27
- export declare const zSlug: z.ZodString;
28
- export declare const zBaseDBEntity: z.ZodObject<{
29
- id: z.ZodString;
30
- created: z.ZodOptional<z.ZodNumber>;
31
- updated: z.ZodOptional<z.ZodNumber>;
32
- }, z.core.$strip>;
22
+ export declare const zSlug: () => z.ZodString;
23
+ export declare const zIanaTimezone: () => z.ZodEnum;
24
+ export declare const customZodSchemas: {
25
+ base62: () => z.ZodString;
26
+ base64: () => z.ZodString;
27
+ base64Url: () => z.ZodString;
28
+ email: () => z.ZodEmail;
29
+ ianaTimezone: () => z.ZodEnum;
30
+ isoDate: () => z.ZodString;
31
+ jwt: () => z.ZodString;
32
+ slug: () => z.ZodString;
33
+ semver: () => z.ZodString;
34
+ unixTimestamp: () => z.ZodNumber;
35
+ unixTimestamp2000: () => z.ZodNumber;
36
+ unixTimestampMillis: () => z.ZodNumber;
37
+ unixTimestampMillis2000: () => z.ZodNumber;
38
+ };
@@ -1,103 +1,75 @@
1
1
  import { z } from 'zod/v4';
2
2
  export const TS_2500 = 16725225600; // 2500-01-01
3
3
  export const TS_2000 = 946684800; // 2000-01-01
4
- export const zUnixTimestamp = z
4
+ export const zUnixTimestamp = () => z
5
5
  .number()
6
6
  .int()
7
7
  .min(0)
8
8
  .max(TS_2500, 'Must be a UnixTimestamp number')
9
9
  // .transform(v => v as UnixTimestamp) // breaks jsonSchema
10
10
  .describe('UnixTimestamp');
11
- export const zUnixTimestamp2000 = z
11
+ export const zUnixTimestamp2000 = () => z
12
12
  .number()
13
13
  .int()
14
14
  .min(TS_2000)
15
15
  .max(TS_2500, 'Must be a UnixTimestamp number after 2000-01-01')
16
16
  // .transform(v => v as UnixTimestamp)
17
17
  .describe('UnixTimestamp2000');
18
- export const zUnixTimestampMillis = z
18
+ export const zUnixTimestampMillis = () => z
19
19
  .number()
20
20
  .int()
21
21
  .min(0)
22
22
  .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number')
23
23
  // .transform(v => v as UnixTimestampMillis)
24
24
  .describe('UnixTimestampMillis');
25
- export const zUnixTimestampMillis2000 = z
25
+ export const zUnixTimestampMillis2000 = () => z
26
26
  .number()
27
27
  .int()
28
28
  .min(TS_2000 * 1000)
29
29
  .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number after 2000-01-01')
30
30
  // .transform(v => v as UnixTimestampMillis)
31
31
  .describe('UnixTimestampMillis2000');
32
- export const zSemVer = z
32
+ export const zSemVer = () => z
33
33
  .string()
34
34
  .regex(/^[0-9]+\.[0-9]+\.[0-9]+$/, 'Must be a SemVer string')
35
35
  .describe('SemVer');
36
- export const zIsoDate = z
36
+ export const zIsoDate = () => z
37
37
  .string()
38
38
  .refine(v => {
39
39
  return /^\d{4}-\d{2}-\d{2}$/.test(v);
40
40
  }, 'Must be an IsoDateString')
41
- // .transform(v => v as IsoDate)
42
41
  .describe('IsoDateString');
43
- export const zEmail = z
44
- .string()
45
- .trim()
46
- .email() // keeping as-is, so trim happens before email validation
47
- .transform(s => s.toLowerCase()) // breaks toJsonSchema
48
- .describe('Email');
49
- export const zEmailNoLowercase = z
50
- .string()
51
- .trim()
52
- .email() // keeping as-is, so trim happens before email validation
53
- // .transform(s => s.toLowerCase()) // breaks toJsonSchema
54
- .describe('Email');
42
+ export const zEmail = () => z.email().describe('Email');
55
43
  export const BASE62_REGEX = /^[a-zA-Z0-9]+$/;
56
44
  export const BASE64_REGEX = /^[A-Za-z0-9+/]+={0,2}$/;
57
- export const BASE64URL_REGEX = /^[\w-/]+$/;
58
- export const zBase62 = z
59
- .string()
60
- .regex(BASE62_REGEX, 'Must be a base62 string')
61
- .describe('Base62String');
62
- export const zBase64 = z
63
- .string()
64
- .regex(BASE64_REGEX, 'Must be a base64 string')
65
- .describe('Base64String');
66
- export const zBase64Url = z
67
- .string()
68
- .regex(BASE64URL_REGEX, 'Must be a base64url string')
69
- .describe('Base64UrlString');
45
+ export const BASE64URL_REGEX = /^[\w\-/]+$/;
46
+ export const zBase62 = () => z.string().regex(BASE62_REGEX, 'Must be a base62 string').describe('Base62String');
47
+ export const zBase64 = () => z.string().regex(BASE64_REGEX, 'Must be a base64 string').describe('Base64String');
48
+ export const zBase64Url = () => z.string().regex(BASE64URL_REGEX, 'Must be a base64url string').describe('Base64UrlString');
70
49
  export const JWT_REGEX = /^[\w-]+\.[\w-]+\.[\w-]+$/;
71
- export const zJwt = z.string().regex(JWT_REGEX, 'Must be a JWT string').describe('JWTString');
72
- export const zId = z
73
- .string()
74
- .regex(/^[a-zA-Z0-9_]{6,64}$/, 'Must be an id string (6 to 64 chars long)')
75
- .describe('IdString');
76
- export const zIdBase62 = z
77
- .string()
78
- .regex(/^[a-zA-Z0-9]{8,64}$/, 'Must be a base62 id string')
79
- .describe('Base62Id');
80
- export const zIdBase64 = z
81
- .string()
82
- .regex(/^[A-Za-z0-9+/]{6,62}={0,2}$/, 'Must be a base64 id string')
83
- .describe('Base64Id');
84
- export const zIdBase64Url = z
85
- .string()
86
- .regex(/^[\w-/]{8,64}$/, 'Must be a base64url id string')
87
- .describe('Base64UrlId');
50
+ export const zJwt = () => z.string().regex(JWT_REGEX, 'Must be a JWT string').describe('JWTString');
88
51
  /**
89
52
  * "Slug" - a valid URL, filename, etc.
90
53
  */
91
- export const zSlug = z
54
+ export const zSlug = () => z
92
55
  .string()
93
56
  .regex(/^[a-z0-9-]{1,255}$/, 'Must be a slug string')
94
57
  .describe('Slug');
95
- export const zBaseDBEntity = z
96
- .object({
97
- id: z.string(),
98
- // created/updated are intentionally optional here
99
- created: zUnixTimestamp2000.optional(),
100
- updated: zUnixTimestamp2000.optional(),
101
- })
102
- .describe('BaseDBEntity');
103
- // export const zSavedDBEntity = zBaseDBEntity.required().describe('SavedDBEntity')
58
+ export const zIanaTimezone = () => z
59
+ // UTC is added to assist unit-testing, which uses UTC by default (not technically a valid Iana timezone identifier)
60
+ .enum([...Intl.supportedValuesOf('timeZone'), 'UTC']);
61
+ export const customZodSchemas = {
62
+ base62: zBase62,
63
+ base64: zBase64,
64
+ base64Url: zBase64Url,
65
+ email: zEmail,
66
+ ianaTimezone: zIanaTimezone,
67
+ isoDate: zIsoDate,
68
+ jwt: zJwt,
69
+ slug: zSlug,
70
+ semver: zSemVer,
71
+ unixTimestamp: zUnixTimestamp,
72
+ unixTimestamp2000: zUnixTimestamp2000,
73
+ unixTimestampMillis: zUnixTimestampMillis,
74
+ unixTimestampMillis2000: zUnixTimestampMillis2000,
75
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.5.2",
4
+ "version": "15.6.1",
5
5
  "dependencies": {
6
6
  "tslib": "^2",
7
7
  "zod": "^3"
@@ -2,28 +2,25 @@ import { isServerSide } from '../index.js'
2
2
  import { loadScript } from './script.util.js'
3
3
 
4
4
  declare global {
5
- interface Window {
6
- dataLayer: any[]
7
- gtag: (...args: any[]) => void
8
- }
5
+ var dataLayer: any[]
6
+ var gtag: (...args: any[]) => void
7
+ var hj: (...args: any[]) => void
9
8
  }
10
9
 
11
- /* eslint-disable unicorn/prefer-global-this */
12
-
13
10
  /**
14
- * Pass enabled = false to only init window.gtag, but not load actual gtag script (e.g in dev mode).
11
+ * Pass enabled = false to only init globalThis.gtag, but not load actual gtag script (e.g in dev mode).
15
12
  */
16
13
  export async function loadGTag(gtagId: string, enabled = true): Promise<void> {
17
14
  if (isServerSide()) return
18
15
 
19
- window.dataLayer ||= []
20
- window.gtag ||= function gtag() {
16
+ globalThis.dataLayer ||= []
17
+ globalThis.gtag ||= function gtag() {
21
18
  // biome-ignore lint/complexity/useArrowFunction: ok
22
19
  // biome-ignore lint/complexity/noArguments: ok
23
- window.dataLayer.push(arguments)
20
+ globalThis.dataLayer.push(arguments)
24
21
  }
25
- window.gtag('js', new Date())
26
- window.gtag('config', gtagId)
22
+ globalThis.gtag('js', new Date())
23
+ globalThis.gtag('config', gtagId)
27
24
 
28
25
  if (!enabled) return
29
26
 
@@ -33,8 +30,8 @@ export async function loadGTag(gtagId: string, enabled = true): Promise<void> {
33
30
  export async function loadGTM(gtmId: string, enabled = true): Promise<void> {
34
31
  if (isServerSide()) return
35
32
 
36
- window.dataLayer ||= []
37
- window.dataLayer.push({
33
+ globalThis.dataLayer ||= []
34
+ globalThis.dataLayer.push({
38
35
  'gtm.start': Date.now(),
39
36
  event: 'gtm.js',
40
37
  })
@@ -63,6 +60,6 @@ export function loadHotjar(hjid: number): void {
63
60
  r.async = 1
64
61
  r.src = t + h._hjSettings.hjid + j + h._hjSettings.hjsv
65
62
  a.append(r)
66
- })(window, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=')
63
+ })(globalThis, document, 'https://static.hotjar.com/c/hotjar-', '.js?sv=')
67
64
  /* eslint-enable */
68
65
  }
@@ -0,0 +1,11 @@
1
+ import { z as z4, ZodType } from 'zod/v4'
2
+ import { customZodSchemas } from './zod.shared.schemas.js'
3
+
4
+ type ExtendedZod = Omit<typeof z4, keyof typeof customZodSchemas | 'iso'> & typeof customZodSchemas
5
+
6
+ const z: ExtendedZod = { ...z4, ...customZodSchemas }
7
+
8
+ // eslint-disable-next-line @typescript-eslint/naming-convention
9
+ type zInfer<T> = z4.infer<T>
10
+
11
+ export { z, type zInfer, ZodType }
package/src/zod/index.ts CHANGED
@@ -1,5 +1,3 @@
1
+ export * from './customZod.js'
1
2
  export * from './zod.shared.schemas.js'
2
3
  export * from './zod.util.js'
3
- import { z, ZodType } from 'zod/v4'
4
-
5
- export { z, ZodType }
@@ -3,113 +3,101 @@ import { z } from 'zod/v4'
3
3
  export const TS_2500 = 16725225600 // 2500-01-01
4
4
  export const TS_2000 = 946684800 // 2000-01-01
5
5
 
6
- export const zUnixTimestamp = z
7
- .number()
8
- .int()
9
- .min(0)
10
- .max(TS_2500, 'Must be a UnixTimestamp number')
11
- // .transform(v => v as UnixTimestamp) // breaks jsonSchema
12
- .describe('UnixTimestamp')
13
- export const zUnixTimestamp2000 = z
14
- .number()
15
- .int()
16
- .min(TS_2000)
17
- .max(TS_2500, 'Must be a UnixTimestamp number after 2000-01-01')
18
- // .transform(v => v as UnixTimestamp)
19
- .describe('UnixTimestamp2000')
20
- export const zUnixTimestampMillis = z
21
- .number()
22
- .int()
23
- .min(0)
24
- .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number')
25
- // .transform(v => v as UnixTimestampMillis)
26
- .describe('UnixTimestampMillis')
27
- export const zUnixTimestampMillis2000 = z
28
- .number()
29
- .int()
30
- .min(TS_2000 * 1000)
31
- .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number after 2000-01-01')
32
- // .transform(v => v as UnixTimestampMillis)
33
- .describe('UnixTimestampMillis2000')
34
-
35
- export const zSemVer = z
36
- .string()
37
- .regex(/^[0-9]+\.[0-9]+\.[0-9]+$/, 'Must be a SemVer string')
38
- .describe('SemVer')
39
-
40
- export const zIsoDate = z
41
- .string()
42
- .refine(v => {
43
- return /^\d{4}-\d{2}-\d{2}$/.test(v)
44
- }, 'Must be an IsoDateString')
45
- // .transform(v => v as IsoDate)
46
- .describe('IsoDateString')
47
-
48
- export const zEmail = z
49
- .string()
50
- .trim()
51
- .email() // keeping as-is, so trim happens before email validation
52
- .transform(s => s.toLowerCase()) // breaks toJsonSchema
53
- .describe('Email')
54
-
55
- export const zEmailNoLowercase = z
56
- .string()
57
- .trim()
58
- .email() // keeping as-is, so trim happens before email validation
59
- // .transform(s => s.toLowerCase()) // breaks toJsonSchema
60
- .describe('Email')
6
+ export const zUnixTimestamp = (): z.ZodNumber =>
7
+ z
8
+ .number()
9
+ .int()
10
+ .min(0)
11
+ .max(TS_2500, 'Must be a UnixTimestamp number')
12
+ // .transform(v => v as UnixTimestamp) // breaks jsonSchema
13
+ .describe('UnixTimestamp')
14
+
15
+ export const zUnixTimestamp2000 = (): z.ZodNumber =>
16
+ z
17
+ .number()
18
+ .int()
19
+ .min(TS_2000)
20
+ .max(TS_2500, 'Must be a UnixTimestamp number after 2000-01-01')
21
+ // .transform(v => v as UnixTimestamp)
22
+ .describe('UnixTimestamp2000')
23
+
24
+ export const zUnixTimestampMillis = (): z.ZodNumber =>
25
+ z
26
+ .number()
27
+ .int()
28
+ .min(0)
29
+ .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number')
30
+ // .transform(v => v as UnixTimestampMillis)
31
+ .describe('UnixTimestampMillis')
32
+
33
+ export const zUnixTimestampMillis2000 = (): z.ZodNumber =>
34
+ z
35
+ .number()
36
+ .int()
37
+ .min(TS_2000 * 1000)
38
+ .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number after 2000-01-01')
39
+ // .transform(v => v as UnixTimestampMillis)
40
+ .describe('UnixTimestampMillis2000')
41
+
42
+ export const zSemVer = (): z.ZodString =>
43
+ z
44
+ .string()
45
+ .regex(/^[0-9]+\.[0-9]+\.[0-9]+$/, 'Must be a SemVer string')
46
+ .describe('SemVer')
47
+
48
+ export const zIsoDate = (): z.ZodString =>
49
+ z
50
+ .string()
51
+ .refine(v => {
52
+ return /^\d{4}-\d{2}-\d{2}$/.test(v)
53
+ }, 'Must be an IsoDateString')
54
+ .describe('IsoDateString')
55
+
56
+ export const zEmail = (): z.ZodEmail => z.email().describe('Email')
61
57
 
62
58
  export const BASE62_REGEX = /^[a-zA-Z0-9]+$/
63
59
  export const BASE64_REGEX = /^[A-Za-z0-9+/]+={0,2}$/
64
- export const BASE64URL_REGEX = /^[\w-/]+$/
65
- export const zBase62 = z
66
- .string()
67
- .regex(BASE62_REGEX, 'Must be a base62 string')
68
- .describe('Base62String')
69
- export const zBase64 = z
70
- .string()
71
- .regex(BASE64_REGEX, 'Must be a base64 string')
72
- .describe('Base64String')
73
- export const zBase64Url = z
74
- .string()
75
- .regex(BASE64URL_REGEX, 'Must be a base64url string')
76
- .describe('Base64UrlString')
60
+ export const BASE64URL_REGEX = /^[\w\-/]+$/
61
+
62
+ export const zBase62 = (): z.ZodString =>
63
+ z.string().regex(BASE62_REGEX, 'Must be a base62 string').describe('Base62String')
64
+
65
+ export const zBase64 = (): z.ZodString =>
66
+ z.string().regex(BASE64_REGEX, 'Must be a base64 string').describe('Base64String')
67
+
68
+ export const zBase64Url = (): z.ZodString =>
69
+ z.string().regex(BASE64URL_REGEX, 'Must be a base64url string').describe('Base64UrlString')
77
70
 
78
71
  export const JWT_REGEX = /^[\w-]+\.[\w-]+\.[\w-]+$/
79
- export const zJwt = z.string().regex(JWT_REGEX, 'Must be a JWT string').describe('JWTString')
80
-
81
- export const zId = z
82
- .string()
83
- .regex(/^[a-zA-Z0-9_]{6,64}$/, 'Must be an id string (6 to 64 chars long)')
84
- .describe('IdString')
85
- export const zIdBase62 = z
86
- .string()
87
- .regex(/^[a-zA-Z0-9]{8,64}$/, 'Must be a base62 id string')
88
- .describe('Base62Id')
89
- export const zIdBase64 = z
90
- .string()
91
- .regex(/^[A-Za-z0-9+/]{6,62}={0,2}$/, 'Must be a base64 id string')
92
- .describe('Base64Id')
93
- export const zIdBase64Url = z
94
- .string()
95
- .regex(/^[\w-/]{8,64}$/, 'Must be a base64url id string')
96
- .describe('Base64UrlId')
72
+ export const zJwt = (): z.ZodString =>
73
+ z.string().regex(JWT_REGEX, 'Must be a JWT string').describe('JWTString')
97
74
 
98
75
  /**
99
76
  * "Slug" - a valid URL, filename, etc.
100
77
  */
101
- export const zSlug = z
102
- .string()
103
- .regex(/^[a-z0-9-]{1,255}$/, 'Must be a slug string')
104
- .describe('Slug')
105
-
106
- export const zBaseDBEntity = z
107
- .object({
108
- id: z.string(),
109
- // created/updated are intentionally optional here
110
- created: zUnixTimestamp2000.optional(),
111
- updated: zUnixTimestamp2000.optional(),
112
- })
113
- .describe('BaseDBEntity')
114
-
115
- // export const zSavedDBEntity = zBaseDBEntity.required().describe('SavedDBEntity')
78
+ export const zSlug = (): z.ZodString =>
79
+ z
80
+ .string()
81
+ .regex(/^[a-z0-9-]{1,255}$/, 'Must be a slug string')
82
+ .describe('Slug')
83
+
84
+ export const zIanaTimezone = (): z.ZodEnum =>
85
+ z
86
+ // UTC is added to assist unit-testing, which uses UTC by default (not technically a valid Iana timezone identifier)
87
+ .enum([...Intl.supportedValuesOf('timeZone'), 'UTC'])
88
+
89
+ export const customZodSchemas = {
90
+ base62: zBase62,
91
+ base64: zBase64,
92
+ base64Url: zBase64Url,
93
+ email: zEmail,
94
+ ianaTimezone: zIanaTimezone,
95
+ isoDate: zIsoDate,
96
+ jwt: zJwt,
97
+ slug: zSlug,
98
+ semver: zSemVer,
99
+ unixTimestamp: zUnixTimestamp,
100
+ unixTimestamp2000: zUnixTimestamp2000,
101
+ unixTimestampMillis: zUnixTimestampMillis,
102
+ unixTimestampMillis2000: zUnixTimestampMillis2000,
103
+ }