@naturalcycles/js-lib 15.37.0 → 15.39.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,4 +1,5 @@
1
- import type { NumberEnum, StringEnum } from './types.js';
1
+ import type { AnyObject, NumberEnum, StringEnum } from './types.js';
2
+ export declare function getEnumType(en: AnyObject): 'StringEnum' | 'NumberEnum' | undefined;
2
3
  /**
3
4
  * Returns all String keys of a number-enum.
4
5
  */
package/dist/enum.util.js CHANGED
@@ -1,3 +1,32 @@
1
+ export function getEnumType(en) {
2
+ /*
3
+ * enum Foo { A = 1, B = 2 }
4
+ * becomes
5
+ * { "1": "A", "2": "B", "A": 1, "B": 2}
6
+ *
7
+ * enum Foo { A = "V1", B = "V2" }
8
+ * becomes
9
+ * { "V1": "A", "V2": "B", "A": "V1", "B": "V2"}
10
+ */
11
+ const entries = Object.entries(en);
12
+ if (!entries.length)
13
+ return;
14
+ const [, value] = entries.pop();
15
+ let isNumberEnum = typeof value === 'number';
16
+ let isStringEnum = typeof value === 'string';
17
+ for (const [key, value] of entries) {
18
+ const isValueNumber = typeof value === 'number';
19
+ const isValueString = typeof value === 'string';
20
+ isStringEnum &&= isValueString;
21
+ isNumberEnum &&= isValueNumber || String(en[value]) === key;
22
+ if (!isStringEnum && !isNumberEnum)
23
+ break;
24
+ }
25
+ if (isNumberEnum)
26
+ return 'NumberEnum';
27
+ if (isStringEnum)
28
+ return 'StringEnum';
29
+ }
1
30
  /**
2
31
  * Returns all String keys of a number-enum.
3
32
  */
@@ -1,4 +1,4 @@
1
- import { type AnyObject, type BaseDBEntity, type IsoDate, type IsoDateTime, type UnixTimestamp } from '../types.js';
1
+ import { type AnyObject, type BaseDBEntity, type IsoDate, type IsoDateTime, type NumberEnum, type StringEnum, type UnixTimestamp, type UnixTimestampMillis } 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>;
@@ -12,24 +12,12 @@ export declare const j: {
12
12
  const<T extends string | number | boolean | null>(value: T): JsonSchemaAnyBuilder<T, JsonSchemaConst<T>, false>;
13
13
  null(): JsonSchemaAnyBuilder<null, JsonSchemaNull, false>;
14
14
  ref<T = unknown>($ref: string): JsonSchemaAnyBuilder<T, JsonSchemaRef<T>, false>;
15
- enum<T = unknown>(enumValues: T[]): JsonSchemaAnyBuilder<T, JsonSchemaEnum<T>, false>;
15
+ enum<const T extends readonly (string | number | boolean | null)[] | StringEnum | NumberEnum>(input: T): JsonSchemaAnyBuilder<T extends readonly (infer U)[] ? U : T extends StringEnum ? T[keyof T] : T extends NumberEnum ? T[keyof T] : never, JsonSchemaEnum<any>, false>;
16
16
  boolean(): JsonSchemaAnyBuilder<boolean, JsonSchemaBoolean, false>;
17
17
  buffer(): JsonSchemaAnyBuilder<Buffer<ArrayBufferLike>, JsonSchemaAny<Buffer<ArrayBufferLike>>, false>;
18
18
  number<T extends number = number>(): JsonSchemaNumberBuilder<T, false>;
19
19
  integer<T extends number = number>(): JsonSchemaNumberBuilder<T, false>;
20
- unixTimestamp(): JsonSchemaNumberBuilder<UnixTimestamp, false>;
21
- unixTimestamp2000(): JsonSchemaNumberBuilder<UnixTimestamp, false>;
22
20
  string<T extends string = string>(): JsonSchemaStringBuilder<T, false>;
23
- jwt(): JsonSchemaStringBuilder<string, false>;
24
- /**
25
- * Accepts only the `YYYY-MM-DD` shape from all ISO 8601 variants.
26
- */
27
- isoDate(): JsonSchemaStringBuilder<IsoDate, false>;
28
- /**
29
- * Accepts strings that start with the `YYYY-MM-DDTHH:MM:SS` shape
30
- * and optionally end with either a `Z` or a `+/-hh:mm` timezone part.
31
- */
32
- isoDateTime(): JsonSchemaStringBuilder<IsoDateTime, false>;
33
21
  object: typeof object;
34
22
  dbEntity<T extends AnyObject>(props: T): JsonSchemaObjectBuilder<BaseDBEntity & ({ [K in keyof T as T[K] extends JsonSchemaAnyBuilder<any, any, infer Opt extends boolean> ? Opt extends true ? never : K : never]: T[K] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never; } & { [K_1 in keyof T as T[K_1] extends JsonSchemaAnyBuilder<any, any, infer Opt extends boolean> ? Opt extends true ? K_1 : never : never]?: (T[K_1] extends JsonSchemaAnyBuilder<infer U, any, any> ? U : never) | undefined; } extends infer O ? { [K_2 in keyof O]: O[K_2]; } : never) extends infer O_1 ? { [K_3 in keyof O_1]: O_1[K_3]; } : never, false>;
35
23
  rootObject<T extends AnyObject>(props: { [K in keyof T]: JsonSchemaAnyBuilder<T[K]>; }): JsonSchemaObjectBuilder<T, false>;
@@ -86,10 +74,10 @@ export declare class JsonSchemaNumberBuilder<T extends number = number, Opt exte
86
74
  int64: () => this;
87
75
  float: () => this;
88
76
  double: () => this;
89
- unixTimestamp: () => this;
90
- unixTimestamp2000: () => this;
91
- unixTimestampMillis: () => this;
92
- unixTimestampMillis2000: () => this;
77
+ unixTimestamp: () => JsonSchemaNumberBuilder<UnixTimestamp>;
78
+ unixTimestamp2000: () => JsonSchemaNumberBuilder<UnixTimestamp>;
79
+ unixTimestampMillis: () => JsonSchemaNumberBuilder<UnixTimestampMillis>;
80
+ unixTimestampMillis2000: () => JsonSchemaNumberBuilder<UnixTimestampMillis>;
93
81
  utcOffset: () => this;
94
82
  utcOffsetHours: () => this;
95
83
  branded<B extends number>(): JsonSchemaNumberBuilder<B>;
@@ -1,4 +1,6 @@
1
1
  import { _uniq } from '../array/array.util.js';
2
+ import { _numberEnumValues, _stringEnumValues, getEnumType } from '../enum.util.js';
3
+ import { _assert } from '../error/assert.js';
2
4
  import { _deepCopy } from '../object/object.util.js';
3
5
  import { _sortObject } from '../object/sortObject.js';
4
6
  import { JWT_REGEX, } from '../types.js';
@@ -27,8 +29,24 @@ export const j = {
27
29
  $ref,
28
30
  });
29
31
  },
30
- enum(enumValues) {
31
- return new JsonSchemaAnyBuilder({ enum: enumValues });
32
+ enum(input) {
33
+ let enumValues;
34
+ if (Array.isArray(input)) {
35
+ enumValues = input;
36
+ }
37
+ else if (typeof input === 'object') {
38
+ const enumType = getEnumType(input);
39
+ if (enumType === 'NumberEnum') {
40
+ enumValues = _numberEnumValues(input);
41
+ }
42
+ else if (enumType === 'StringEnum') {
43
+ enumValues = _stringEnumValues(input);
44
+ }
45
+ }
46
+ _assert(enumValues, 'Unsupported enum input');
47
+ return new JsonSchemaAnyBuilder({
48
+ enum: enumValues,
49
+ });
32
50
  },
33
51
  boolean() {
34
52
  return new JsonSchemaAnyBuilder({
@@ -47,41 +65,18 @@ export const j = {
47
65
  integer() {
48
66
  return new JsonSchemaNumberBuilder().integer();
49
67
  },
50
- unixTimestamp() {
51
- return new JsonSchemaNumberBuilder().unixTimestamp();
52
- },
53
- unixTimestamp2000() {
54
- return new JsonSchemaNumberBuilder().unixTimestamp2000();
55
- },
56
68
  // string types
57
69
  string() {
58
70
  return new JsonSchemaStringBuilder();
59
71
  },
60
- jwt() {
61
- return new JsonSchemaStringBuilder().jwt();
62
- },
63
- /**
64
- * Accepts only the `YYYY-MM-DD` shape from all ISO 8601 variants.
65
- */
66
- isoDate() {
67
- return new JsonSchemaStringBuilder().isoDate();
68
- },
69
- /**
70
- * Accepts strings that start with the `YYYY-MM-DDTHH:MM:SS` shape
71
- * and optionally end with either a `Z` or a `+/-hh:mm` timezone part.
72
- */
73
- isoDateTime() {
74
- return new JsonSchemaStringBuilder().isoDateTime();
75
- },
76
- // email: () => new JsonSchemaStringBuilder().email(),
77
72
  // complex types
78
73
  object,
79
74
  dbEntity(props) {
80
75
  return j
81
76
  .object({
82
77
  id: j.string(),
83
- created: j.unixTimestamp2000(),
84
- updated: j.unixTimestamp2000(),
78
+ created: j.integer().unixTimestamp2000(),
79
+ updated: j.integer().unixTimestamp2000(),
85
80
  })
86
81
  .extend(j.object(props));
87
82
  },
@@ -226,10 +221,19 @@ export class JsonSchemaNumberBuilder extends JsonSchemaAnyBuilder {
226
221
  int64 = () => this.format('int64');
227
222
  float = () => this.format('float');
228
223
  double = () => this.format('double');
229
- unixTimestamp = () => this.format('unixTimestamp').description('UnixTimestamp');
230
- unixTimestamp2000 = () => this.format('unixTimestamp2000').description('UnixTimestamp2000');
231
- unixTimestampMillis = () => this.format('unixTimestampMillis').description('UnixTimestampMillis');
232
- unixTimestampMillis2000 = () => this.format('unixTimestampMillis2000').description('UnixTimestampMillis2000');
224
+ unixTimestamp = () => this.integer().branded().format('unixTimestamp').description('UnixTimestamp');
225
+ unixTimestamp2000 = () => this.integer()
226
+ .branded()
227
+ .format('unixTimestamp2000')
228
+ .description('UnixTimestamp2000');
229
+ unixTimestampMillis = () => this.integer()
230
+ .branded()
231
+ .format('unixTimestampMillis')
232
+ .description('UnixTimestampMillis');
233
+ unixTimestampMillis2000 = () => this.integer()
234
+ .branded()
235
+ .format('unixTimestampMillis2000')
236
+ .description('UnixTimestampMillis2000');
233
237
  utcOffset = () => this.format('utcOffset');
234
238
  utcOffsetHours = () => this.format('utcOffsetHours');
235
239
  branded() {
@@ -1,6 +1,6 @@
1
1
  import { j } from './jsonSchemaBuilder.js';
2
2
  export const baseDBEntityJsonSchema = j.object({
3
3
  id: j.string(),
4
- created: j.unixTimestamp2000(),
5
- updated: j.unixTimestamp2000(),
4
+ created: j.integer().unixTimestamp2000(),
5
+ updated: j.integer().unixTimestamp2000(),
6
6
  });
package/dist/nanoid.js CHANGED
@@ -2,9 +2,9 @@
2
2
  // All credit to nanoid authors: https://github.com/ai/nanoid
3
3
  // Reason for vendoring: (still) cannot import esm, and Nanoid went ESM-only since 4.0
4
4
  /// <reference lib="dom" preserve="true" />
5
- /* eslint-disable no-bitwise */
6
5
  // "0-9a-zA-Z-_", same as base64url alphabet
7
6
  const urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';
7
+ // oxlint-disable no-bitwise -- NanoID uses bit operations to build compact IDs
8
8
  export function nanoidBrowser(length = 21) {
9
9
  let id = '';
10
10
  const bytes = globalThis.crypto.getRandomValues(new Uint8Array(length));
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-bitwise */
2
1
  /**
3
2
  * Returns a "deterministic Math.random() function"
4
3
  *
@@ -6,6 +5,7 @@
6
5
  */
7
6
  export function _createDeterministicRandom(seed = 0x2f6e2b1) {
8
7
  return () => {
8
+ // oxlint-disable no-bitwise
9
9
  // Robert Jenkins’ 32 bit integer hash function
10
10
  seed = (seed + 0x7ed55d16 + (seed << 12)) & 0xffffffff;
11
11
  seed = (seed ^ 0xc761c23c ^ (seed >>> 19)) & 0xffffffff;
@@ -1,3 +1,4 @@
1
+ // oxlint-disable no-bitwise -- hash implementations use bit-level operations for speed
1
2
  const BASE62 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
2
3
  // const BASE64 = BASE62 + '+/'
3
4
  const BASE64URL = BASE62 + '-_';
@@ -48,7 +49,7 @@ export function hashCode(s) {
48
49
  let i = 0;
49
50
  const len = s.length;
50
51
  while (i < len) {
51
- // eslint-disable-next-line no-bitwise, unicorn/prefer-math-trunc, unicorn/prefer-code-point
52
+ // eslint-disable-next-line unicorn/prefer-math-trunc, unicorn/prefer-code-point
52
53
  hash = ((hash << 5) - hash + s.charCodeAt(i++)) << 0;
53
54
  }
54
55
  return hash + 2147483647 + 1;
@@ -1,6 +1,7 @@
1
1
  const array = [];
2
2
  const characterCodeCache = [];
3
- /* eslint-disable unicorn/prefer-code-point, no-bitwise */
3
+ /* eslint-disable unicorn/prefer-code-point */
4
+ // oxlint-disable no-bitwise
4
5
  /**
5
6
  * Modified version of: https://github.com/sindresorhus/leven/
6
7
  *
@@ -13,7 +13,6 @@ export function _safeJsonStringify(obj, replacer, spaces, cycleReplacer) {
13
13
  return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
14
14
  }
15
15
  }
16
- /* eslint-disable no-bitwise, no-implicit-coercion */
17
16
  // oxlint-disable no-unused-expressions
18
17
  function serializer(replacer, cycleReplacer) {
19
18
  const stack = [];
@@ -26,9 +25,15 @@ function serializer(replacer, cycleReplacer) {
26
25
  return function (key, value) {
27
26
  if (stack.length > 0) {
28
27
  const thisPos = stack.indexOf(this);
29
- ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
30
- ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
31
- if (~stack.indexOf(value)) {
28
+ if (thisPos !== -1) {
29
+ stack.splice(thisPos + 1);
30
+ keys.splice(thisPos, Infinity, key);
31
+ }
32
+ else {
33
+ stack.push(this);
34
+ keys.push(key);
35
+ }
36
+ if (stack.includes(value)) {
32
37
  value = cycleReplacer.call(this, key, value);
33
38
  }
34
39
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/js-lib",
3
3
  "type": "module",
4
- "version": "15.37.0",
4
+ "version": "15.39.0",
5
5
  "dependencies": {
6
6
  "tslib": "^2",
7
7
  "undici": "^7",
package/src/enum.util.ts CHANGED
@@ -1,4 +1,36 @@
1
- import type { NumberEnum, StringEnum } from './types.js'
1
+ import type { AnyObject, NumberEnum, StringEnum } from './types.js'
2
+
3
+ export function getEnumType(en: AnyObject): 'StringEnum' | 'NumberEnum' | undefined {
4
+ /*
5
+ * enum Foo { A = 1, B = 2 }
6
+ * becomes
7
+ * { "1": "A", "2": "B", "A": 1, "B": 2}
8
+ *
9
+ * enum Foo { A = "V1", B = "V2" }
10
+ * becomes
11
+ * { "V1": "A", "V2": "B", "A": "V1", "B": "V2"}
12
+ */
13
+
14
+ const entries = Object.entries(en)
15
+ if (!entries.length) return
16
+
17
+ const [, value] = entries.pop()!
18
+
19
+ let isNumberEnum = typeof value === 'number'
20
+ let isStringEnum = typeof value === 'string'
21
+
22
+ for (const [key, value] of entries) {
23
+ const isValueNumber = typeof value === 'number'
24
+ const isValueString = typeof value === 'string'
25
+
26
+ isStringEnum &&= isValueString
27
+ isNumberEnum &&= isValueNumber || String(en[value]) === key
28
+ if (!isStringEnum && !isNumberEnum) break
29
+ }
30
+
31
+ if (isNumberEnum) return 'NumberEnum'
32
+ if (isStringEnum) return 'StringEnum'
33
+ }
2
34
 
3
35
  /**
4
36
  * Returns all String keys of a number-enum.
@@ -1,4 +1,6 @@
1
1
  import { _uniq } from '../array/array.util.js'
2
+ import { _numberEnumValues, _stringEnumValues, getEnumType } from '../enum.util.js'
3
+ import { _assert } from '../error/assert.js'
2
4
  import { _deepCopy } from '../object/object.util.js'
3
5
  import { _sortObject } from '../object/sortObject.js'
4
6
  import {
@@ -7,8 +9,10 @@ import {
7
9
  type IsoDate,
8
10
  type IsoDateTime,
9
11
  JWT_REGEX,
10
- type JWTString,
12
+ type NumberEnum,
13
+ type StringEnum,
11
14
  type UnixTimestamp,
15
+ type UnixTimestampMillis,
12
16
  } from '../types.js'
13
17
  import { JSON_SCHEMA_ORDER } from './jsonSchema.cnst.js'
14
18
  import type {
@@ -58,9 +62,39 @@ export const j = {
58
62
  $ref,
59
63
  })
60
64
  },
61
- enum<T = unknown>(enumValues: T[]) {
62
- return new JsonSchemaAnyBuilder<T, JsonSchemaEnum<T>>({ enum: enumValues })
65
+
66
+ enum<const T extends readonly (string | number | boolean | null)[] | StringEnum | NumberEnum>(
67
+ input: T,
68
+ ) {
69
+ let enumValues: readonly (string | number | boolean | null)[] | undefined
70
+
71
+ if (Array.isArray(input)) {
72
+ enumValues = input
73
+ } else if (typeof input === 'object') {
74
+ const enumType = getEnumType(input)
75
+ if (enumType === 'NumberEnum') {
76
+ enumValues = _numberEnumValues(input as NumberEnum)
77
+ } else if (enumType === 'StringEnum') {
78
+ enumValues = _stringEnumValues(input as StringEnum)
79
+ }
80
+ }
81
+
82
+ _assert(enumValues, 'Unsupported enum input')
83
+
84
+ return new JsonSchemaAnyBuilder<
85
+ T extends readonly (infer U)[]
86
+ ? U
87
+ : T extends StringEnum
88
+ ? T[keyof T]
89
+ : T extends NumberEnum
90
+ ? T[keyof T]
91
+ : never,
92
+ JsonSchemaEnum<any>
93
+ >({
94
+ enum: enumValues as any[],
95
+ })
63
96
  },
97
+
64
98
  boolean() {
65
99
  return new JsonSchemaAnyBuilder<boolean, JsonSchemaBoolean>({
66
100
  type: 'boolean',
@@ -79,45 +113,20 @@ export const j = {
79
113
  integer<T extends number = number>() {
80
114
  return new JsonSchemaNumberBuilder<T>().integer()
81
115
  },
82
- unixTimestamp() {
83
- return new JsonSchemaNumberBuilder<UnixTimestamp>().unixTimestamp()
84
- },
85
- unixTimestamp2000() {
86
- return new JsonSchemaNumberBuilder<UnixTimestamp>().unixTimestamp2000()
87
- },
88
116
 
89
117
  // string types
90
118
  string<T extends string = string>() {
91
119
  return new JsonSchemaStringBuilder<T>()
92
120
  },
93
- jwt() {
94
- return new JsonSchemaStringBuilder<JWTString>().jwt()
95
- },
96
-
97
- /**
98
- * Accepts only the `YYYY-MM-DD` shape from all ISO 8601 variants.
99
- */
100
- isoDate() {
101
- return new JsonSchemaStringBuilder<IsoDate>().isoDate()
102
- },
103
-
104
- /**
105
- * Accepts strings that start with the `YYYY-MM-DDTHH:MM:SS` shape
106
- * and optionally end with either a `Z` or a `+/-hh:mm` timezone part.
107
- */
108
- isoDateTime() {
109
- return new JsonSchemaStringBuilder<IsoDateTime>().isoDateTime()
110
- },
111
121
 
112
- // email: () => new JsonSchemaStringBuilder().email(),
113
122
  // complex types
114
123
  object,
115
124
  dbEntity<T extends AnyObject>(props: T) {
116
125
  return j
117
126
  .object<BaseDBEntity>({
118
127
  id: j.string(),
119
- created: j.unixTimestamp2000(),
120
- updated: j.unixTimestamp2000(),
128
+ created: j.integer().unixTimestamp2000(),
129
+ updated: j.integer().unixTimestamp2000(),
121
130
  })
122
131
  .extend(j.object(props))
123
132
  },
@@ -305,13 +314,27 @@ export class JsonSchemaNumberBuilder<
305
314
  int64 = (): this => this.format('int64')
306
315
  float = (): this => this.format('float')
307
316
  double = (): this => this.format('double')
308
- unixTimestamp = (): this => this.format('unixTimestamp').description('UnixTimestamp')
309
- unixTimestamp2000 = (): this => this.format('unixTimestamp2000').description('UnixTimestamp2000')
310
- unixTimestampMillis = (): this =>
311
- this.format('unixTimestampMillis').description('UnixTimestampMillis')
312
317
 
313
- unixTimestampMillis2000 = (): this =>
314
- this.format('unixTimestampMillis2000').description('UnixTimestampMillis2000')
318
+ unixTimestamp = (): JsonSchemaNumberBuilder<UnixTimestamp> =>
319
+ this.integer().branded<UnixTimestamp>().format('unixTimestamp').description('UnixTimestamp')
320
+
321
+ unixTimestamp2000 = (): JsonSchemaNumberBuilder<UnixTimestamp> =>
322
+ this.integer()
323
+ .branded<UnixTimestamp>()
324
+ .format('unixTimestamp2000')
325
+ .description('UnixTimestamp2000')
326
+
327
+ unixTimestampMillis = (): JsonSchemaNumberBuilder<UnixTimestampMillis> =>
328
+ this.integer()
329
+ .branded<UnixTimestampMillis>()
330
+ .format('unixTimestampMillis')
331
+ .description('UnixTimestampMillis')
332
+
333
+ unixTimestampMillis2000 = (): JsonSchemaNumberBuilder<UnixTimestampMillis> =>
334
+ this.integer()
335
+ .branded<UnixTimestampMillis>()
336
+ .format('unixTimestampMillis2000')
337
+ .description('UnixTimestampMillis2000')
315
338
 
316
339
  utcOffset = (): this => this.format('utcOffset')
317
340
  utcOffsetHours = (): this => this.format('utcOffsetHours')
@@ -3,6 +3,6 @@ import { j } from './jsonSchemaBuilder.js'
3
3
 
4
4
  export const baseDBEntityJsonSchema = j.object<BaseDBEntity>({
5
5
  id: j.string(),
6
- created: j.unixTimestamp2000(),
7
- updated: j.unixTimestamp2000(),
6
+ created: j.integer().unixTimestamp2000(),
7
+ updated: j.integer().unixTimestamp2000(),
8
8
  })
package/src/nanoid.ts CHANGED
@@ -4,8 +4,6 @@
4
4
 
5
5
  /// <reference lib="dom" preserve="true" />
6
6
 
7
- /* eslint-disable no-bitwise */
8
-
9
7
  // "0-9a-zA-Z-_", same as base64url alphabet
10
8
  const urlAlphabet = 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'
11
9
 
@@ -16,6 +14,7 @@ export type NanoidFunction = (length?: number) => string
16
14
 
17
15
  type NanoidRandomFunction = (bytes: number) => Uint8Array
18
16
 
17
+ // oxlint-disable no-bitwise -- NanoID uses bit operations to build compact IDs
19
18
  export function nanoidBrowser(length = 21): string {
20
19
  let id = ''
21
20
  const bytes = globalThis.crypto.getRandomValues(new Uint8Array(length))
@@ -1,5 +1,3 @@
1
- /* eslint-disable no-bitwise */
2
-
3
1
  /**
4
2
  * Function that returns a random number between 0 and 1.
5
3
  * Exactly same signature as Math.random function.
@@ -13,6 +11,7 @@ export type RandomFunction = () => number
13
11
  */
14
12
  export function _createDeterministicRandom(seed = 0x2f6e2b1): RandomFunction {
15
13
  return () => {
14
+ // oxlint-disable no-bitwise
16
15
  // Robert Jenkins’ 32 bit integer hash function
17
16
  seed = (seed + 0x7ed55d16 + (seed << 12)) & 0xffffffff
18
17
  seed = (seed ^ 0xc761c23c ^ (seed >>> 19)) & 0xffffffff
@@ -1,5 +1,7 @@
1
1
  import type { Integer } from '../types.js'
2
2
 
3
+ // oxlint-disable no-bitwise -- hash implementations use bit-level operations for speed
4
+
3
5
  const BASE62 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
4
6
  // const BASE64 = BASE62 + '+/'
5
7
  const BASE64URL = BASE62 + '-_'
@@ -54,7 +56,7 @@ export function hashCode(s: string): Integer {
54
56
  let i = 0
55
57
  const len = s.length
56
58
  while (i < len) {
57
- // eslint-disable-next-line no-bitwise, unicorn/prefer-math-trunc, unicorn/prefer-code-point
59
+ // eslint-disable-next-line unicorn/prefer-math-trunc, unicorn/prefer-code-point
58
60
  hash = ((hash << 5) - hash + s.charCodeAt(i++)) << 0
59
61
  }
60
62
  return hash + 2147483647 + 1
@@ -1,7 +1,8 @@
1
1
  const array: number[] = []
2
2
  const characterCodeCache: number[] = []
3
3
 
4
- /* eslint-disable unicorn/prefer-code-point, no-bitwise */
4
+ /* eslint-disable unicorn/prefer-code-point */
5
+ // oxlint-disable no-bitwise
5
6
 
6
7
  /**
7
8
  * Modified version of: https://github.com/sindresorhus/leven/
@@ -20,7 +20,6 @@ export function _safeJsonStringify(
20
20
  }
21
21
  }
22
22
 
23
- /* eslint-disable no-bitwise, no-implicit-coercion */
24
23
  // oxlint-disable no-unused-expressions
25
24
  function serializer(replacer?: Reviver, cycleReplacer?: Reviver): Reviver {
26
25
  const stack: any[] = []
@@ -34,9 +33,15 @@ function serializer(replacer?: Reviver, cycleReplacer?: Reviver): Reviver {
34
33
  return function (key, value) {
35
34
  if (stack.length > 0) {
36
35
  const thisPos = stack.indexOf(this)
37
- ~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
38
- ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)
39
- if (~stack.indexOf(value)) {
36
+ if (thisPos !== -1) {
37
+ stack.splice(thisPos + 1)
38
+ keys.splice(thisPos, Infinity, key)
39
+ } else {
40
+ stack.push(this)
41
+ keys.push(key)
42
+ }
43
+
44
+ if (stack.includes(value)) {
40
45
  value = cycleReplacer.call(this, key, value)
41
46
  }
42
47
  } else {