@augment-vir/common 29.2.0 → 30.0.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.
Files changed (273) hide show
  1. package/LICENSE-CC0 +121 -0
  2. package/LICENSE-MIT +21 -0
  3. package/dist/augments/array/array-map.d.ts +6 -0
  4. package/dist/augments/array/array-map.js +4 -0
  5. package/dist/augments/array/array-to-object.d.ts +17 -0
  6. package/dist/augments/array/array-to-object.js +31 -0
  7. package/dist/augments/array/awaited/awaited-filter.d.ts +7 -0
  8. package/dist/augments/array/awaited/awaited-filter.js +7 -0
  9. package/dist/augments/array/awaited/awaited-for-each.d.ts +6 -0
  10. package/dist/augments/array/awaited/awaited-for-each.js +9 -0
  11. package/dist/augments/array/awaited/awaited-map.d.ts +1 -0
  12. package/dist/augments/array/awaited/awaited-map.js +8 -0
  13. package/dist/augments/array/filter.d.ts +3 -0
  14. package/dist/augments/array/filter.js +13 -0
  15. package/dist/augments/array/repeat-array.d.ts +1 -0
  16. package/dist/augments/array/repeat-array.js +3 -0
  17. package/dist/augments/array/shuffle-array.d.ts +2 -0
  18. package/dist/augments/array/shuffle-array.js +10 -0
  19. package/dist/augments/array/string-array.d.ts +1 -0
  20. package/dist/augments/array/string-array.js +3 -0
  21. package/dist/augments/boolean/if-truthy.d.ts +2 -0
  22. package/dist/{esm/augments/boolean.js → augments/boolean/if-truthy.js} +2 -7
  23. package/dist/augments/core-exports.d.ts +1 -0
  24. package/dist/augments/core-exports.js +1 -0
  25. package/dist/augments/enum/enum-value-check.d.ts +2 -0
  26. package/dist/augments/enum/enum-value-check.js +4 -0
  27. package/dist/augments/error/combine-errors.d.ts +3 -0
  28. package/dist/augments/error/combine-errors.js +12 -0
  29. package/dist/augments/function/call-asynchronously.d.ts +6 -0
  30. package/dist/augments/function/call-asynchronously.js +7 -0
  31. package/dist/augments/function/call-with-retries.d.ts +4 -0
  32. package/dist/augments/function/call-with-retries.js +27 -0
  33. package/dist/augments/function/debounce.d.ts +22 -0
  34. package/dist/augments/function/debounce.js +50 -0
  35. package/dist/augments/function/execution-duration.d.ts +8 -0
  36. package/dist/{esm/augments/time.js → augments/function/execution-duration.js} +7 -12
  37. package/dist/{types/augments → augments/function}/wrap-in-try.d.ts +2 -3
  38. package/dist/{esm/augments → augments/function}/wrap-in-try.js +4 -4
  39. package/dist/augments/json/append-json.d.ts +5 -0
  40. package/dist/augments/json/append-json.js +26 -0
  41. package/dist/augments/json/copy-through-json.d.ts +3 -0
  42. package/dist/augments/json/copy-through-json.js +11 -0
  43. package/dist/augments/json/jsonify.d.ts +2 -0
  44. package/dist/augments/json/jsonify.js +4 -0
  45. package/dist/augments/log/log-colors.d.ts +23 -0
  46. package/dist/augments/log/log-colors.js +116 -0
  47. package/dist/augments/log/log-string.d.ts +14 -0
  48. package/dist/augments/log/log-string.js +66 -0
  49. package/dist/augments/log/log-writer.d.ts +8 -0
  50. package/dist/augments/log/log.d.ts +13 -0
  51. package/dist/augments/log/log.js +42 -0
  52. package/dist/augments/log/logger.d.ts +11 -0
  53. package/dist/augments/log/logger.js +38 -0
  54. package/dist/augments/number/clamp.d.ts +7 -0
  55. package/dist/augments/number/clamp.js +8 -0
  56. package/dist/augments/number/coords.d.ts +19 -0
  57. package/dist/augments/number/digit.d.ts +1 -0
  58. package/dist/augments/number/dimensions.d.ts +19 -0
  59. package/dist/augments/number/min-max.d.ts +11 -0
  60. package/dist/augments/number/min-max.js +14 -0
  61. package/dist/augments/number/number-conversion.d.ts +23 -0
  62. package/dist/augments/number/number-conversion.js +50 -0
  63. package/dist/augments/number/round.d.ts +3 -0
  64. package/dist/augments/number/round.js +5 -0
  65. package/dist/augments/number/scientific.d.ts +1 -0
  66. package/dist/augments/number/scientific.js +3 -0
  67. package/dist/{esm/augments → augments/number}/truncate-number.js +14 -12
  68. package/dist/augments/number/wrap-number.d.ts +13 -0
  69. package/dist/augments/number/wrap-number.js +22 -0
  70. package/dist/augments/object/diff.d.ts +29 -0
  71. package/dist/augments/object/diff.js +133 -0
  72. package/dist/augments/object/empty.d.ts +3 -0
  73. package/dist/augments/object/get-or-set.d.ts +31 -0
  74. package/dist/{esm/augments → augments}/object/get-or-set.js +5 -3
  75. package/dist/{types/augments → augments}/object/key-count.d.ts +9 -5
  76. package/dist/augments/object/map-entries.d.ts +13 -0
  77. package/dist/augments/object/map-entries.js +57 -0
  78. package/dist/augments/object/map-enum.d.ts +4 -0
  79. package/dist/augments/object/map-enum.js +21 -0
  80. package/dist/{types/augments/object/map-object.d.ts → augments/object/map-values.d.ts} +6 -3
  81. package/dist/{esm/augments/object/map-object.js → augments/object/map-values.js} +9 -9
  82. package/dist/{esm/augments → augments}/object/merge-deep.js +5 -6
  83. package/dist/augments/object/merge-defined-properties.d.ts +6 -0
  84. package/dist/augments/object/merge-defined-properties.js +19 -0
  85. package/dist/{esm/augments → augments}/object/merge-property-arrays.js +1 -1
  86. package/dist/augments/object/object-entries.d.ts +4 -0
  87. package/dist/augments/object/object-entries.js +13 -0
  88. package/dist/augments/object/object-filter.d.ts +2 -0
  89. package/dist/augments/object/object-filter.js +7 -0
  90. package/dist/augments/object/object-keys.d.ts +2 -0
  91. package/dist/augments/object/object-keys.js +11 -0
  92. package/dist/augments/object/object-values.d.ts +2 -0
  93. package/dist/augments/object/object-values.js +4 -0
  94. package/dist/augments/prisma/prisma-models.d.ts +106 -0
  95. package/dist/augments/prisma/prisma-models.js +1 -0
  96. package/dist/augments/promise/timed-promise.d.ts +7 -0
  97. package/dist/augments/promise/timed-promise.js +36 -0
  98. package/dist/augments/random/random-boolean.d.ts +18 -0
  99. package/dist/augments/random/random-boolean.js +26 -0
  100. package/dist/augments/random/random-integer.d.ts +12 -0
  101. package/dist/augments/random/random-integer.js +32 -0
  102. package/dist/augments/random/random-string.d.ts +14 -0
  103. package/dist/augments/random/random-string.js +63 -0
  104. package/dist/{types/augments/regexp.d.ts → augments/regexp/regexp-flags.d.ts} +1 -1
  105. package/dist/augments/regexp/regexp-flags.js +18 -0
  106. package/dist/augments/regexp/regexp-string.d.ts +5 -0
  107. package/dist/augments/regexp/regexp-string.js +7 -0
  108. package/dist/augments/regexp/safe-match.d.ts +1 -0
  109. package/dist/augments/regexp/safe-match.js +4 -0
  110. package/dist/augments/selection-set/select-collapsed.d.ts +11 -0
  111. package/dist/augments/selection-set/select-collapsed.js +25 -0
  112. package/dist/augments/selection-set/select-from.d.ts +3 -0
  113. package/dist/augments/selection-set/select-from.js +25 -0
  114. package/dist/augments/selection-set/selection-set.d.ts +18 -0
  115. package/dist/augments/selection-set/selection-set.js +4 -0
  116. package/dist/augments/string/casing/capitalization.d.ts +3 -0
  117. package/dist/augments/string/casing/capitalization.js +11 -0
  118. package/dist/augments/string/casing/casing.d.ts +27 -0
  119. package/dist/augments/string/casing/casing.js +40 -0
  120. package/dist/augments/string/casing/kebab-and-camel.d.ts +3 -0
  121. package/dist/augments/string/casing/kebab-and-camel.js +42 -0
  122. package/dist/augments/string/commas.d.ts +7 -0
  123. package/dist/augments/string/commas.js +29 -0
  124. package/dist/augments/string/join.d.ts +10 -0
  125. package/dist/augments/string/join.js +23 -0
  126. package/dist/{types/augments/string/prefixes.d.ts → augments/string/prefix.d.ts} +16 -1
  127. package/dist/{esm/augments/string/prefixes.js → augments/string/prefix.js} +11 -1
  128. package/dist/augments/string/replace.d.ts +1 -0
  129. package/dist/augments/string/replace.js +5 -0
  130. package/dist/augments/string/split.d.ts +4 -0
  131. package/dist/augments/string/split.js +28 -0
  132. package/dist/augments/string/substring-index.d.ts +13 -0
  133. package/dist/augments/string/substring-index.js +38 -0
  134. package/dist/augments/string/suffix.d.ts +74 -0
  135. package/dist/augments/string/suffix.js +73 -0
  136. package/dist/augments/string/white-space.d.ts +5 -0
  137. package/dist/augments/string/white-space.js +12 -0
  138. package/dist/augments/string/wrap-string.d.ts +4 -0
  139. package/dist/augments/string/wrap-string.js +5 -0
  140. package/dist/augments/type/ensure-type.d.ts +8 -0
  141. package/dist/augments/type/ensure-type.js +10 -0
  142. package/dist/augments/type/readonly.d.ts +2 -0
  143. package/dist/augments/type/readonly.js +3 -0
  144. package/dist/augments/type/type-recursion.js +1 -0
  145. package/dist/augments/type/void-type.d.ts +5 -0
  146. package/dist/augments/type/void-type.js +1 -0
  147. package/dist/augments/type/writable.d.ts +3 -0
  148. package/dist/augments/type/writable.js +3 -0
  149. package/dist/index.d.ts +81 -0
  150. package/dist/index.js +81 -0
  151. package/package.json +33 -15
  152. package/README.md +0 -7
  153. package/dist/cjs/augments/ansi.js +0 -27
  154. package/dist/cjs/augments/array/array.js +0 -68
  155. package/dist/cjs/augments/array/remove-duplicates.js +0 -16
  156. package/dist/cjs/augments/async.js +0 -28
  157. package/dist/cjs/augments/boolean.js +0 -19
  158. package/dist/cjs/augments/common-number.js +0 -112
  159. package/dist/cjs/augments/common-string.js +0 -245
  160. package/dist/cjs/augments/debounce.js +0 -38
  161. package/dist/cjs/augments/environment.js +0 -6
  162. package/dist/cjs/augments/error.js +0 -52
  163. package/dist/cjs/augments/esm-path.js +0 -11
  164. package/dist/cjs/augments/function.js +0 -2
  165. package/dist/cjs/augments/json-compatible.js +0 -2
  166. package/dist/cjs/augments/json.js +0 -28
  167. package/dist/cjs/augments/object/any-object.js +0 -2
  168. package/dist/cjs/augments/object/enum.js +0 -48
  169. package/dist/cjs/augments/object/filter-object.js +0 -26
  170. package/dist/cjs/augments/object/get-or-set.js +0 -40
  171. package/dist/cjs/augments/object/has-key.js +0 -6
  172. package/dist/cjs/augments/object/jsonify.js +0 -6
  173. package/dist/cjs/augments/object/key-count.js +0 -2
  174. package/dist/cjs/augments/object/map-object.js +0 -61
  175. package/dist/cjs/augments/object/merge-deep.js +0 -52
  176. package/dist/cjs/augments/object/merge-property-arrays.js +0 -14
  177. package/dist/cjs/augments/object/object-entries.js +0 -40
  178. package/dist/cjs/augments/object/object.js +0 -18
  179. package/dist/cjs/augments/object/pick-deep.js +0 -2
  180. package/dist/cjs/augments/object/selection-set.js +0 -56
  181. package/dist/cjs/augments/object/typed-has-property.js +0 -29
  182. package/dist/cjs/augments/promise/deferred-promise.js +0 -31
  183. package/dist/cjs/augments/promise/promise.js +0 -79
  184. package/dist/cjs/augments/promise/wait.js +0 -66
  185. package/dist/cjs/augments/random.js +0 -123
  186. package/dist/cjs/augments/regexp.js +0 -19
  187. package/dist/cjs/augments/string/prefixes.js +0 -20
  188. package/dist/cjs/augments/string/suffixes.js +0 -40
  189. package/dist/cjs/augments/string/uuid.js +0 -7
  190. package/dist/cjs/augments/time.js +0 -35
  191. package/dist/cjs/augments/truncate-number.js +0 -153
  192. package/dist/cjs/augments/tuple.js +0 -20
  193. package/dist/cjs/augments/type-recursion.js +0 -2
  194. package/dist/cjs/augments/type.js +0 -36
  195. package/dist/cjs/augments/union.js +0 -2
  196. package/dist/cjs/augments/wrap-in-try.js +0 -37
  197. package/dist/cjs/index.js +0 -60
  198. package/dist/esm/augments/ansi.js +0 -24
  199. package/dist/esm/augments/array/array.js +0 -57
  200. package/dist/esm/augments/async.js +0 -23
  201. package/dist/esm/augments/common-number.js +0 -100
  202. package/dist/esm/augments/common-string.js +0 -227
  203. package/dist/esm/augments/debounce.js +0 -34
  204. package/dist/esm/augments/environment.js +0 -3
  205. package/dist/esm/augments/error.js +0 -45
  206. package/dist/esm/augments/json.js +0 -24
  207. package/dist/esm/augments/object/enum.js +0 -41
  208. package/dist/esm/augments/object/filter-object.js +0 -21
  209. package/dist/esm/augments/object/has-key.js +0 -3
  210. package/dist/esm/augments/object/jsonify.js +0 -3
  211. package/dist/esm/augments/object/object-entries.js +0 -32
  212. package/dist/esm/augments/object/object.js +0 -14
  213. package/dist/esm/augments/object/selection-set.js +0 -52
  214. package/dist/esm/augments/object/typed-has-property.js +0 -25
  215. package/dist/esm/augments/promise/deferred-promise.js +0 -28
  216. package/dist/esm/augments/promise/promise.js +0 -71
  217. package/dist/esm/augments/promise/wait.js +0 -60
  218. package/dist/esm/augments/random.js +0 -117
  219. package/dist/esm/augments/regexp.js +0 -14
  220. package/dist/esm/augments/string/suffixes.js +0 -31
  221. package/dist/esm/augments/string/uuid.js +0 -4
  222. package/dist/esm/augments/tuple.js +0 -16
  223. package/dist/esm/augments/type.js +0 -30
  224. package/dist/esm/index.js +0 -44
  225. package/dist/types/augments/ansi.d.ts +0 -1
  226. package/dist/types/augments/array/array.d.ts +0 -26
  227. package/dist/types/augments/async.d.ts +0 -14
  228. package/dist/types/augments/boolean.d.ts +0 -6
  229. package/dist/types/augments/common-number.d.ts +0 -52
  230. package/dist/types/augments/common-string.d.ts +0 -74
  231. package/dist/types/augments/debounce.d.ts +0 -15
  232. package/dist/types/augments/environment.d.ts +0 -1
  233. package/dist/types/augments/error.d.ts +0 -9
  234. package/dist/types/augments/function.d.ts +0 -25
  235. package/dist/types/augments/json.d.ts +0 -9
  236. package/dist/types/augments/object/any-object.d.ts +0 -2
  237. package/dist/types/augments/object/enum.d.ts +0 -8
  238. package/dist/types/augments/object/filter-object.d.ts +0 -4
  239. package/dist/types/augments/object/get-or-set.d.ts +0 -26
  240. package/dist/types/augments/object/has-key.d.ts +0 -1
  241. package/dist/types/augments/object/jsonify.d.ts +0 -2
  242. package/dist/types/augments/object/object-entries.d.ts +0 -8
  243. package/dist/types/augments/object/object.d.ts +0 -21
  244. package/dist/types/augments/object/pick-deep.d.ts +0 -14
  245. package/dist/types/augments/object/selection-set.d.ts +0 -27
  246. package/dist/types/augments/object/typed-has-property.d.ts +0 -7
  247. package/dist/types/augments/promise/deferred-promise.d.ts +0 -8
  248. package/dist/types/augments/promise/promise.d.ts +0 -15
  249. package/dist/types/augments/promise/wait.d.ts +0 -18
  250. package/dist/types/augments/random.d.ts +0 -39
  251. package/dist/types/augments/string/suffixes.d.ts +0 -17
  252. package/dist/types/augments/string/uuid.d.ts +0 -1
  253. package/dist/types/augments/time.d.ts +0 -14
  254. package/dist/types/augments/tuple.d.ts +0 -17
  255. package/dist/types/augments/type.d.ts +0 -69
  256. package/dist/types/augments/union.d.ts +0 -5
  257. package/dist/types/index.d.ts +0 -44
  258. /package/dist/{types/augments → augments}/array/remove-duplicates.d.ts +0 -0
  259. /package/dist/{esm/augments → augments}/array/remove-duplicates.js +0 -0
  260. /package/dist/{types/augments → augments/file}/esm-path.d.ts +0 -0
  261. /package/dist/{esm/augments → augments/file}/esm-path.js +0 -0
  262. /package/dist/{types/augments → augments/json}/json-compatible.d.ts +0 -0
  263. /package/dist/{esm/augments → augments/json}/json-compatible.js +0 -0
  264. /package/dist/{esm/augments/function.js → augments/log/log-writer.js} +0 -0
  265. /package/dist/{esm/augments/object/any-object.js → augments/number/coords.js} +0 -0
  266. /package/dist/{esm/augments/object/key-count.js → augments/number/digit.js} +0 -0
  267. /package/dist/{esm/augments/object/pick-deep.js → augments/number/dimensions.js} +0 -0
  268. /package/dist/{types/augments → augments/number}/truncate-number.d.ts +0 -0
  269. /package/dist/{esm/augments/type-recursion.js → augments/object/empty.js} +0 -0
  270. /package/dist/{esm/augments/union.js → augments/object/key-count.js} +0 -0
  271. /package/dist/{types/augments → augments}/object/merge-deep.d.ts +0 -0
  272. /package/dist/{types/augments → augments}/object/merge-property-arrays.d.ts +0 -0
  273. /package/dist/{types/augments → augments/type}/type-recursion.d.ts +0 -0
@@ -0,0 +1,106 @@
1
+ import type { AnyFunction, AnyObject } from '@augment-vir/core';
2
+ /**
3
+ * Extracts all model names from a generated `Prisma` object.
4
+ *
5
+ * @example
6
+ *
7
+ * ```ts
8
+ * import type {Prisma} from '@prisma/client';
9
+ *
10
+ * function doThing(modelName: ModelNameFromPrismaTypeMap<Prisma.TypeMap>) {}
11
+ * ```
12
+ */
13
+ export type ModelNameFromPrismaTypeMap<PrismaTypeMap extends BasePrismaTypeMap> = PrismaTypeMap['meta']['modelProps'];
14
+ /**
15
+ * Extracts all model names from a generated `PrismaClient`.
16
+ *
17
+ * @example
18
+ *
19
+ * ```ts
20
+ * import type {PrismaClient} from '@prisma/client';
21
+ *
22
+ * function doThing(modelName: ModelNameFromPrismaClient<PrismaClient>) {}
23
+ * ```
24
+ */
25
+ export type ModelNameFromPrismaClient<PrismaClient extends AnyObject> = keyof {
26
+ [Model in Extract<keyof PrismaClient, string> as PrismaClient[Model] extends {
27
+ findFirst: AnyFunction;
28
+ } ? Model : never]: boolean;
29
+ };
30
+ /**
31
+ * Extracts the creation data for a model from the given `PrismaClient` type.
32
+ *
33
+ * @example
34
+ *
35
+ * ```ts
36
+ * import type {PrismaClient} from '@prisma/client';
37
+ *
38
+ * function doThing(entry: ModelCreationEntry<PrismaClient, 'User'>) {}
39
+ * ```
40
+ */
41
+ export type PrismaModelCreationEntry<PrismaClient extends AnyObject, Model extends ModelNameFromPrismaClient<PrismaClient>> = NonNullable<Parameters<PrismaClient[Model]['create']>[0]> extends {
42
+ data?: infer Data;
43
+ } ? NonNullable<Data> : `ERROR: failed to infer creation entry for model '${Model}'`;
44
+ /**
45
+ * A base type for `Prisma.TypeMap` because Prisma doesn't give us one. This currently only includes
46
+ * the properties that are used within `@augment-vir/prisma-node-js`.
47
+ */
48
+ export type BasePrismaTypeMap = {
49
+ meta: {
50
+ modelProps: string;
51
+ };
52
+ model: Record<string, {
53
+ payload: BasePrismaPayload;
54
+ }>;
55
+ };
56
+ /**
57
+ * A base type for Prisma model payloads because Prisma doesn't give us one. This currently only
58
+ * includes the properties that are used within this package.
59
+ *
60
+ * Note: this omits the `composites` property because I don't have any examples of what those
61
+ * actually are.
62
+ */
63
+ export type BasePrismaPayload = {
64
+ name: string;
65
+ objects: Record<string, BasePrismaPayload | BasePrismaPayload[] | null>;
66
+ scalars: AnyObject;
67
+ };
68
+ /**
69
+ * A full model entry with all relations from the given Prisma type map and model name.
70
+ *
71
+ * @example
72
+ *
73
+ * ```ts
74
+ * import type {Prisma} from '@prisma/client';
75
+ *
76
+ * function doThing(fullModel: FullModel<Prisma.TypeMap, 'User'>) {}
77
+ * ```
78
+ */
79
+ export type FullPrismaModel<PrismaTypeMap extends BasePrismaTypeMap, Model extends ModelNameFromPrismaTypeMap<PrismaTypeMap>> = ExpandPrismaTypeMapPayload<PrismaTypeMap['model'][Model]['payload']>;
80
+ /**
81
+ * A base model entry with only its immediate properties from the given Prisma type map and model
82
+ * name.
83
+ *
84
+ * @example
85
+ *
86
+ * ```ts
87
+ * import type {Prisma} from '@prisma/client';
88
+ *
89
+ * function doThing(fullModel: BaseModel<Prisma.TypeMap, 'User'>) {}
90
+ * ```
91
+ */
92
+ export type BasePrismaModel<PrismaTypeMap extends BasePrismaTypeMap, Model extends ModelNameFromPrismaTypeMap<PrismaTypeMap>> = PrismaTypeMap['model'][Model]['payload']['scalars'];
93
+ /**
94
+ * Expand a Prisma payload into its scalars and recursive relations.
95
+ *
96
+ * @category Internals
97
+ */
98
+ export type ExpandPrismaTypeMapPayload<Payload extends BasePrismaPayload> = Payload['scalars'] & {
99
+ [Key in keyof Payload['objects']]: ExpandPotentialArrayPrismaTypeMapPayload<NonNullable<Payload['objects'][Key]>> | (null extends Payload['objects'][Key] ? null : never);
100
+ };
101
+ /**
102
+ * Expand a payload that might be inside of an array, keeping it inside of an array if it is.
103
+ *
104
+ * @category Internals
105
+ */
106
+ export type ExpandPotentialArrayPrismaTypeMapPayload<PayloadWrapper extends BasePrismaPayload | BasePrismaPayload[]> = PayloadWrapper extends (infer ActualPayload extends BasePrismaPayload)[] ? ExpandPrismaTypeMapPayload<ActualPayload>[] : PayloadWrapper extends BasePrismaPayload ? ExpandPrismaTypeMapPayload<PayloadWrapper> : never;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import { AnyDuration } from '@date-vir/duration';
2
+ export declare class PromiseTimeoutError extends Error {
3
+ readonly duration: AnyDuration;
4
+ readonly name = "PromiseTimeoutError";
5
+ constructor(duration: AnyDuration, failureMessage?: string | undefined);
6
+ }
7
+ export declare function wrapPromiseInTimeout<T>(duration: Readonly<AnyDuration>, originalPromise: PromiseLike<T>, failureMessage?: string | undefined): Promise<T>;
@@ -0,0 +1,36 @@
1
+ import { check } from '@augment-vir/assert';
2
+ import { ensureError } from '@augment-vir/core';
3
+ import { convertDuration, DurationUnit } from '@date-vir/duration';
4
+ export class PromiseTimeoutError extends Error {
5
+ duration;
6
+ name = 'PromiseTimeoutError';
7
+ constructor(duration, failureMessage) {
8
+ super([
9
+ failureMessage,
10
+ `Promised timed out after ${convertDuration(duration, DurationUnit.Milliseconds).milliseconds} ms.`,
11
+ ]
12
+ .filter(check.isTruthy)
13
+ .join(': '));
14
+ this.duration = duration;
15
+ }
16
+ }
17
+ export function wrapPromiseInTimeout(duration, originalPromise, failureMessage) {
18
+ const milliseconds = convertDuration(duration, DurationUnit.Milliseconds).milliseconds;
19
+ return new Promise(async (resolve, reject) => {
20
+ const timeoutId = milliseconds === Infinity
21
+ ? undefined
22
+ : setTimeout(() => {
23
+ reject(new PromiseTimeoutError(duration, failureMessage));
24
+ }, milliseconds);
25
+ try {
26
+ const result = await originalPromise;
27
+ resolve(result);
28
+ }
29
+ catch (error) {
30
+ reject(ensureError(error));
31
+ }
32
+ finally {
33
+ clearTimeout(timeoutId);
34
+ }
35
+ });
36
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Returns true at rate of the percentLikelyToBeTrue input. Inputs should be whole numbers which
3
+ * will be treated like percents. Anything outside of 0-100 inclusively will be clamped. An input 0
4
+ * will always return true. An input of 100 will always return true. Decimals on the input will be
5
+ * chopped off, use whole numbers.
6
+ *
7
+ * This function uses cryptographically secure randomness.
8
+ *
9
+ * @example
10
+ *
11
+ * ```ts
12
+ * randomBoolean(50); // 50% chance to return true
13
+ * randomBoolean(0); // always false, 0% chance of being true
14
+ * randomBoolean(100); // always true, 100% chance of being true
15
+ * randomBoolean(59.67); // 59% chance of being true
16
+ * ```
17
+ */
18
+ export declare function randomBoolean(percentLikelyToBeTrue?: number): boolean;
@@ -0,0 +1,26 @@
1
+ import { clamp } from '../number/clamp.js';
2
+ import { randomInteger } from './random-integer.js';
3
+ /**
4
+ * Returns true at rate of the percentLikelyToBeTrue input. Inputs should be whole numbers which
5
+ * will be treated like percents. Anything outside of 0-100 inclusively will be clamped. An input 0
6
+ * will always return true. An input of 100 will always return true. Decimals on the input will be
7
+ * chopped off, use whole numbers.
8
+ *
9
+ * This function uses cryptographically secure randomness.
10
+ *
11
+ * @example
12
+ *
13
+ * ```ts
14
+ * randomBoolean(50); // 50% chance to return true
15
+ * randomBoolean(0); // always false, 0% chance of being true
16
+ * randomBoolean(100); // always true, 100% chance of being true
17
+ * randomBoolean(59.67); // 59% chance of being true
18
+ * ```
19
+ */
20
+ export function randomBoolean(percentLikelyToBeTrue = 50) {
21
+ return (randomInteger({ min: 0, max: 99 }) <
22
+ clamp(Math.floor(percentLikelyToBeTrue), {
23
+ min: 0,
24
+ max: 100,
25
+ }));
26
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Creates a random integer (no decimal points are included) between the given min and max values
3
+ * (inclusive).
4
+ *
5
+ * This function uses cryptographically secure randomness.
6
+ *
7
+ * @category Random:Common
8
+ */
9
+ export declare function randomInteger({ min: rawMin, max: rawMax }: {
10
+ min: number;
11
+ max: number;
12
+ }): number;
@@ -0,0 +1,32 @@
1
+ import { ensureMinMax } from '../number/min-max.js';
2
+ /**
3
+ * Creates a random integer (no decimal points are included) between the given min and max values
4
+ * (inclusive).
5
+ *
6
+ * This function uses cryptographically secure randomness.
7
+ *
8
+ * @category Random:Common
9
+ */
10
+ export function randomInteger({ min: rawMin, max: rawMax }) {
11
+ const { min, max } = ensureMinMax({ min: Math.floor(rawMin), max: Math.floor(rawMax) });
12
+ const range = max - min + 1;
13
+ const bitsNeeded = Math.ceil(Math.log2(range));
14
+ const neededBytes = Math.ceil(bitsNeeded / 8);
15
+ /**
16
+ * Testing on my system maxes out at 65,536 (Node) or 65,537 (Safari / Chrome / Firefox) bytes.
17
+ * I don't know why, and that may be system dependent, I don't know.
18
+ */
19
+ if (neededBytes > 65_000) {
20
+ throw new RangeError(`Cannot create a random integer so large. ({min: ${min}, max: ${max}})`);
21
+ }
22
+ const cutoff = Math.floor(256 ** neededBytes / range) * range;
23
+ const currentBytes = new Uint8Array(neededBytes);
24
+ let value;
25
+ do {
26
+ crypto.getRandomValues(currentBytes);
27
+ value = currentBytes.reduce((accum, byte, index) => {
28
+ return accum + byte * 256 ** index;
29
+ }, 0);
30
+ } while (value >= cutoff);
31
+ return min + (value % range);
32
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * All letters allowed in {@link randomString}.
3
+ *
4
+ * @category Random:Common
5
+ */
6
+ export declare const allowedRandomStringLetters: ReadonlyArray<string>;
7
+ /**
8
+ * Creates a random string (including letters and numbers) of a given length.
9
+ *
10
+ * This function uses cryptographically secure randomness.
11
+ *
12
+ * @category Random:Common
13
+ */
14
+ export declare function randomString(generatedStringLength?: number): string;
@@ -0,0 +1,63 @@
1
+ import { randomInteger } from './random-integer.js';
2
+ /**
3
+ * All letters allowed in {@link randomString}.
4
+ *
5
+ * @category Random:Common
6
+ */
7
+ export const allowedRandomStringLetters = [
8
+ 'a',
9
+ 'b',
10
+ 'c',
11
+ 'd',
12
+ 'e',
13
+ 'f',
14
+ 'g',
15
+ 'h',
16
+ 'i',
17
+ 'j',
18
+ 'k',
19
+ 'l',
20
+ 'm',
21
+ 'n',
22
+ 'o',
23
+ 'p',
24
+ 'q',
25
+ 'r',
26
+ 's',
27
+ 't',
28
+ 'u',
29
+ 'v',
30
+ 'w',
31
+ 'x',
32
+ 'y',
33
+ 'z',
34
+ '0',
35
+ '1',
36
+ '2',
37
+ '3',
38
+ '4',
39
+ '5',
40
+ '6',
41
+ '7',
42
+ '8',
43
+ '9',
44
+ ];
45
+ /**
46
+ * Creates a random string (including letters and numbers) of a given length.
47
+ *
48
+ * This function uses cryptographically secure randomness.
49
+ *
50
+ * @category Random:Common
51
+ */
52
+ export function randomString(generatedStringLength = 16) {
53
+ let stringBuilder = '';
54
+ for (let i = 0; i < generatedStringLength; i++) {
55
+ const index = randomInteger({
56
+ min: 0,
57
+ max: allowedRandomStringLetters.length - 1,
58
+ });
59
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
60
+ stringBuilder += allowedRandomStringLetters[index];
61
+ }
62
+ return stringBuilder;
63
+ }
@@ -1,3 +1,3 @@
1
1
  export declare function deDupeRegExFlags(flags: string): string;
2
2
  export declare function addRegExpFlags(originalRegExp: RegExp, flags: string): RegExp;
3
- export declare function safeMatch(input: string, regExp: RegExp): string[];
3
+ export declare function makeCaseInsensitiveRegExp(searchForInput: string | RegExp, caseSensitive: boolean): RegExp;
@@ -0,0 +1,18 @@
1
+ import { escapeStringForRegExp } from './regexp-string.js';
2
+ export function deDupeRegExFlags(flags) {
3
+ const deDuped = new Set(Array.from(flags.toLowerCase()));
4
+ return Array.from(deDuped).join('');
5
+ }
6
+ export function addRegExpFlags(originalRegExp, flags) {
7
+ return new RegExp(originalRegExp.source, deDupeRegExFlags([
8
+ originalRegExp.flags,
9
+ flags,
10
+ ].join('')));
11
+ }
12
+ export function makeCaseInsensitiveRegExp(searchForInput, caseSensitive) {
13
+ const regExpFlags = `g${!caseSensitive && typeof searchForInput === 'string' ? 'i' : ''}`;
14
+ const searchFor = searchForInput instanceof RegExp
15
+ ? new RegExp(searchForInput.source, deDupeRegExFlags(`${searchForInput.flags}${regExpFlags}`))
16
+ : new RegExp(escapeStringForRegExp(searchForInput), regExpFlags);
17
+ return searchFor;
18
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Escapes characters from the given string so that it can be used within a RegExp without being
3
+ * parsed as RegExp syntax.
4
+ */
5
+ export declare function escapeStringForRegExp(input: string): string;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Escapes characters from the given string so that it can be used within a RegExp without being
3
+ * parsed as RegExp syntax.
4
+ */
5
+ export function escapeStringForRegExp(input) {
6
+ return input.replace(/[\^$\\.*+?()[\]{}|]/g, String.raw `\$&`);
7
+ }
@@ -0,0 +1 @@
1
+ export declare function safeMatch(input: string, regExp: RegExp): string[];
@@ -0,0 +1,4 @@
1
+ export function safeMatch(input, regExp) {
2
+ const match = input.match(regExp);
3
+ return match ?? [];
4
+ }
@@ -0,0 +1,11 @@
1
+ import type { AnyObject, Values } from '@augment-vir/core';
2
+ import { ExcludeEmpty } from '../object/empty.js';
3
+ import { KeyCount } from '../object/key-count.js';
4
+ import { TsRecurse, TsRecursionStart, TsRecursionTracker, TsTooMuchRecursion } from '../type/type-recursion.js';
5
+ import { GenericSelectionSet, PickSelection, SelectionSet } from './selection-set.js';
6
+ export declare function selectCollapsedFrom<Full extends AnyObject, const Selection extends SelectionSet<NoInfer<Full>>>(originalObject: Readonly<Full>, selectionSet: Readonly<Selection>): PickCollapsedSelection<Full, Selection>;
7
+ /**
8
+ * Collapses a selected value to the first part of the selection that contains more than 1 key or
9
+ * that is not an object.
10
+ */
11
+ export type PickCollapsedSelection<Full extends Readonly<AnyObject>, Selection extends SelectionSet<Full>, Depth extends TsRecursionTracker = TsRecursionStart> = Depth extends TsTooMuchRecursion ? 'Error: recursive object depth is too deep.' : KeyCount<ExcludeEmpty<NonNullable<PickSelection<Full, Selection, Depth>>>> extends 1 ? Selection[keyof PickSelection<Full, Selection, Depth>] extends GenericSelectionSet ? PickCollapsedSelection<NonNullable<Full[keyof PickSelection<Full, Selection, Depth>]>, Selection[keyof PickSelection<Full, Selection, Depth>], TsRecurse<Depth>> | Extract<Full[keyof PickSelection<Full, Selection, Depth>], undefined | null> : Values<PickSelection<Full, Selection, Depth>> : PickSelection<Full, Selection, Depth>;
@@ -0,0 +1,25 @@
1
+ import { check } from '@augment-vir/assert';
2
+ import { selectFrom } from './select-from.js';
3
+ import { shouldPreserveInSelectionSet, } from './selection-set.js';
4
+ export function selectCollapsedFrom(originalObject, selectionSet) {
5
+ const selected = selectFrom(originalObject, selectionSet);
6
+ return collapseObject(selected, selectionSet);
7
+ }
8
+ function collapseObject(input, selectionSet) {
9
+ if (shouldPreserveInSelectionSet(input)) {
10
+ return input;
11
+ }
12
+ const keys = Object.keys(input);
13
+ if (Array.isArray(input)) {
14
+ return input.map((innerInput) => collapseObject(innerInput, selectionSet));
15
+ }
16
+ else if (check.isLengthAtLeast(keys, 2)) {
17
+ return input;
18
+ }
19
+ else if (check.isLengthAtLeast(keys, 1) && check.isObject(selectionSet)) {
20
+ return collapseObject(input[keys[0]], selectionSet[keys[0]]);
21
+ }
22
+ else {
23
+ return input;
24
+ }
25
+ }
@@ -0,0 +1,3 @@
1
+ import type { AnyObject } from '@augment-vir/core';
2
+ import { PickSelection, SelectionSet } from './selection-set.js';
3
+ export declare function selectFrom<Full extends AnyObject, const Selection extends SelectionSet<NoInfer<Full>>>(originalObject: Readonly<Full>, selectionSet: Readonly<Selection>): PickSelection<Full, Selection>;
@@ -0,0 +1,25 @@
1
+ import { mapObjectValues } from '../object/map-values.js';
2
+ import { omitObjectKeys } from '../object/object-keys.js';
3
+ import { shouldPreserveInSelectionSet } from './selection-set.js';
4
+ export function selectFrom(originalObject, selectionSet) {
5
+ if (Array.isArray(originalObject)) {
6
+ return originalObject.map((originalEntry) => selectFrom(originalEntry, selectionSet));
7
+ }
8
+ const keysToRemove = [];
9
+ return omitObjectKeys(mapObjectValues(originalObject, (key, value) => {
10
+ const selection = selectionSet[key];
11
+ if (selection === true) {
12
+ return value;
13
+ }
14
+ else if (!selection) {
15
+ keysToRemove.push(key);
16
+ return undefined;
17
+ }
18
+ else if (shouldPreserveInSelectionSet(value)) {
19
+ return value;
20
+ }
21
+ else {
22
+ return selectFrom(value, selection);
23
+ }
24
+ }), keysToRemove);
25
+ }
@@ -0,0 +1,18 @@
1
+ import type { AnyObject } from '@augment-vir/core';
2
+ import { IsAny, IsNever, Primitive, UnionToIntersection } from 'type-fest';
3
+ import { TsRecurse, TsRecursionStart, TsRecursionTracker, TsTooMuchRecursion } from '../type/type-recursion.js';
4
+ export declare function shouldPreserveInSelectionSet(input: unknown): input is SelectionTypesToPreserve;
5
+ /** All types that won't be recursed into when defining a {@link SelectionSet}. */
6
+ export type SelectionTypesToPreserve = Primitive | RegExp | Promise<any>;
7
+ /** A generic selection set without specific keys. */
8
+ export type GenericSelectionSet = {
9
+ [Key in PropertyKey]: unknown;
10
+ };
11
+ /** Masks an object value with the given {@link SelectionSet}. */
12
+ export type PickSelection<Full extends Readonly<AnyObject>, Selection extends SelectionSet<Full>, Depth extends TsRecursionTracker = TsRecursionStart> = Depth extends TsTooMuchRecursion ? ['Error: recursive object depth is too deep.'] : Full extends ReadonlyArray<infer Element extends any> ? (PickSelection<Extract<Element, AnyObject>, Selection, TsRecurse<Depth>> | Exclude<Element, AnyObject>)[] : {
13
+ -readonly [Key in keyof Selection as Selection[Key] extends false ? never : Key extends keyof Full ? Key : never]: (Selection[Key] extends GenericSelectionSet ? PickSelection<NonNullable<Extract<Full[Key], AnyObject>>, Selection[Key], TsRecurse<Depth>> : Full[Key]) | Exclude<Full[Key], AnyObject>;
14
+ };
15
+ /** Defines a selection set for the given object. */
16
+ export type SelectionSet<Full extends Readonly<AnyObject>, Depth extends TsRecursionTracker = TsRecursionStart> = IsAny<Full> extends true ? any : Depth extends TsTooMuchRecursion ? boolean : Full extends ReadonlyArray<infer FullChild extends AnyObject> ? SelectionSet<FullChild, TsRecurse<Depth>> : Partial<{
17
+ [Key in keyof Full]: IsNever<Exclude<Full[Key], SelectionTypesToPreserve>> extends true ? boolean : UnionToIntersection<SelectionSet<NonNullable<Required<Full>[Key]>, TsRecurse<Depth>>> | boolean;
18
+ }>;
@@ -0,0 +1,4 @@
1
+ import { check } from '@augment-vir/assert';
2
+ export function shouldPreserveInSelectionSet(input) {
3
+ return check.isPrimitive(input) || input instanceof RegExp || input instanceof Promise;
4
+ }
@@ -0,0 +1,3 @@
1
+ import { CasingOptions } from './casing.js';
2
+ export declare function maybeCapitalize(input: string, casingOptions: Partial<CasingOptions>): string;
3
+ export declare function capitalizeFirstLetter<InputGeneric extends string>(input: InputGeneric): Capitalize<InputGeneric>;
@@ -0,0 +1,11 @@
1
+ export function maybeCapitalize(input, casingOptions) {
2
+ return casingOptions.capitalizeFirstLetter ? capitalizeFirstLetter(input) : input;
3
+ }
4
+ export function capitalizeFirstLetter(input) {
5
+ if (!input.length) {
6
+ return '';
7
+ }
8
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
9
+ const firstLetter = input[0];
10
+ return (firstLetter.toUpperCase() + input.slice(1));
11
+ }
@@ -0,0 +1,27 @@
1
+ import { PartialWithUndefined } from '@augment-vir/core';
2
+ export type CasingOptions = {
3
+ capitalizeFirstLetter: boolean;
4
+ };
5
+ export declare const defaultCasingOptions: Required<CasingOptions>;
6
+ export declare enum StringCaseEnum {
7
+ Upper = "upper",
8
+ Lower = "lower"
9
+ }
10
+ /** Indicates whether the given string has different lower and upper case variants. */
11
+ export declare function hasCase(input: string): boolean;
12
+ export type IsCaseOptions = {
13
+ /**
14
+ * Fail on characters that don't have different upper and lower case versions (such as
15
+ * punctuation, like `'.'` or symbols, like `'√'`).
16
+ */
17
+ failOnNoCaseCharacters: boolean;
18
+ };
19
+ /**
20
+ * Checks if the given string is exclusively of the specific case.
21
+ *
22
+ * Note that some characters have no casing, such as punctuation (they have no difference between
23
+ * upper and lower casings). By default, those letters always return `true` for this function,
24
+ * regardless of which `caseType` is provided. To instead return `false` for any such characters,
25
+ * pass in an options object and set blockNoCaseCharacters to true.
26
+ */
27
+ export declare function isCase(input: string, caseType: StringCaseEnum, options?: PartialWithUndefined<IsCaseOptions>): boolean;
@@ -0,0 +1,40 @@
1
+ export const defaultCasingOptions = {
2
+ capitalizeFirstLetter: false,
3
+ };
4
+ export var StringCaseEnum;
5
+ (function (StringCaseEnum) {
6
+ StringCaseEnum["Upper"] = "upper";
7
+ StringCaseEnum["Lower"] = "lower";
8
+ })(StringCaseEnum || (StringCaseEnum = {}));
9
+ /** Indicates whether the given string has different lower and upper case variants. */
10
+ export function hasCase(input) {
11
+ return input.toLowerCase() !== input.toUpperCase();
12
+ }
13
+ /**
14
+ * Checks if the given string is exclusively of the specific case.
15
+ *
16
+ * Note that some characters have no casing, such as punctuation (they have no difference between
17
+ * upper and lower casings). By default, those letters always return `true` for this function,
18
+ * regardless of which `caseType` is provided. To instead return `false` for any such characters,
19
+ * pass in an options object and set blockNoCaseCharacters to true.
20
+ */
21
+ export function isCase(input, caseType, options) {
22
+ if (!input && options?.failOnNoCaseCharacters) {
23
+ return false;
24
+ }
25
+ for (const letter of input) {
26
+ if (!hasCase(letter)) {
27
+ if (options?.failOnNoCaseCharacters) {
28
+ return false;
29
+ }
30
+ else {
31
+ continue;
32
+ }
33
+ }
34
+ else if ((caseType === StringCaseEnum.Upper && letter !== letter.toUpperCase()) ||
35
+ (caseType === StringCaseEnum.Lower && letter !== letter.toLowerCase())) {
36
+ return false;
37
+ }
38
+ }
39
+ return true;
40
+ }
@@ -0,0 +1,3 @@
1
+ import { CasingOptions } from './casing.js';
2
+ export declare function kebabCaseToCamelCase(rawKebabCase: string, casingOptions?: Partial<CasingOptions> | undefined): string;
3
+ export declare function camelCaseToKebabCase(rawCamelCase: string): string;
@@ -0,0 +1,42 @@
1
+ import { maybeCapitalize } from './capitalization.js';
2
+ import { defaultCasingOptions, isCase, StringCaseEnum } from './casing.js';
3
+ export function kebabCaseToCamelCase(rawKebabCase, casingOptions = defaultCasingOptions) {
4
+ const kebabCase = rawKebabCase.toLowerCase();
5
+ if (!kebabCase.length) {
6
+ return '';
7
+ }
8
+ const camelCase = kebabCase
9
+ .replace(/^-+/, '')
10
+ .replace(/-{2,}/g, '-')
11
+ .replace(/-(?:.|$)/g, (dashMatch) => {
12
+ const letter = dashMatch[1];
13
+ if (letter) {
14
+ return letter.toUpperCase();
15
+ }
16
+ else {
17
+ return '';
18
+ }
19
+ });
20
+ return maybeCapitalize(camelCase, casingOptions);
21
+ }
22
+ export function camelCaseToKebabCase(rawCamelCase) {
23
+ const kebabCase = rawCamelCase
24
+ .split('')
25
+ .reduce((accum, currentLetter, index, originalString) => {
26
+ const previousLetter = index > 0 ? originalString[index - 1] || '' : '';
27
+ const nextLetter = index < originalString.length - 1 ? originalString[index + 1] || '' : '';
28
+ const possibleWordBoundary = isCase(previousLetter, StringCaseEnum.Lower, { failOnNoCaseCharacters: true }) ||
29
+ isCase(nextLetter, StringCaseEnum.Lower, { failOnNoCaseCharacters: true });
30
+ if (currentLetter === currentLetter.toLowerCase() ||
31
+ index === 0 ||
32
+ !possibleWordBoundary) {
33
+ accum += currentLetter;
34
+ }
35
+ else {
36
+ accum += `-${currentLetter.toLowerCase()}`;
37
+ }
38
+ return accum;
39
+ }, '')
40
+ .toLowerCase();
41
+ return kebabCase;
42
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Removes all commas from the given string.
3
+ *
4
+ * @category String:Common
5
+ */
6
+ export declare function removeCommas(input: string): string;
7
+ export declare function addCommasToNumber(input: number | string): string;
@@ -0,0 +1,29 @@
1
+ import { safeMatch } from '../regexp/safe-match.js';
2
+ /**
3
+ * Removes all commas from the given string.
4
+ *
5
+ * @category String:Common
6
+ */
7
+ export function removeCommas(input) {
8
+ return input.replace(/,/g, '');
9
+ }
10
+ export function addCommasToNumber(input) {
11
+ if (typeof input === 'string' && isNaN(Number(input))) {
12
+ return 'NaN';
13
+ }
14
+ const numericValue = Number(input);
15
+ const isNegative = numericValue < 0;
16
+ const stringValue = String(Math.abs(numericValue));
17
+ const [digits = '', decimalValues,] = stringValue.split('.');
18
+ const decimalString = decimalValues ? `.${decimalValues}` : '';
19
+ const separated = safeMatch(digits.split('').reverse().join(''), /.{1,3}/g)
20
+ .reverse()
21
+ .map((entry) => entry.split('').reverse().join(''));
22
+ const valueWithCommas = separated.join(',');
23
+ const negativeMarker = isNegative ? '-' : '';
24
+ return [
25
+ negativeMarker,
26
+ valueWithCommas,
27
+ decimalString,
28
+ ].join('');
29
+ }