@naturalcycles/js-lib 15.68.0 → 15.69.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.
@@ -3,4 +3,4 @@
3
3
  *
4
4
  * Source: https://regexr.com/3e48o
5
5
  */
6
- export const SIMPLE_EMAIL_REGEX = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/;
6
+ export const SIMPLE_EMAIL_REGEX = /^[\w\-.]+@([\w-]+\.)+[\w-]{2,4}$/;
package/package.json CHANGED
@@ -1,20 +1,16 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.68.0",
4
+ "version": "15.69.0",
5
5
  "dependencies": {
6
6
  "tslib": "^2"
7
7
  },
8
8
  "peerDependencies": {
9
- "undici": "^7",
10
- "zod": "^4"
9
+ "undici": "^7"
11
10
  },
12
11
  "peerDependenciesMeta": {
13
12
  "undici": {
14
13
  "optional": true
15
- },
16
- "zod": {
17
- "optional": true
18
14
  }
19
15
  },
20
16
  "devDependencies": {
@@ -52,8 +48,7 @@
52
48
  "./semver": "./dist/semver.js",
53
49
  "./string": "./dist/string/index.js",
54
50
  "./string/*.js": "./dist/string/*.js",
55
- "./types": "./dist/types.js",
56
- "./zod": "./dist/zod/index.js"
51
+ "./types": "./dist/types.js"
57
52
  },
58
53
  "files": [
59
54
  "dist",
@@ -3,4 +3,4 @@
3
3
  *
4
4
  * Source: https://regexr.com/3e48o
5
5
  */
6
- export const SIMPLE_EMAIL_REGEX = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/
6
+ export const SIMPLE_EMAIL_REGEX = /^[\w\-.]+@([\w-]+\.)+[\w-]{2,4}$/
@@ -1,6 +0,0 @@
1
- import { z as z4, ZodType } from 'zod';
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 };
@@ -1,4 +0,0 @@
1
- import { z as z4, ZodType } from 'zod';
2
- import { customZodSchemas } from './zod.shared.schemas.js';
3
- const z = { ...z4, ...customZodSchemas };
4
- export { z, ZodType };
@@ -1,3 +0,0 @@
1
- export * from './customZod.js';
2
- export * from './zod.shared.schemas.js';
3
- export * from './zod.util.js';
package/dist/zod/index.js DELETED
@@ -1,3 +0,0 @@
1
- export * from './customZod.js';
2
- export * from './zod.shared.schemas.js';
3
- export * from './zod.util.js';
@@ -1,46 +0,0 @@
1
- import type { ZodString } from 'zod';
2
- import { z } from 'zod';
3
- import type { IANATimezone, IsoDate, UnixTimestamp, UnixTimestampMillis } from '../types.js';
4
- type ZodBranded<T, B> = T & Record<'_zod', Record<'output', B>>;
5
- export type ZodBrandedString<B> = ZodBranded<z.ZodString, B>;
6
- export type ZodBrandedInt<B> = ZodBranded<z.ZodInt, B>;
7
- export type ZodBrandedNumber<B> = ZodBranded<z.ZodNumber, B>;
8
- export type ZodBrandedIsoDate = ZodBranded<z.ZodISODate, IsoDate>;
9
- declare function unixTimestamp(): ZodBrandedInt<UnixTimestamp>;
10
- declare function unixTimestamp2000(): ZodBrandedInt<UnixTimestamp>;
11
- declare function unixTimestampMillis(): ZodBranded<z.ZodNumber, UnixTimestampMillis>;
12
- declare function unixTimestampMillis2000(): ZodBrandedInt<UnixTimestampMillis>;
13
- declare function semVer(): z.ZodString;
14
- declare function isoDate(): ZodBrandedString<IsoDate>;
15
- declare function base62(): z.ZodString;
16
- declare function base64(): z.ZodString;
17
- declare function base64Url(): z.ZodString;
18
- declare function jwt(): z.ZodString;
19
- /**
20
- * "Slug" - a valid URL, filename, etc.
21
- */
22
- declare function slug(): z.ZodString;
23
- declare function ianaTimezone(): ZodBrandedString<IANATimezone>;
24
- type BaseDBEntityZodShape = {
25
- id: ZodString;
26
- created: ZodBrandedInt<UnixTimestamp>;
27
- updated: ZodBrandedInt<UnixTimestamp>;
28
- };
29
- declare function dbEntity(): z.ZodObject<BaseDBEntityZodShape>;
30
- declare function dbEntity<T extends z.ZodRawShape>(shape: T): z.ZodObject<BaseDBEntityZodShape & T>;
31
- export declare const customZodSchemas: {
32
- base62: typeof base62;
33
- base64: typeof base64;
34
- base64Url: typeof base64Url;
35
- dbEntity: typeof dbEntity;
36
- ianaTimezone: typeof ianaTimezone;
37
- isoDate: typeof isoDate;
38
- jwt: typeof jwt;
39
- slug: typeof slug;
40
- semver: typeof semVer;
41
- unixTimestamp: typeof unixTimestamp;
42
- unixTimestamp2000: typeof unixTimestamp2000;
43
- unixTimestampMillis: typeof unixTimestampMillis;
44
- unixTimestampMillis2000: typeof unixTimestampMillis2000;
45
- };
46
- export {};
@@ -1,101 +0,0 @@
1
- import { z } from 'zod';
2
- const TS_2500 = 16725225600; // 2500-01-01
3
- const TS_2000 = 946684800; // 2000-01-01
4
- function unixTimestamp() {
5
- return z
6
- .number()
7
- .int()
8
- .min(0)
9
- .max(TS_2500, 'Must be a UnixTimestamp number')
10
- .describe('UnixTimestamp');
11
- }
12
- function unixTimestamp2000() {
13
- return z
14
- .number()
15
- .int()
16
- .min(TS_2000)
17
- .max(TS_2500, 'Must be a UnixTimestamp number after 2000-01-01')
18
- .describe('UnixTimestamp2000');
19
- }
20
- function unixTimestampMillis() {
21
- return z
22
- .number()
23
- .int()
24
- .min(0)
25
- .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number')
26
- .describe('UnixTimestampMillis');
27
- }
28
- function unixTimestampMillis2000() {
29
- return z
30
- .number()
31
- .int()
32
- .min(TS_2000 * 1000)
33
- .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number after 2000-01-01')
34
- .describe('UnixTimestampMillis2000');
35
- }
36
- function semVer() {
37
- return z
38
- .string()
39
- .regex(/^[0-9]+\.[0-9]+\.[0-9]+$/, 'Must be a SemVer string')
40
- .describe('SemVer');
41
- }
42
- function isoDate() {
43
- return z
44
- .string()
45
- .regex(/^\d{4}-\d{2}-\d{2}$/, { error: 'Must be a YYYY-MM-DD string' })
46
- .describe('IsoDate');
47
- }
48
- const BASE62_REGEX = /^[a-zA-Z0-9]+$/;
49
- const BASE64_REGEX = /^[A-Za-z0-9+/]+={0,2}$/;
50
- const BASE64URL_REGEX = /^[\w\-/]+$/;
51
- function base62() {
52
- return z.string().regex(BASE62_REGEX, 'Must be a base62 string').describe('Base62String');
53
- }
54
- function base64() {
55
- return z.string().regex(BASE64_REGEX, 'Must be a base64 string').describe('Base64String');
56
- }
57
- function base64Url() {
58
- return z.string().regex(BASE64URL_REGEX, 'Must be a base64url string').describe('Base64UrlString');
59
- }
60
- const JWT_REGEX = /^[\w-]+\.[\w-]+\.[\w-]+$/;
61
- function jwt() {
62
- return z.string().regex(JWT_REGEX, 'Must be a JWT string').describe('JWTString');
63
- }
64
- /**
65
- * "Slug" - a valid URL, filename, etc.
66
- */
67
- function slug() {
68
- return z
69
- .string()
70
- .regex(/^[a-z0-9-]{1,255}$/, 'Must be a slug string')
71
- .describe('Slug');
72
- }
73
- function ianaTimezone() {
74
- return z
75
- // UTC is added to assist unit-testing, which uses UTC by default (not technically a valid Iana timezone identifier)
76
- .enum([...Intl.supportedValuesOf('timeZone'), 'UTC'])
77
- .describe('IANATimezone');
78
- }
79
- const baseDBEntitySchema = z.object({
80
- id: z.string(),
81
- created: unixTimestamp2000(),
82
- updated: unixTimestamp2000(),
83
- });
84
- function dbEntity(shape) {
85
- return baseDBEntitySchema.extend(shape ?? {});
86
- }
87
- export const customZodSchemas = {
88
- base62,
89
- base64,
90
- base64Url,
91
- dbEntity,
92
- ianaTimezone,
93
- isoDate,
94
- jwt,
95
- slug,
96
- semver: semVer,
97
- unixTimestamp,
98
- unixTimestamp2000,
99
- unixTimestampMillis,
100
- unixTimestampMillis2000,
101
- };
@@ -1,13 +0,0 @@
1
- import type { ZodError, ZodType } from 'zod';
2
- import type { ErrorData } from '../error/error.model.js';
3
- import { AppError } from '../error/error.util.js';
4
- import type { ValidationFunction, ValidationFunctionResult } from '../validation/validation.js';
5
- export declare function getZodValidationFunction<T>(schema: ZodType<T>): ValidationFunction<T, ZodValidationError>;
6
- export declare function zIsValid<T>(value: unknown, schema: ZodType<T>): boolean;
7
- export declare function zValidate<T>(value: unknown, schema: ZodType<T>): T;
8
- export declare function zSafeValidate<T>(input: unknown, schema: ZodType<T>): ValidationFunctionResult<T, ZodValidationError>;
9
- export interface ZodValidationErrorData extends ErrorData {
10
- }
11
- export declare class ZodValidationError extends AppError<ZodValidationErrorData> {
12
- constructor(zodError: ZodError, value: any, schema: ZodType);
13
- }
@@ -1,54 +0,0 @@
1
- import { _assert } from '../error/assert.js';
2
- import { AppError } from '../error/error.util.js';
3
- import { _stringify } from '../string/stringify.js';
4
- export function getZodValidationFunction(schema) {
5
- return (input, opt) => {
6
- _assert(!opt?.mutateInput, 'mutateInput=true is not yet supported with Zod');
7
- return zSafeValidate(input, schema);
8
- };
9
- }
10
- export function zIsValid(value, schema) {
11
- const { success } = schema.safeParse(value);
12
- return success;
13
- }
14
- export function zValidate(value, schema) {
15
- const [err, data] = zSafeValidate(value, schema);
16
- if (err)
17
- throw err;
18
- return data;
19
- }
20
- export function zSafeValidate(input, schema
21
- // inputName?: string,
22
- ) {
23
- const r = schema.safeParse(input);
24
- if (r.success) {
25
- return [null, r.data];
26
- }
27
- return [new ZodValidationError(r.error, input, schema), r.data ?? input];
28
- }
29
- export class ZodValidationError extends AppError {
30
- constructor(zodError, value, schema) {
31
- const message = createZodErrorMessage(zodError, schema, value);
32
- // const message = z.prettifyError(zodError) // todo: consider adopting it instead
33
- super(message, {}, { name: 'ZodValidationError' });
34
- }
35
- }
36
- function createZodErrorMessage(err, schema, value) {
37
- let objectTitle = schema.description;
38
- if (typeof value === 'object' && value) {
39
- const inputName = schema.description || value.constructor?.name;
40
- const inputId = value['id'];
41
- objectTitle = [inputName, inputId].filter(Boolean).join('.');
42
- }
43
- objectTitle ||= 'data';
44
- return [
45
- `Invalid ${objectTitle}`,
46
- '',
47
- 'Input:',
48
- _stringify(value),
49
- err.issues.length > 1 ? `\n${err.issues.length} issues:` : '',
50
- ...err.issues.slice(0, 100).map(i => {
51
- return [i.path.join('.'), i.message].filter(Boolean).join(': ');
52
- }),
53
- ].join('\n');
54
- }
@@ -1,11 +0,0 @@
1
- import { z as z4, ZodType } from 'zod'
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 DELETED
@@ -1,3 +0,0 @@
1
- export * from './customZod.js'
2
- export * from './zod.shared.schemas.js'
3
- export * from './zod.util.js'
@@ -1,139 +0,0 @@
1
- import type { ZodString } from 'zod'
2
- import { z } from 'zod'
3
- import type { IANATimezone, IsoDate, UnixTimestamp, UnixTimestampMillis } from '../types.js'
4
-
5
- type ZodBranded<T, B> = T & Record<'_zod', Record<'output', B>>
6
- export type ZodBrandedString<B> = ZodBranded<z.ZodString, B>
7
- export type ZodBrandedInt<B> = ZodBranded<z.ZodInt, B>
8
- export type ZodBrandedNumber<B> = ZodBranded<z.ZodNumber, B>
9
- export type ZodBrandedIsoDate = ZodBranded<z.ZodISODate, IsoDate>
10
-
11
- const TS_2500 = 16725225600 // 2500-01-01
12
- const TS_2000 = 946684800 // 2000-01-01
13
-
14
- function unixTimestamp(): ZodBrandedInt<UnixTimestamp> {
15
- return z
16
- .number()
17
- .int()
18
- .min(0)
19
- .max(TS_2500, 'Must be a UnixTimestamp number')
20
- .describe('UnixTimestamp') as ZodBrandedInt<UnixTimestamp>
21
- }
22
-
23
- function unixTimestamp2000(): ZodBrandedInt<UnixTimestamp> {
24
- return z
25
- .number()
26
- .int()
27
- .min(TS_2000)
28
- .max(TS_2500, 'Must be a UnixTimestamp number after 2000-01-01')
29
- .describe('UnixTimestamp2000') as ZodBrandedInt<UnixTimestamp>
30
- }
31
-
32
- function unixTimestampMillis(): ZodBranded<z.ZodNumber, UnixTimestampMillis> {
33
- return z
34
- .number()
35
- .int()
36
- .min(0)
37
- .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number')
38
- .describe('UnixTimestampMillis') as ZodBrandedInt<UnixTimestampMillis>
39
- }
40
-
41
- function unixTimestampMillis2000(): ZodBrandedInt<UnixTimestampMillis> {
42
- return z
43
- .number()
44
- .int()
45
- .min(TS_2000 * 1000)
46
- .max(TS_2500 * 1000, 'Must be a UnixTimestampMillis number after 2000-01-01')
47
- .describe('UnixTimestampMillis2000') as ZodBrandedInt<UnixTimestampMillis>
48
- }
49
-
50
- function semVer(): z.ZodString {
51
- return z
52
- .string()
53
- .regex(/^[0-9]+\.[0-9]+\.[0-9]+$/, 'Must be a SemVer string')
54
- .describe('SemVer')
55
- }
56
-
57
- function isoDate(): ZodBrandedString<IsoDate> {
58
- return z
59
- .string()
60
- .regex(/^\d{4}-\d{2}-\d{2}$/, { error: 'Must be a YYYY-MM-DD string' })
61
- .describe('IsoDate') as ZodBrandedString<IsoDate>
62
- }
63
-
64
- const BASE62_REGEX = /^[a-zA-Z0-9]+$/
65
- const BASE64_REGEX = /^[A-Za-z0-9+/]+={0,2}$/
66
- const BASE64URL_REGEX = /^[\w\-/]+$/
67
-
68
- function base62(): z.ZodString {
69
- return z.string().regex(BASE62_REGEX, 'Must be a base62 string').describe('Base62String')
70
- }
71
-
72
- function base64(): z.ZodString {
73
- return z.string().regex(BASE64_REGEX, 'Must be a base64 string').describe('Base64String')
74
- }
75
-
76
- function base64Url(): z.ZodString {
77
- return z.string().regex(BASE64URL_REGEX, 'Must be a base64url string').describe('Base64UrlString')
78
- }
79
-
80
- const JWT_REGEX = /^[\w-]+\.[\w-]+\.[\w-]+$/
81
-
82
- function jwt(): z.ZodString {
83
- return z.string().regex(JWT_REGEX, 'Must be a JWT string').describe('JWTString')
84
- }
85
-
86
- /**
87
- * "Slug" - a valid URL, filename, etc.
88
- */
89
- function slug(): z.ZodString {
90
- return z
91
- .string()
92
- .regex(/^[a-z0-9-]{1,255}$/, 'Must be a slug string')
93
- .describe('Slug')
94
- }
95
-
96
- function ianaTimezone(): ZodBrandedString<IANATimezone> {
97
- return (
98
- z
99
- // UTC is added to assist unit-testing, which uses UTC by default (not technically a valid Iana timezone identifier)
100
- .enum([...Intl.supportedValuesOf('timeZone'), 'UTC'])
101
- .describe('IANATimezone') as unknown as ZodBrandedString<IANATimezone>
102
- )
103
- }
104
-
105
- const baseDBEntitySchema = z.object({
106
- id: z.string(),
107
- created: unixTimestamp2000(),
108
- updated: unixTimestamp2000(),
109
- })
110
-
111
- // oxlint-disable-next-line @typescript-eslint/consistent-type-definitions
112
- type BaseDBEntityZodShape = {
113
- id: ZodString
114
- created: ZodBrandedInt<UnixTimestamp>
115
- updated: ZodBrandedInt<UnixTimestamp>
116
- }
117
-
118
- function dbEntity(): z.ZodObject<BaseDBEntityZodShape>
119
- function dbEntity<T extends z.ZodRawShape>(shape: T): z.ZodObject<BaseDBEntityZodShape & T>
120
-
121
- function dbEntity<T extends z.ZodRawShape>(shape?: T): z.ZodObject<BaseDBEntityZodShape & T> {
122
- return baseDBEntitySchema.extend(shape ?? {}) as z.ZodObject<BaseDBEntityZodShape & T>
123
- }
124
-
125
- export const customZodSchemas = {
126
- base62,
127
- base64,
128
- base64Url,
129
- dbEntity,
130
- ianaTimezone,
131
- isoDate,
132
- jwt,
133
- slug,
134
- semver: semVer,
135
- unixTimestamp,
136
- unixTimestamp2000,
137
- unixTimestampMillis,
138
- unixTimestampMillis2000,
139
- }
@@ -1,72 +0,0 @@
1
- import type { ZodError, ZodType } from 'zod'
2
- import { _assert } from '../error/assert.js'
3
- import type { ErrorData } from '../error/error.model.js'
4
- import { AppError } from '../error/error.util.js'
5
- import { _stringify } from '../string/stringify.js'
6
- import type { ValidationFunction, ValidationFunctionResult } from '../validation/validation.js'
7
-
8
- export function getZodValidationFunction<T>(
9
- schema: ZodType<T>,
10
- ): ValidationFunction<T, ZodValidationError> {
11
- return (input, opt) => {
12
- _assert(!opt?.mutateInput, 'mutateInput=true is not yet supported with Zod')
13
- return zSafeValidate(input, schema)
14
- }
15
- }
16
-
17
- export function zIsValid<T>(value: unknown, schema: ZodType<T>): boolean {
18
- const { success } = schema.safeParse(value)
19
- return success
20
- }
21
-
22
- export function zValidate<T>(value: unknown, schema: ZodType<T>): T {
23
- const [err, data] = zSafeValidate(value, schema)
24
- if (err) throw err
25
- return data
26
- }
27
-
28
- export function zSafeValidate<T>(
29
- input: unknown,
30
- schema: ZodType<T>,
31
- // inputName?: string,
32
- ): ValidationFunctionResult<T, ZodValidationError> {
33
- const r = schema.safeParse(input)
34
- if (r.success) {
35
- return [null, r.data]
36
- }
37
-
38
- return [new ZodValidationError(r.error, input, schema), r.data ?? (input as T)]
39
- }
40
-
41
- export interface ZodValidationErrorData extends ErrorData {}
42
-
43
- export class ZodValidationError extends AppError<ZodValidationErrorData> {
44
- constructor(zodError: ZodError, value: any, schema: ZodType) {
45
- const message = createZodErrorMessage(zodError, schema, value)
46
- // const message = z.prettifyError(zodError) // todo: consider adopting it instead
47
- super(message, {}, { name: 'ZodValidationError' })
48
- }
49
- }
50
-
51
- function createZodErrorMessage<T>(err: ZodError<T>, schema: ZodType<T>, value: T): string {
52
- let objectTitle = schema.description
53
-
54
- if (typeof value === 'object' && value) {
55
- const inputName = schema.description || value.constructor?.name
56
- const inputId = (value as any)['id'] as string
57
- objectTitle = [inputName, inputId].filter(Boolean).join('.')
58
- }
59
-
60
- objectTitle ||= 'data'
61
-
62
- return [
63
- `Invalid ${objectTitle}`,
64
- '',
65
- 'Input:',
66
- _stringify(value),
67
- err.issues.length > 1 ? `\n${err.issues.length} issues:` : '',
68
- ...err.issues.slice(0, 100).map(i => {
69
- return [i.path.join('.'), i.message].filter(Boolean).join(': ')
70
- }),
71
- ].join('\n')
72
- }