@naturalcycles/nodejs-lib 15.73.0 → 15.74.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.
@@ -5,7 +5,7 @@ import { _uniq } from '@naturalcycles/js-lib/array';
5
5
  import { _assert } from '@naturalcycles/js-lib/error';
6
6
  import { _deepCopy, _sortObject } from '@naturalcycles/js-lib/object';
7
7
  import { _objectAssign, JWT_REGEX, } from '@naturalcycles/js-lib/types';
8
- import { BASE64URL_REGEX, COUNTRY_CODE_REGEX, CURRENCY_REGEX, IPV4_REGEX, IPV6_REGEX, LANGUAGE_TAG_REGEX, SEMVER_REGEX, SLUG_REGEX, UUID_REGEX, } from '../regexes.js';
8
+ import { BASE64URL_REGEX, COUNTRY_CODE_REGEX, CURRENCY_REGEX, IPV4_REGEX, IPV6_REGEX, LANGUAGE_TAG_REGEX, SEMVER_REGEX, SLUG_REGEX, URL_REGEX, UUID_REGEX, } from '../regexes.js';
9
9
  import { TIMEZONES } from '../timezones.js';
10
10
  import { isEveryItemNumber, isEveryItemPrimitive, isEveryItemString, JSON_SCHEMA_ORDER, mergeJsonSchemaObjects, } from './jsonSchemaBuilder.util.js';
11
11
  export const j = {
@@ -157,6 +157,7 @@ export class JsonSchemaTerminal {
157
157
  * Same as if it would be JSON.stringified.
158
158
  */
159
159
  build() {
160
+ _assert(!(this.schema.optionalField && this.schema.default !== undefined), '.optional() and .default() should not be used together - the default value makes .optional() redundant and causes incorrect type inference');
160
161
  const jsonSchema = _sortObject(JSON.parse(JSON.stringify(this.schema)), JSON_SCHEMA_ORDER);
161
162
  delete jsonSchema.optionalField;
162
163
  return jsonSchema;
@@ -278,6 +279,7 @@ export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder {
278
279
  return newBuilder;
279
280
  }
280
281
  regex(pattern, opt) {
282
+ _assert(!pattern.flags, `Regex flags are not supported by JSON Schema. Received: /${pattern.source}/${pattern.flags}`);
281
283
  return this.pattern(pattern.source, opt);
282
284
  }
283
285
  pattern(pattern, opt) {
@@ -348,9 +350,7 @@ export class JsonSchemaStringBuilder extends JsonSchemaAnyBuilder {
348
350
  return this.regex(JWT_REGEX, { msg: 'is not a valid JWT format' });
349
351
  }
350
352
  url() {
351
- // from `ajv-formats`
352
- const regex = /^(?:https?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u{00A1}-\u{FFFF}]+-)*[a-z0-9\u{00A1}-\u{FFFF}]+)(?:\.(?:[a-z0-9\u{00A1}-\u{FFFF}]+-)*[a-z0-9\u{00A1}-\u{FFFF}]+)*(?:\.(?:[a-z\u{00A1}-\u{FFFF}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu;
353
- return this.regex(regex, { msg: 'is not a valid URL format' });
353
+ return this.regex(URL_REGEX, { msg: 'is not a valid URL format' });
354
354
  }
355
355
  ipv4() {
356
356
  return this.regex(IPV4_REGEX, { msg: 'is not a valid IPv4 format' });
@@ -807,6 +807,9 @@ function record(keySchema, valueSchema) {
807
807
  });
808
808
  }
809
809
  function withRegexKeys(keyRegex, schema) {
810
+ if (keyRegex instanceof RegExp) {
811
+ _assert(!keyRegex.flags, `Regex flags are not supported by JSON Schema. Received: /${keyRegex.source}/${keyRegex.flags}`);
812
+ }
810
813
  const pattern = keyRegex instanceof RegExp ? keyRegex.source : keyRegex;
811
814
  const jsonSchema = schema.build();
812
815
  return new JsonSchemaObjectBuilder([], {
@@ -18,3 +18,4 @@ export declare const LANGUAGE_TAG_REGEX: RegExp;
18
18
  export declare const MAC_ADDRESS_REGEX: RegExp;
19
19
  export declare const SEMVER_REGEX: RegExp;
20
20
  export declare const SLUG_REGEX: RegExp;
21
+ export declare const URL_REGEX: RegExp;
@@ -23,3 +23,7 @@ export const LANGUAGE_TAG_REGEX = /^[a-z]{2}(-[A-Z]{2})?$/;
23
23
  export const MAC_ADDRESS_REGEX = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
24
24
  export const SEMVER_REGEX = /^[0-9]+\.[0-9]+\.[0-9]+$/;
25
25
  export const SLUG_REGEX = /^[a-z0-9-]+$/;
26
+ // URL regex based on `ajv-formats`, but without flags for JSON Schema compatibility.
27
+ // Uses [a-zA-Z] instead of [a-z] with i flag. Simplified to not require unicode flag.
28
+ // Without the unicode flag - it DOES NOT support urls like https://münchen.de
29
+ export const URL_REGEX = /^(?:https?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-zA-Z0-9]+-)*[a-zA-Z0-9]+)(?:\.(?:[a-zA-Z0-9]+-)*[a-zA-Z0-9]+)*(?:\.(?:[a-zA-Z]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
3
  "type": "module",
4
- "version": "15.73.0",
4
+ "version": "15.74.1",
5
5
  "dependencies": {
6
6
  "@naturalcycles/js-lib": "^15",
7
7
  "@types/js-yaml": "^4",
@@ -36,6 +36,7 @@ import {
36
36
  LANGUAGE_TAG_REGEX,
37
37
  SEMVER_REGEX,
38
38
  SLUG_REGEX,
39
+ URL_REGEX,
39
40
  UUID_REGEX,
40
41
  } from '../regexes.js'
41
42
  import { TIMEZONES } from '../timezones.js'
@@ -246,6 +247,11 @@ export class JsonSchemaTerminal<IN, OUT, Opt> {
246
247
  * Same as if it would be JSON.stringified.
247
248
  */
248
249
  build(): JsonSchema<IN, OUT> {
250
+ _assert(
251
+ !(this.schema.optionalField && this.schema.default !== undefined),
252
+ '.optional() and .default() should not be used together - the default value makes .optional() redundant and causes incorrect type inference',
253
+ )
254
+
249
255
  const jsonSchema = _sortObject(
250
256
  JSON.parse(JSON.stringify(this.schema)),
251
257
  JSON_SCHEMA_ORDER,
@@ -405,6 +411,10 @@ export class JsonSchemaStringBuilder<
405
411
  }
406
412
 
407
413
  regex(pattern: RegExp, opt?: JsonBuilderRuleOpt): this {
414
+ _assert(
415
+ !pattern.flags,
416
+ `Regex flags are not supported by JSON Schema. Received: /${pattern.source}/${pattern.flags}`,
417
+ )
408
418
  return this.pattern(pattern.source, opt)
409
419
  }
410
420
 
@@ -490,10 +500,7 @@ export class JsonSchemaStringBuilder<
490
500
  }
491
501
 
492
502
  url(): this {
493
- // from `ajv-formats`
494
- const regex =
495
- /^(?:https?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u{00A1}-\u{FFFF}]+-)*[a-z0-9\u{00A1}-\u{FFFF}]+)(?:\.(?:[a-z0-9\u{00A1}-\u{FFFF}]+-)*[a-z0-9\u{00A1}-\u{FFFF}]+)*(?:\.(?:[a-z\u{00A1}-\u{FFFF}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu
496
- return this.regex(regex, { msg: 'is not a valid URL format' })
503
+ return this.regex(URL_REGEX, { msg: 'is not a valid URL format' })
497
504
  }
498
505
 
499
506
  ipv4(): this {
@@ -1353,6 +1360,12 @@ function withRegexKeys<
1353
1360
  Opt extends true ? StringMap<SchemaOut<S>> : StringMap<SchemaOut<S>>,
1354
1361
  false
1355
1362
  > {
1363
+ if (keyRegex instanceof RegExp) {
1364
+ _assert(
1365
+ !keyRegex.flags,
1366
+ `Regex flags are not supported by JSON Schema. Received: /${keyRegex.source}/${keyRegex.flags}`,
1367
+ )
1368
+ }
1356
1369
  const pattern = keyRegex instanceof RegExp ? keyRegex.source : keyRegex
1357
1370
  const jsonSchema = schema.build()
1358
1371
 
@@ -24,3 +24,8 @@ export const LANGUAGE_TAG_REGEX = /^[a-z]{2}(-[A-Z]{2})?$/
24
24
  export const MAC_ADDRESS_REGEX = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/
25
25
  export const SEMVER_REGEX = /^[0-9]+\.[0-9]+\.[0-9]+$/
26
26
  export const SLUG_REGEX = /^[a-z0-9-]+$/
27
+ // URL regex based on `ajv-formats`, but without flags for JSON Schema compatibility.
28
+ // Uses [a-zA-Z] instead of [a-z] with i flag. Simplified to not require unicode flag.
29
+ // Without the unicode flag - it DOES NOT support urls like https://münchen.de
30
+ export const URL_REGEX =
31
+ /^(?:https?|ftp):\/\/(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-zA-Z0-9]+-)*[a-zA-Z0-9]+)(?:\.(?:[a-zA-Z0-9]+-)*[a-zA-Z0-9]+)*(?:\.(?:[a-zA-Z]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/