@naturalcycles/js-lib 15.24.1 → 15.25.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.
@@ -47,7 +47,7 @@ export interface JsonSchemaNot<T = unknown> extends JsonSchemaAny<T> {
47
47
  export interface JsonSchemaConst<T = unknown> extends JsonSchemaAny<T> {
48
48
  const: T;
49
49
  }
50
- export interface JsonSchemaString extends JsonSchemaAny<string> {
50
+ export interface JsonSchemaString<T extends string = string> extends JsonSchemaAny<T> {
51
51
  type: 'string';
52
52
  pattern?: string;
53
53
  minLength?: number;
@@ -60,7 +60,7 @@ export interface JsonSchemaString extends JsonSchemaAny<string> {
60
60
  */
61
61
  transform?: ('trim' | 'toLowerCase' | 'toUpperCase')[];
62
62
  }
63
- export interface JsonSchemaNumber extends JsonSchemaAny<number> {
63
+ export interface JsonSchemaNumber<T extends number = number> extends JsonSchemaAny<T> {
64
64
  type: 'number' | 'integer';
65
65
  format?: string;
66
66
  multipleOf?: number;
@@ -1,13 +1,13 @@
1
- import type { AnyObject, BaseDBEntity } from '../types.js';
1
+ import type { AnyObject, BaseDBEntity, IsoDate, UnixTimestamp } from '../types.js';
2
2
  import type { JsonSchema, JsonSchemaAllOf, JsonSchemaAny, JsonSchemaArray, JsonSchemaBoolean, JsonSchemaConst, JsonSchemaEnum, JsonSchemaNull, JsonSchemaNumber, JsonSchemaObject, JsonSchemaOneOf, JsonSchemaRef, JsonSchemaString, JsonSchemaTuple } from './jsonSchema.model.js';
3
3
  export interface JsonSchemaBuilder<T = unknown> {
4
4
  build: () => JsonSchema<T>;
5
5
  }
6
6
  /**
7
7
  * Fluent (chainable) API to manually create Json Schemas.
8
- * Inspired by Joi
8
+ * Inspired by Joi and Zod.
9
9
  */
10
- export declare const jsonSchema: {
10
+ export declare const j: {
11
11
  any<T = unknown>(): JsonSchemaAnyBuilder<T, JsonSchemaAny<T>>;
12
12
  const<T = unknown>(value: T): JsonSchemaAnyBuilder<T, JsonSchemaConst<T>>;
13
13
  null(): JsonSchemaAnyBuilder<null, JsonSchemaNull>;
@@ -15,14 +15,14 @@ export declare const jsonSchema: {
15
15
  enum<T = unknown>(enumValues: T[]): JsonSchemaAnyBuilder<T, JsonSchemaEnum<T>>;
16
16
  boolean(): JsonSchemaAnyBuilder<boolean, JsonSchemaBoolean>;
17
17
  buffer(): JsonSchemaAnyBuilder<Buffer<ArrayBufferLike>, JsonSchemaAny<Buffer<ArrayBufferLike>>>;
18
- number(): JsonSchemaNumberBuilder;
19
- integer(): JsonSchemaNumberBuilder;
20
- unixTimestamp(): JsonSchemaNumberBuilder;
21
- unixTimestamp2000(): JsonSchemaNumberBuilder;
22
- string(): JsonSchemaStringBuilder;
23
- dateString(): JsonSchemaStringBuilder;
24
- object<T extends AnyObject>(props: { [k in keyof T]: JsonSchemaAnyBuilder<T[k]>; }): JsonSchemaObjectBuilder<T>;
25
- rootObject<T extends AnyObject>(props: { [k in keyof T]: JsonSchemaAnyBuilder<T[k]>; }): JsonSchemaObjectBuilder<T>;
18
+ number<T extends number = number>(): JsonSchemaNumberBuilder<T>;
19
+ integer<T extends number = number>(): JsonSchemaNumberBuilder<T>;
20
+ unixTimestamp(): JsonSchemaNumberBuilder<UnixTimestamp>;
21
+ unixTimestamp2000(): JsonSchemaNumberBuilder<UnixTimestamp>;
22
+ string<T extends string = string>(): JsonSchemaStringBuilder<T>;
23
+ isoDate(): JsonSchemaStringBuilder<IsoDate>;
24
+ object<T extends AnyObject>(props: { [K in keyof T]: JsonSchemaAnyBuilder<T[K]>; }): JsonSchemaObjectBuilder<T>;
25
+ rootObject<T extends AnyObject>(props: { [K in keyof T]: JsonSchemaAnyBuilder<T[K]>; }): JsonSchemaObjectBuilder<T>;
26
26
  array<ITEM = unknown>(itemSchema: JsonSchemaAnyBuilder<ITEM>): JsonSchemaArrayBuilder<ITEM>;
27
27
  tuple<T extends any[] = unknown[]>(items: JsonSchemaAnyBuilder[]): JsonSchemaTupleBuilder<T>;
28
28
  oneOf<T = unknown>(items: JsonSchemaAnyBuilder[]): JsonSchemaAnyBuilder<T, JsonSchemaOneOf<T>>;
@@ -53,8 +53,12 @@ export declare class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonS
53
53
  */
54
54
  build(): SCHEMA_TYPE;
55
55
  clone(): JsonSchemaAnyBuilder<T, SCHEMA_TYPE>;
56
+ /**
57
+ * @experimental
58
+ */
59
+ infer: T;
56
60
  }
57
- export declare class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder<number, JsonSchemaNumber> {
61
+ export declare class JsonSchemaNumberBuilder<T extends number = number> extends JsonSchemaAnyBuilder<T, JsonSchemaNumber<T>> {
58
62
  constructor();
59
63
  integer(): this;
60
64
  multipleOf(multipleOf: number): this;
@@ -78,7 +82,7 @@ export declare class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder<number
78
82
  utcOffset: () => this;
79
83
  utcOffsetHours: () => this;
80
84
  }
81
- export declare class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder<string, JsonSchemaString> {
85
+ export declare class JsonSchemaStringBuilder<T extends string = string> extends JsonSchemaAnyBuilder<T, JsonSchemaString<T>> {
82
86
  constructor();
83
87
  pattern(pattern: string): this;
84
88
  min(minLength: number): this;
@@ -86,7 +90,7 @@ export declare class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder<string
86
90
  length(minLength: number, maxLength: number): this;
87
91
  format(format: string): this;
88
92
  email: () => this;
89
- date: () => this;
93
+ isoDate: () => this;
90
94
  url: () => this;
91
95
  ipv4: () => this;
92
96
  ipv6: () => this;
@@ -5,9 +5,9 @@ import { JSON_SCHEMA_ORDER } from './jsonSchema.cnst.js';
5
5
  import { mergeJsonSchemaObjects } from './jsonSchema.util.js';
6
6
  /**
7
7
  * Fluent (chainable) API to manually create Json Schemas.
8
- * Inspired by Joi
8
+ * Inspired by Joi and Zod.
9
9
  */
10
- export const jsonSchema = {
10
+ export const j = {
11
11
  any() {
12
12
  return new JsonSchemaAnyBuilder({});
13
13
  },
@@ -56,8 +56,8 @@ export const jsonSchema = {
56
56
  string() {
57
57
  return new JsonSchemaStringBuilder();
58
58
  },
59
- dateString() {
60
- return new JsonSchemaStringBuilder().date();
59
+ isoDate() {
60
+ return new JsonSchemaStringBuilder().isoDate();
61
61
  },
62
62
  // email: () => new JsonSchemaStringBuilder().email(),
63
63
  // complex types
@@ -158,6 +158,10 @@ export class JsonSchemaAnyBuilder {
158
158
  clone() {
159
159
  return new JsonSchemaAnyBuilder(_deepCopy(this.schema));
160
160
  }
161
+ /**
162
+ * @experimental
163
+ */
164
+ infer;
161
165
  }
162
166
  export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder {
163
167
  constructor() {
@@ -204,10 +208,10 @@ export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder {
204
208
  int64 = () => this.format('int64');
205
209
  float = () => this.format('float');
206
210
  double = () => this.format('double');
207
- unixTimestamp = () => this.format('unixTimestamp');
208
- unixTimestamp2000 = () => this.format('unixTimestamp2000');
209
- unixTimestampMillis = () => this.format('unixTimestampMillis');
210
- unixTimestampMillis2000 = () => this.format('unixTimestampMillis2000');
211
+ unixTimestamp = () => this.format('unixTimestamp').description('UnixTimestamp');
212
+ unixTimestamp2000 = () => this.format('unixTimestamp2000').description('UnixTimestamp2000');
213
+ unixTimestampMillis = () => this.format('unixTimestampMillis').description('UnixTimestampMillis');
214
+ unixTimestampMillis2000 = () => this.format('unixTimestampMillis2000').description('UnixTimestampMillis2000');
211
215
  utcOffset = () => this.format('utcOffset');
212
216
  utcOffsetHours = () => this.format('utcOffsetHours');
213
217
  }
@@ -238,7 +242,7 @@ export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder {
238
242
  return this;
239
243
  }
240
244
  email = () => this.format('email');
241
- date = () => this.format('date');
245
+ isoDate = () => this.format('date').description('IsoDate'); // todo: make it custom isoDate instead
242
246
  url = () => this.format('url');
243
247
  ipv4 = () => this.format('ipv4');
244
248
  ipv6 = () => this.format('ipv6');
@@ -1,6 +1,6 @@
1
- import { jsonSchema } from './jsonSchemaBuilder.js';
2
- export const baseDBEntityJsonSchema = jsonSchema.object({
3
- id: jsonSchema.string(),
4
- created: jsonSchema.unixTimestamp2000(),
5
- updated: jsonSchema.unixTimestamp2000(),
1
+ import { j } from './jsonSchemaBuilder.js';
2
+ export const baseDBEntityJsonSchema = j.object({
3
+ id: j.string(),
4
+ created: j.unixTimestamp2000(),
5
+ updated: j.unixTimestamp2000(),
6
6
  });
@@ -44,8 +44,8 @@ function isoDate() {
44
44
  .string()
45
45
  .refine(v => {
46
46
  return /^\d{4}-\d{2}-\d{2}$/.test(v);
47
- }, 'Must be an IsoDateString')
48
- .describe('IsoDateString');
47
+ }, 'Must be a YYYY-MM-DD string')
48
+ .describe('IsoDate');
49
49
  }
50
50
  function email() {
51
51
  return z.email().describe('Email');
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.24.1",
4
+ "version": "15.25.1",
5
5
  "dependencies": {
6
6
  "tslib": "^2",
7
7
  "zod": "^4"
@@ -12,7 +12,7 @@
12
12
  "@types/semver": "^7",
13
13
  "crypto-js": "^4",
14
14
  "dayjs": "^1",
15
- "@naturalcycles/dev-lib": "18.4.2"
15
+ "@naturalcycles/dev-lib": "19.25.4"
16
16
  },
17
17
  "exports": {
18
18
  ".": "./dist/index.js",
@@ -13,7 +13,7 @@ export type JsonSchema<T = unknown> =
13
13
  | JsonSchemaNumber
14
14
  | JsonSchemaBoolean
15
15
  | JsonSchemaNull
16
- | JsonSchemaObject
16
+ | JsonSchemaObject // cannot use <T>, because T needs to extend AnyObject
17
17
  | JsonSchemaArray<T>
18
18
  | JsonSchemaTuple<T>
19
19
 
@@ -80,7 +80,7 @@ export interface JsonSchemaConst<T = unknown> extends JsonSchemaAny<T> {
80
80
  const: T // literal type
81
81
  }
82
82
 
83
- export interface JsonSchemaString extends JsonSchemaAny<string> {
83
+ export interface JsonSchemaString<T extends string = string> extends JsonSchemaAny<T> {
84
84
  type: 'string'
85
85
  pattern?: string
86
86
  minLength?: number
@@ -96,7 +96,7 @@ export interface JsonSchemaString extends JsonSchemaAny<string> {
96
96
  transform?: ('trim' | 'toLowerCase' | 'toUpperCase')[]
97
97
  }
98
98
 
99
- export interface JsonSchemaNumber extends JsonSchemaAny<number> {
99
+ export interface JsonSchemaNumber<T extends number = number> extends JsonSchemaAny<T> {
100
100
  type: 'number' | 'integer'
101
101
  format?: string
102
102
  multipleOf?: number
@@ -1,7 +1,7 @@
1
1
  import { _uniq } from '../array/array.util.js'
2
2
  import { _deepCopy } from '../object/object.util.js'
3
3
  import { _sortObject } from '../object/sortObject.js'
4
- import type { AnyObject, BaseDBEntity } from '../types.js'
4
+ import type { AnyObject, BaseDBEntity, IsoDate, UnixTimestamp } from '../types.js'
5
5
  import { JSON_SCHEMA_ORDER } from './jsonSchema.cnst.js'
6
6
  import type {
7
7
  JsonSchema,
@@ -29,9 +29,9 @@ export interface JsonSchemaBuilder<T = unknown> {
29
29
 
30
30
  /**
31
31
  * Fluent (chainable) API to manually create Json Schemas.
32
- * Inspired by Joi
32
+ * Inspired by Joi and Zod.
33
33
  */
34
- export const jsonSchema = {
34
+ export const j = {
35
35
  any<T = unknown>() {
36
36
  return new JsonSchemaAnyBuilder<T, JsonSchemaAny<T>>({})
37
37
  },
@@ -65,34 +65,34 @@ export const jsonSchema = {
65
65
  },
66
66
 
67
67
  // number types
68
- number() {
69
- return new JsonSchemaNumberBuilder()
68
+ number<T extends number = number>() {
69
+ return new JsonSchemaNumberBuilder<T>()
70
70
  },
71
- integer() {
72
- return new JsonSchemaNumberBuilder().integer()
71
+ integer<T extends number = number>() {
72
+ return new JsonSchemaNumberBuilder<T>().integer()
73
73
  },
74
74
  unixTimestamp() {
75
- return new JsonSchemaNumberBuilder().unixTimestamp()
75
+ return new JsonSchemaNumberBuilder<UnixTimestamp>().unixTimestamp()
76
76
  },
77
77
  unixTimestamp2000() {
78
- return new JsonSchemaNumberBuilder().unixTimestamp2000()
78
+ return new JsonSchemaNumberBuilder<UnixTimestamp>().unixTimestamp2000()
79
79
  },
80
80
  // string types
81
- string() {
82
- return new JsonSchemaStringBuilder()
81
+ string<T extends string = string>() {
82
+ return new JsonSchemaStringBuilder<T>()
83
83
  },
84
- dateString() {
85
- return new JsonSchemaStringBuilder().date()
84
+ isoDate() {
85
+ return new JsonSchemaStringBuilder<IsoDate>().isoDate()
86
86
  },
87
87
  // email: () => new JsonSchemaStringBuilder().email(),
88
88
  // complex types
89
89
  object<T extends AnyObject>(props: {
90
- [k in keyof T]: JsonSchemaAnyBuilder<T[k]>
90
+ [K in keyof T]: JsonSchemaAnyBuilder<T[K]>
91
91
  }) {
92
92
  return new JsonSchemaObjectBuilder<T>().addProperties(props)
93
93
  },
94
94
  rootObject<T extends AnyObject>(props: {
95
- [k in keyof T]: JsonSchemaAnyBuilder<T[k]>
95
+ [K in keyof T]: JsonSchemaAnyBuilder<T[K]>
96
96
  }) {
97
97
  return new JsonSchemaObjectBuilder<T>().addProperties(props).$schemaDraft7()
98
98
  },
@@ -201,9 +201,17 @@ export class JsonSchemaAnyBuilder<T = unknown, SCHEMA_TYPE extends JsonSchema<T>
201
201
  clone(): JsonSchemaAnyBuilder<T, SCHEMA_TYPE> {
202
202
  return new JsonSchemaAnyBuilder<T, SCHEMA_TYPE>(_deepCopy(this.schema))
203
203
  }
204
+
205
+ /**
206
+ * @experimental
207
+ */
208
+ infer!: T
204
209
  }
205
210
 
206
- export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder<number, JsonSchemaNumber> {
211
+ export class JsonSchemaNumberBuilder<T extends number = number> extends JsonSchemaAnyBuilder<
212
+ T,
213
+ JsonSchemaNumber<T>
214
+ > {
207
215
  constructor() {
208
216
  super({
209
217
  type: 'number',
@@ -257,15 +265,22 @@ export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder<number, JsonSc
257
265
  int64 = (): this => this.format('int64')
258
266
  float = (): this => this.format('float')
259
267
  double = (): this => this.format('double')
260
- unixTimestamp = (): this => this.format('unixTimestamp')
261
- unixTimestamp2000 = (): this => this.format('unixTimestamp2000')
262
- unixTimestampMillis = (): this => this.format('unixTimestampMillis')
263
- unixTimestampMillis2000 = (): this => this.format('unixTimestampMillis2000')
268
+ unixTimestamp = (): this => this.format('unixTimestamp').description('UnixTimestamp')
269
+ unixTimestamp2000 = (): this => this.format('unixTimestamp2000').description('UnixTimestamp2000')
270
+ unixTimestampMillis = (): this =>
271
+ this.format('unixTimestampMillis').description('UnixTimestampMillis')
272
+
273
+ unixTimestampMillis2000 = (): this =>
274
+ this.format('unixTimestampMillis2000').description('UnixTimestampMillis2000')
275
+
264
276
  utcOffset = (): this => this.format('utcOffset')
265
277
  utcOffsetHours = (): this => this.format('utcOffsetHours')
266
278
  }
267
279
 
268
- export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder<string, JsonSchemaString> {
280
+ export class JsonSchemaStringBuilder<T extends string = string> extends JsonSchemaAnyBuilder<
281
+ T,
282
+ JsonSchemaString<T>
283
+ > {
269
284
  constructor() {
270
285
  super({
271
286
  type: 'string',
@@ -298,7 +313,7 @@ export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder<string, JsonSc
298
313
  }
299
314
 
300
315
  email = (): this => this.format('email')
301
- date = (): this => this.format('date')
316
+ isoDate = (): this => this.format('date').description('IsoDate') // todo: make it custom isoDate instead
302
317
  url = (): this => this.format('url')
303
318
  ipv4 = (): this => this.format('ipv4')
304
319
  ipv6 = (): this => this.format('ipv6')
@@ -1,8 +1,8 @@
1
1
  import type { BaseDBEntity } from '../types.js'
2
- import { jsonSchema } from './jsonSchemaBuilder.js'
2
+ import { j } from './jsonSchemaBuilder.js'
3
3
 
4
- export const baseDBEntityJsonSchema = jsonSchema.object<BaseDBEntity>({
5
- id: jsonSchema.string(),
6
- created: jsonSchema.unixTimestamp2000(),
7
- updated: jsonSchema.unixTimestamp2000(),
4
+ export const baseDBEntityJsonSchema = j.object<BaseDBEntity>({
5
+ id: j.string(),
6
+ created: j.unixTimestamp2000(),
7
+ updated: j.unixTimestamp2000(),
8
8
  })
@@ -58,8 +58,8 @@ function isoDate(): ZodBrandedString<IsoDate> {
58
58
  .string()
59
59
  .refine(v => {
60
60
  return /^\d{4}-\d{2}-\d{2}$/.test(v)
61
- }, 'Must be an IsoDateString')
62
- .describe('IsoDateString') as ZodBrandedString<IsoDate>
61
+ }, 'Must be a YYYY-MM-DD string')
62
+ .describe('IsoDate') as ZodBrandedString<IsoDate>
63
63
  }
64
64
 
65
65
  function email(): z.ZodEmail {