@transcend-io/type-utils 2.0.1 → 3.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 (167) hide show
  1. package/LICENSE +201 -21
  2. package/dist/index.d.mts +591 -0
  3. package/dist/index.d.mts.map +1 -0
  4. package/dist/index.mjs +529 -0
  5. package/dist/index.mjs.map +1 -0
  6. package/package.json +33 -43
  7. package/.yarn/sdks/eslint/package.json +0 -14
  8. package/.yarn/sdks/prettier/package.json +0 -7
  9. package/.yarn/sdks/typescript/package.json +0 -10
  10. package/README.md +0 -37
  11. package/build/aggregateObjects.d.ts +0 -27
  12. package/build/aggregateObjects.d.ts.map +0 -1
  13. package/build/aggregateObjects.js +0 -34
  14. package/build/aggregateObjects.js.map +0 -1
  15. package/build/apply.d.ts +0 -35
  16. package/build/apply.d.ts.map +0 -1
  17. package/build/apply.js +0 -47
  18. package/build/apply.js.map +0 -1
  19. package/build/codecTools/FixedLengthArray.d.ts +0 -20
  20. package/build/codecTools/FixedLengthArray.d.ts.map +0 -1
  21. package/build/codecTools/FixedLengthArray.js +0 -11
  22. package/build/codecTools/FixedLengthArray.js.map +0 -1
  23. package/build/codecTools/FixedLengthString.d.ts +0 -17
  24. package/build/codecTools/FixedLengthString.d.ts.map +0 -1
  25. package/build/codecTools/FixedLengthString.js +0 -10
  26. package/build/codecTools/FixedLengthString.js.map +0 -1
  27. package/build/codecTools/NonEmptyString.d.ts +0 -12
  28. package/build/codecTools/NonEmptyString.d.ts.map +0 -1
  29. package/build/codecTools/NonEmptyString.js +0 -6
  30. package/build/codecTools/NonEmptyString.js.map +0 -1
  31. package/build/codecTools/createDefaultCodec.d.ts +0 -39
  32. package/build/codecTools/createDefaultCodec.d.ts.map +0 -1
  33. package/build/codecTools/createDefaultCodec.js +0 -114
  34. package/build/codecTools/createDefaultCodec.js.map +0 -1
  35. package/build/codecTools/decodeCodec.d.ts +0 -12
  36. package/build/codecTools/decodeCodec.d.ts.map +0 -1
  37. package/build/codecTools/decodeCodec.js +0 -47
  38. package/build/codecTools/decodeCodec.js.map +0 -1
  39. package/build/codecTools/dictionary.d.ts +0 -18
  40. package/build/codecTools/dictionary.d.ts.map +0 -1
  41. package/build/codecTools/dictionary.js +0 -13
  42. package/build/codecTools/dictionary.js.map +0 -1
  43. package/build/codecTools/index.d.ts +0 -10
  44. package/build/codecTools/index.d.ts.map +0 -1
  45. package/build/codecTools/index.js +0 -10
  46. package/build/codecTools/index.js.map +0 -1
  47. package/build/codecTools/isCodecError.d.ts +0 -7
  48. package/build/codecTools/isCodecError.d.ts.map +0 -1
  49. package/build/codecTools/isCodecError.js +0 -9
  50. package/build/codecTools/isCodecError.js.map +0 -1
  51. package/build/codecTools/partialRecord.d.ts +0 -16
  52. package/build/codecTools/partialRecord.d.ts.map +0 -1
  53. package/build/codecTools/partialRecord.js +0 -11
  54. package/build/codecTools/partialRecord.js.map +0 -1
  55. package/build/codecTools/toJsonSchema.d.ts +0 -11
  56. package/build/codecTools/toJsonSchema.d.ts.map +0 -1
  57. package/build/codecTools/toJsonSchema.js +0 -115
  58. package/build/codecTools/toJsonSchema.js.map +0 -1
  59. package/build/enum.d.ts +0 -47
  60. package/build/enum.d.ts.map +0 -1
  61. package/build/enum.js +0 -44
  62. package/build/enum.js.map +0 -1
  63. package/build/enums.d.ts +0 -20
  64. package/build/enums.d.ts.map +0 -1
  65. package/build/enums.js +0 -18
  66. package/build/enums.js.map +0 -1
  67. package/build/findAllWithRegex.d.ts +0 -41
  68. package/build/findAllWithRegex.d.ts.map +0 -1
  69. package/build/findAllWithRegex.js +0 -41
  70. package/build/findAllWithRegex.js.map +0 -1
  71. package/build/flattenObject.d.ts +0 -33
  72. package/build/flattenObject.d.ts.map +0 -1
  73. package/build/flattenObject.js +0 -72
  74. package/build/flattenObject.js.map +0 -1
  75. package/build/fromEntries.d.ts +0 -9
  76. package/build/fromEntries.d.ts.map +0 -1
  77. package/build/fromEntries.js +0 -9
  78. package/build/fromEntries.js.map +0 -1
  79. package/build/getEntries.d.ts +0 -8
  80. package/build/getEntries.d.ts.map +0 -1
  81. package/build/getEntries.js +0 -10
  82. package/build/getEntries.js.map +0 -1
  83. package/build/getKeys.d.ts +0 -14
  84. package/build/getKeys.d.ts.map +0 -1
  85. package/build/getKeys.js +0 -19
  86. package/build/getKeys.js.map +0 -1
  87. package/build/getValues.d.ts +0 -9
  88. package/build/getValues.d.ts.map +0 -1
  89. package/build/getValues.js +0 -9
  90. package/build/getValues.js.map +0 -1
  91. package/build/gql.d.ts +0 -22
  92. package/build/gql.d.ts.map +0 -1
  93. package/build/gql.js +0 -32
  94. package/build/gql.js.map +0 -1
  95. package/build/groupBy.d.ts +0 -11
  96. package/build/groupBy.d.ts.map +0 -1
  97. package/build/groupBy.js +0 -20
  98. package/build/groupBy.js.map +0 -1
  99. package/build/index.d.ts +0 -19
  100. package/build/index.d.ts.map +0 -1
  101. package/build/index.js +0 -19
  102. package/build/index.js.map +0 -1
  103. package/build/invert.d.ts +0 -23
  104. package/build/invert.d.ts.map +0 -1
  105. package/build/invert.js +0 -79
  106. package/build/invert.js.map +0 -1
  107. package/build/noExcess.d.ts +0 -33
  108. package/build/noExcess.d.ts.map +0 -1
  109. package/build/noExcess.js +0 -153
  110. package/build/noExcess.js.map +0 -1
  111. package/build/tests/FixedLengthArray.test.d.ts +0 -2
  112. package/build/tests/FixedLengthArray.test.d.ts.map +0 -1
  113. package/build/tests/FixedLengthArray.test.js +0 -15
  114. package/build/tests/FixedLengthArray.test.js.map +0 -1
  115. package/build/tests/aggregateObjects.test.d.ts +0 -2
  116. package/build/tests/aggregateObjects.test.d.ts.map +0 -1
  117. package/build/tests/aggregateObjects.test.js +0 -98
  118. package/build/tests/aggregateObjects.test.js.map +0 -1
  119. package/build/tests/createDefaultCodec.test.d.ts +0 -2
  120. package/build/tests/createDefaultCodec.test.d.ts.map +0 -1
  121. package/build/tests/createDefaultCodec.test.js +0 -104
  122. package/build/tests/createDefaultCodec.test.js.map +0 -1
  123. package/build/tests/decodeCodec.test.d.ts +0 -2
  124. package/build/tests/decodeCodec.test.d.ts.map +0 -1
  125. package/build/tests/decodeCodec.test.js +0 -43
  126. package/build/tests/decodeCodec.test.js.map +0 -1
  127. package/build/tests/enum.test.d.ts +0 -2
  128. package/build/tests/enum.test.d.ts.map +0 -1
  129. package/build/tests/enum.test.js +0 -21
  130. package/build/tests/enum.test.js.map +0 -1
  131. package/build/tests/flattenObject.test.d.ts +0 -2
  132. package/build/tests/flattenObject.test.d.ts.map +0 -1
  133. package/build/tests/flattenObject.test.js +0 -115
  134. package/build/tests/flattenObject.test.js.map +0 -1
  135. package/build/tests/gql.test.d.ts +0 -2
  136. package/build/tests/gql.test.d.ts.map +0 -1
  137. package/build/tests/gql.test.js +0 -44
  138. package/build/tests/gql.test.js.map +0 -1
  139. package/build/tests/groupBy.test.d.ts +0 -2
  140. package/build/tests/groupBy.test.d.ts.map +0 -1
  141. package/build/tests/groupBy.test.js +0 -13
  142. package/build/tests/groupBy.test.js.map +0 -1
  143. package/build/tests/invert.test.d.ts +0 -2
  144. package/build/tests/invert.test.d.ts.map +0 -1
  145. package/build/tests/invert.test.js +0 -50
  146. package/build/tests/invert.test.js.map +0 -1
  147. package/build/tests/noExcess.test.d.ts +0 -2
  148. package/build/tests/noExcess.test.d.ts.map +0 -1
  149. package/build/tests/noExcess.test.js +0 -65
  150. package/build/tests/noExcess.test.js.map +0 -1
  151. package/build/tests/transposeObjectArray.test.d.ts +0 -2
  152. package/build/tests/transposeObjectArray.test.d.ts.map +0 -1
  153. package/build/tests/transposeObjectArray.test.js +0 -155
  154. package/build/tests/transposeObjectArray.test.js.map +0 -1
  155. package/build/transposeObjectArray.d.ts +0 -67
  156. package/build/transposeObjectArray.d.ts.map +0 -1
  157. package/build/transposeObjectArray.js +0 -39
  158. package/build/transposeObjectArray.js.map +0 -1
  159. package/build/tsbuildinfo +0 -1
  160. package/build/types.d.ts +0 -150
  161. package/build/types.d.ts.map +0 -1
  162. package/build/types.js +0 -2
  163. package/build/types.js.map +0 -1
  164. package/build/valuesOf.d.ts +0 -12
  165. package/build/valuesOf.d.ts.map +0 -1
  166. package/build/valuesOf.js +0 -14
  167. package/build/valuesOf.js.map +0 -1
package/dist/index.mjs ADDED
@@ -0,0 +1,529 @@
1
+ import { either, function as function$1 } from "fp-ts";
2
+ import * as t from "io-ts";
3
+ //#region src/enum.ts
4
+ /**
5
+ * Convert a list of strings to an enum-like object.
6
+ */
7
+ function listToEnum(attributes) {
8
+ return attributes.reduce((accumulator, value) => {
9
+ accumulator[value] = value;
10
+ return accumulator;
11
+ }, {});
12
+ }
13
+ /**
14
+ * Merge enum-like inputs into a single enum object.
15
+ */
16
+ function createEnum(...attributes) {
17
+ const objectAttributes = attributes.map((attribute) => Array.isArray(attribute) ? listToEnum(attribute) : attribute);
18
+ return Object.assign({}, ...objectAttributes);
19
+ }
20
+ /**
21
+ * Filter an enum and return the keys that remain.
22
+ */
23
+ function filterEnum(obj, filterFunc) {
24
+ return Object.keys(obj).filter((key) => filterFunc(obj[key], key, obj)).map((key) => key);
25
+ }
26
+ /**
27
+ * Make an enum compatible with type inference without changing its runtime
28
+ * shape.
29
+ */
30
+ function makeEnum(value) {
31
+ return value;
32
+ }
33
+ //#endregion
34
+ //#region src/getKeys.ts
35
+ /**
36
+ * `Object.keys` for string keys only.
37
+ */
38
+ function getStringKeys(obj) {
39
+ return Object.keys(obj).filter((key) => typeof key === "string");
40
+ }
41
+ /**
42
+ * `Object.keys` that preserves key types.
43
+ */
44
+ function getKeys(obj) {
45
+ return Object.keys(obj);
46
+ }
47
+ //#endregion
48
+ //#region src/apply.ts
49
+ /**
50
+ * Apply a function to each value of an object while preserving the key types.
51
+ */
52
+ function apply(obj, applyFunc) {
53
+ return Object.keys(obj).reduce((accumulator, key, index) => Object.assign(accumulator, { [key]: applyFunc(obj[key], key, obj, index) }), {});
54
+ }
55
+ /**
56
+ * Async version of `apply`.
57
+ */
58
+ async function asyncApply(obj, applyFunc) {
59
+ return (await Promise.all(getKeys(obj).map(async (key, index) => ({
60
+ key,
61
+ value: await applyFunc(obj[key], key, obj, index)
62
+ })))).reduce((accumulator, { key, value }) => Object.assign(accumulator, { [key]: value }), {});
63
+ }
64
+ /**
65
+ * Convert a TypeScript enum to a value-to-value map and then call `apply`.
66
+ */
67
+ function applyEnum(enm, applyFunc) {
68
+ return apply(createEnum(Object.values(enm)), applyFunc);
69
+ }
70
+ //#endregion
71
+ //#region src/codecTools/decodeCodec.ts
72
+ /**
73
+ * Determine the codec paths that are invalid.
74
+ */
75
+ function getPaths(validation) {
76
+ return function$1.pipe(validation, either.fold((errors) => errors.map((error) => {
77
+ const lastContext = error.context.at(-1);
78
+ return `${error.context.map(({ key }) => key).join(".")} expected type '${lastContext?.type.name}'`;
79
+ }), () => ["no errors"]));
80
+ }
81
+ /**
82
+ * Get custom error messages for the errors.
83
+ */
84
+ function getCustomErrors(validation, customErrorFromContext) {
85
+ return function$1.pipe(validation, either.fold((errors) => errors.map((error) => customErrorFromContext(error.context)), () => ["no errors"]));
86
+ }
87
+ const CODEC_ERROR_MESSAGE = "Failed to decode codec:";
88
+ /**
89
+ * Decode a codec, returning the decoded value or throwing an error.
90
+ */
91
+ function decodeCodec(codec, txt, parse = true, customErrorFromContext = void 0) {
92
+ const decoded = codec.decode(parse && typeof txt === "string" ? JSON.parse(txt) : txt);
93
+ if (either.isLeft(decoded)) {
94
+ const errorPaths = getPaths(decoded);
95
+ const customError = customErrorFromContext !== void 0 ? JSON.stringify(getCustomErrors(decoded, customErrorFromContext), null, 2) : void 0;
96
+ throw new Error(`${CODEC_ERROR_MESSAGE} ${JSON.stringify(errorPaths, null, 2)}${customError ?? ""}`);
97
+ }
98
+ return decoded.right;
99
+ }
100
+ //#endregion
101
+ //#region src/codecTools/dictionary.ts
102
+ /**
103
+ * Helper to encode/decode a record with partial keys.
104
+ */
105
+ const dictionary = (keys, values, name) => function$1.unsafeCoerce(t.record(t.union([keys, t.undefined]), values, name));
106
+ //#endregion
107
+ //#region src/codecTools/FixedLengthString.ts
108
+ /**
109
+ * Codec for strings constrained to a fixed length.
110
+ */
111
+ const FixedLengthString = (len) => t.brand(t.string, (value) => value.length === len, "FixedLengthString");
112
+ //#endregion
113
+ //#region src/codecTools/FixedLengthArray.ts
114
+ /**
115
+ * Codec for arrays constrained to a fixed length range.
116
+ */
117
+ const FixedLengthArray = (min, max, codec) => t.brand(t.array(codec), (value) => min <= value.length && value.length <= max, "fixedLengthArray");
118
+ //#endregion
119
+ //#region src/codecTools/partialRecord.ts
120
+ /**
121
+ * Create an `io-ts` compatible partial record.
122
+ */
123
+ const partialRecord = (domain, codomain, name) => t.record(t.union([domain, t.undefined]), codomain, name);
124
+ //#endregion
125
+ //#region src/codecTools/isCodecError.ts
126
+ /**
127
+ * Checks an error message to see if it is an `io-ts` codec error.
128
+ */
129
+ function isCodecError(err) {
130
+ return err.message.startsWith("Failed to decode codec");
131
+ }
132
+ //#endregion
133
+ //#region src/codecTools/NonEmptyString.ts
134
+ /**
135
+ * Codec for non-empty trimmed strings.
136
+ */
137
+ const NonEmptyString = t.brand(t.string, (value) => value.trim().length !== 0, "NonEmptyString");
138
+ //#endregion
139
+ //#region src/codecTools/toJsonSchema.ts
140
+ /**
141
+ * Convert an `io-ts` codec to a JSON Schema (v7).
142
+ */
143
+ const toJsonSchema = (rawType, strict = false, alwaysIncludeRequired = false) => {
144
+ const type = rawType;
145
+ if (type._tag === "StringType") return { type: "string" };
146
+ if (type._tag === "NumberType") return { type: "number" };
147
+ if (type._tag === "NullType") return { type: "null" };
148
+ if (type._tag === "BooleanType") return { type: "boolean" };
149
+ if (type._tag === "LiteralType") return { const: type.value };
150
+ if (type._tag === "KeyofType") return {
151
+ type: "string",
152
+ enum: Object.keys(type.keys)
153
+ };
154
+ if (type._tag === "UnionType") return { anyOf: type.types.map((subtype) => toJsonSchema(subtype, strict, alwaysIncludeRequired)) };
155
+ if (type._tag === "IntersectionType" && !alwaysIncludeRequired) return { allOf: type.types.map((subtype) => toJsonSchema(subtype, strict, alwaysIncludeRequired)) };
156
+ if (type._tag === "IntersectionType" && alwaysIncludeRequired) {
157
+ const results = type.types.map((subtype) => toJsonSchema(subtype, strict, alwaysIncludeRequired));
158
+ if (!results.every((result) => result.type === "object")) throw new Error("InterfaceType must have all children as type=object");
159
+ return {
160
+ type: "object",
161
+ required: results.map((result) => result.required).flat(),
162
+ properties: results.reduce((accumulator, result) => ({
163
+ ...accumulator,
164
+ ...result.properties
165
+ }), {}),
166
+ ...strict ? { additionalProperties: false } : {}
167
+ };
168
+ }
169
+ if (type._tag === "InterfaceType") return {
170
+ type: "object",
171
+ required: Object.keys(type.props),
172
+ properties: Object.fromEntries(Object.entries(type.props).map(([key, subtype]) => [key, toJsonSchema(subtype, strict, alwaysIncludeRequired)])),
173
+ ...strict ? { additionalProperties: false } : {}
174
+ };
175
+ if (type._tag === "DictionaryType") return {
176
+ type: "object",
177
+ additionalProperties: toJsonSchema(type.codomain, strict, alwaysIncludeRequired)
178
+ };
179
+ if (type._tag === "PartialType") return {
180
+ type: "object",
181
+ ...alwaysIncludeRequired ? { required: Object.keys(type.props) } : {},
182
+ properties: Object.fromEntries(Object.entries(type.props).map(([key, subtype]) => {
183
+ const result = toJsonSchema(subtype, strict, alwaysIncludeRequired);
184
+ return [key, alwaysIncludeRequired && result.type ? {
185
+ ...result,
186
+ type: [result.type, "null"]
187
+ } : result];
188
+ })),
189
+ ...strict ? { additionalProperties: false } : {}
190
+ };
191
+ if (type._tag === "ArrayType") return {
192
+ type: "array",
193
+ items: toJsonSchema(type.type, strict, alwaysIncludeRequired)
194
+ };
195
+ if (type._tag === "TupleType") return {
196
+ type: "array",
197
+ items: type.types.map((subtype) => toJsonSchema(subtype, strict, alwaysIncludeRequired))
198
+ };
199
+ if (type._tag === "RefinementType") {
200
+ if (type.name === "Int") return { type: "integer" };
201
+ return {
202
+ ...toJsonSchema(type.type, strict, alwaysIncludeRequired),
203
+ description: `Predicate: ${type.predicate.name || type.name}`
204
+ };
205
+ }
206
+ return unhandledType(type);
207
+ };
208
+ const unhandledType = (_shouldBeNever) => ({});
209
+ //#endregion
210
+ //#region src/codecTools/createDefaultCodec.ts
211
+ /**
212
+ * Creates a default value for an `io-ts` codec.
213
+ */
214
+ const createDefaultCodec = (codec) => {
215
+ if (codec instanceof t.UnionType) {
216
+ const arrayType = codec.types.find((type) => type instanceof t.ArrayType);
217
+ if (arrayType) return createDefaultCodec(arrayType);
218
+ const objectType = codec.types.find((type) => type instanceof t.InterfaceType || type instanceof t.PartialType || type instanceof t.IntersectionType || type instanceof t.ArrayType);
219
+ if (objectType) return createDefaultCodec(objectType);
220
+ if (codec.types.some((type) => type instanceof t.NullType || type.name === "null")) return null;
221
+ return createDefaultCodec(codec.types[0]);
222
+ }
223
+ if (codec instanceof t.InterfaceType || codec instanceof t.PartialType) {
224
+ const defaults = {};
225
+ Object.entries(codec.props).forEach(([key, type]) => {
226
+ defaults[key] = createDefaultCodec(type);
227
+ });
228
+ return defaults;
229
+ }
230
+ if (codec instanceof t.IntersectionType) return codec.types.reduce((accumulator, type) => ({
231
+ ...accumulator,
232
+ ...createDefaultCodec(type)
233
+ }), {});
234
+ if (codec instanceof t.ArrayType) {
235
+ const elementType = codec.type;
236
+ return elementType instanceof t.InterfaceType || elementType instanceof t.PartialType || elementType instanceof t.IntersectionType ? [createDefaultCodec(elementType)] : [];
237
+ }
238
+ if (codec instanceof t.LiteralType) return codec.value;
239
+ if (codec instanceof t.ObjectType) return {};
240
+ switch (codec.name) {
241
+ case "string": return "";
242
+ case "number": return 0;
243
+ case "boolean": return false;
244
+ case "null": return null;
245
+ case "undefined": return;
246
+ default: return null;
247
+ }
248
+ };
249
+ //#endregion
250
+ //#region src/enums.ts
251
+ /**
252
+ * The HTTP method types.
253
+ */
254
+ const HttpMethod = makeEnum({
255
+ Get: "GET",
256
+ Post: "POST",
257
+ Delete: "DELETE",
258
+ Put: "PUT",
259
+ Patch: "PATCH"
260
+ });
261
+ //#endregion
262
+ //#region src/getEntries.ts
263
+ /**
264
+ * `Object.entries` that preserves entry types.
265
+ */
266
+ function getEntries(obj) {
267
+ return Object.entries(obj);
268
+ }
269
+ //#endregion
270
+ //#region src/getValues.ts
271
+ /**
272
+ * `Object.values` that preserves value types.
273
+ */
274
+ function getValues(obj) {
275
+ return Object.values(obj);
276
+ }
277
+ //#endregion
278
+ //#region src/groupBy.ts
279
+ /**
280
+ * A typed version of lodash's `groupBy`.
281
+ */
282
+ function groupBy(iterable, getKey) {
283
+ return iterable.reduce((groupedItems, item) => {
284
+ const groupedKey = getKey(item);
285
+ return groupedItems.set(groupedKey, [...groupedItems.get(groupedKey) ?? [], item]);
286
+ }, /* @__PURE__ */ new Map());
287
+ }
288
+ //#endregion
289
+ //#region src/gql.ts
290
+ /**
291
+ * Identify whether a string looks like a GraphQL interface/type/input
292
+ * declaration.
293
+ */
294
+ const INTERFACE_REGEX = /(interface|type|input) [a-zA-Z0-9]* (implements .+?|){([\s\S]+?)}/;
295
+ /**
296
+ * Template tag for GraphQL fragments with a small amount of interpolation
297
+ * support for interface bodies.
298
+ */
299
+ function gql(strings, ...expressions) {
300
+ if (expressions.length === 0) return strings[0];
301
+ const count = strings.length - 1;
302
+ let result = "";
303
+ for (let index = 0; index < count; index += 1) {
304
+ const expression = expressions[index];
305
+ const text = typeof expression === "string" ? expression : expression.toString();
306
+ const useExpression = INTERFACE_REGEX.test(text) ? (INTERFACE_REGEX.exec(text) || [])[3] : expression;
307
+ result += (strings[index] ?? "") + (useExpression ?? "");
308
+ }
309
+ result += strings[count] ?? "";
310
+ return result;
311
+ }
312
+ //#endregion
313
+ //#region src/invert.ts
314
+ /**
315
+ * Invert an object so the values look up the keys. Arrays are expanded and map
316
+ * back to arrays of keys.
317
+ */
318
+ function invert(obj, throwOnDuplicate = true) {
319
+ const result = {};
320
+ getEntries(obj).forEach(([key, instance]) => {
321
+ if (instance === void 0) throw new Error("inverse found undefined value, this is not supported");
322
+ if (Array.isArray(instance)) {
323
+ instance.forEach((listKey) => {
324
+ if (!result[listKey]) result[listKey] = [key];
325
+ else result[listKey].push(key);
326
+ });
327
+ return;
328
+ }
329
+ if (result[instance] && throwOnDuplicate) throw new Error(`Encountered duplicate value inverting object: "${instance}: ${key} and ${result[instance]}"`);
330
+ result[instance] = key;
331
+ });
332
+ return result;
333
+ }
334
+ /**
335
+ * Safely invert an object into `{ [value]: key[] }`.
336
+ */
337
+ function invertSafe(obj) {
338
+ const result = {};
339
+ getEntries(obj).forEach(([key, instance]) => {
340
+ if (instance === void 0) throw new Error("inverse found undefined value, this is not supported");
341
+ if (Array.isArray(instance)) {
342
+ instance.forEach((listKey) => {
343
+ if (!result[listKey]) result[listKey] = [key];
344
+ else result[listKey].push(key);
345
+ });
346
+ return;
347
+ }
348
+ if (!result[instance]) {
349
+ result[instance] = [key];
350
+ return;
351
+ }
352
+ result[instance].push(key);
353
+ });
354
+ return result;
355
+ }
356
+ //#endregion
357
+ //#region src/valuesOf.ts
358
+ /**
359
+ * Build an `io-ts` codec over the values of an enum-like object.
360
+ */
361
+ function valuesOf(enm) {
362
+ return t.keyof(invert(enm));
363
+ }
364
+ //#endregion
365
+ //#region src/findAllWithRegex.ts
366
+ /**
367
+ * Use a regex with the global flag to find all matches and return the list with
368
+ * capture groups mapped to named properties.
369
+ */
370
+ function findAllWithRegex(regex, text) {
371
+ if (!regex.value.flags.includes("g")) throw new Error("Regex.value must have a g flag");
372
+ const matchParams = ["fullMatch", ...regex.matches];
373
+ const results = [];
374
+ let match = regex.value.exec(text);
375
+ let index = 0;
376
+ while (match) {
377
+ if (matchParams.length !== match.length && !regex.skipMatchValidation) throw new Error(`Mismatch in match length at index [${index}]: "${match.length}" vs expected: "${matchParams.length}"`);
378
+ const result = match.reduce((accumulator, matchResult, matchIndex) => Object.assign(accumulator, { [matchParams[matchIndex]]: matchResult }), {});
379
+ result.matchIndex = match.index;
380
+ if (regex.strict) result.isStrict = regex.strict.test(result.fullMatch);
381
+ results.push(result);
382
+ match = regex.value.exec(text);
383
+ index += 1;
384
+ }
385
+ return results;
386
+ }
387
+ //#endregion
388
+ //#region src/aggregateObjects.ts
389
+ /**
390
+ * Aggregates multiple objects into a single object by combining values of
391
+ * matching keys into comma-separated strings.
392
+ */
393
+ const aggregateObjects = ({ objs, wrap = false }) => {
394
+ return Array.from(new Set(objs.flatMap((obj) => obj && typeof obj === "object" ? Object.keys(obj) : []))).reduce((accumulator, key) => {
395
+ accumulator[key] = objs.map((obj) => wrap ? `[${obj?.[key] ?? ""}]` : obj?.[key] ?? "").join(",");
396
+ return accumulator;
397
+ }, {});
398
+ };
399
+ //#endregion
400
+ //#region src/flattenObject.ts
401
+ /**
402
+ * Flattens a nested object into a single-level object with concatenated key
403
+ * names.
404
+ */
405
+ const flattenObject = ({ obj, prefix = "" }) => !obj ? {} : Object.keys(obj ?? []).reduce((accumulator, key) => {
406
+ const newKey = prefix ? `${prefix}_${key}` : key;
407
+ const entry = obj[key];
408
+ if (Array.isArray(entry) && entry.length > 0 && entry.some((item) => typeof item === "object" && item !== null)) {
409
+ const aggregated = aggregateObjects({ objs: entry.filter((item) => typeof item === "object" && item !== null).map((item) => flattenObject({ obj: item })) });
410
+ Object.entries(aggregated).forEach(([aggregatedKey, value]) => {
411
+ accumulator[`${newKey}_${aggregatedKey}`] = value;
412
+ });
413
+ } else if (typeof entry === "object" && entry !== null && !Array.isArray(entry)) Object.assign(accumulator, flattenObject({
414
+ obj: entry,
415
+ prefix: newKey
416
+ }));
417
+ else accumulator[newKey] = Array.isArray(entry) ? entry.map((item) => {
418
+ if (typeof item === "string") return item.replaceAll(",", "");
419
+ return item ?? "";
420
+ }).join(",") : typeof entry === "string" ? entry.replaceAll(",", "") : entry ?? "";
421
+ return accumulator;
422
+ }, {});
423
+ //#endregion
424
+ //#region src/transposeObjectArray.ts
425
+ /**
426
+ * Transpose an array of objects by converting selected properties into arrays
427
+ * while keeping the remaining properties grouped in `rest`.
428
+ */
429
+ const transposeObjectArray = ({ objects, properties, options = { includeOtherProperties: true } }) => objects.reduce((accumulator, item) => {
430
+ const result = { ...accumulator };
431
+ properties.forEach((property) => {
432
+ result[property] = [...accumulator[property] || [], item[property]];
433
+ });
434
+ const restObject = {};
435
+ Object.entries(item).forEach(([key, value]) => {
436
+ if (!properties.includes(key)) restObject[key] = value;
437
+ });
438
+ if (options.includeOtherProperties) result.rest = [...accumulator.rest || [], restObject];
439
+ return result;
440
+ }, {});
441
+ //#endregion
442
+ //#region src/fromEntries.ts
443
+ /**
444
+ * `Object.fromEntries` that preserves entry types.
445
+ */
446
+ function fromEntries(entries) {
447
+ return Object.fromEntries(entries);
448
+ }
449
+ //#endregion
450
+ //#region src/noExcess.ts
451
+ /**
452
+ * Creates a type guard function that checks if a codec matches a specific tag.
453
+ */
454
+ const getIsCodec = (tag) => (codec) => codec._tag === tag;
455
+ const isInterfaceCodec = getIsCodec("InterfaceType");
456
+ const isPartialCodec = getIsCodec("PartialType");
457
+ /**
458
+ * Extract property definitions from various codec types.
459
+ */
460
+ const getProps = (codec) => {
461
+ switch (codec._tag) {
462
+ case "RefinementType":
463
+ case "ReadonlyType": return getProps(codec.type);
464
+ case "InterfaceType":
465
+ case "StrictType":
466
+ case "PartialType": return codec.props;
467
+ case "IntersectionType": return codec.types.reduce((props, type) => Object.assign(props, getProps(type)), {});
468
+ default: return {};
469
+ }
470
+ };
471
+ /**
472
+ * Generate a string representation of props for type naming.
473
+ */
474
+ const getNameFromProps = (props) => Object.keys(props).map((key) => `${key}: ${props[key].name}`).join(", ");
475
+ /**
476
+ * Wrap a type name with `Partial<>`.
477
+ */
478
+ const getPartialTypeName = (inner) => `Partial<${inner}>`;
479
+ /**
480
+ * Generate a human-readable type name for the no-excess wrapper.
481
+ */
482
+ const getNoExcessTypeName = (codec) => {
483
+ if (isInterfaceCodec(codec)) return `{| ${getNameFromProps(codec.props)} |}`;
484
+ if (isPartialCodec(codec)) return getPartialTypeName(`{| ${getNameFromProps(codec.props)} |}`);
485
+ return `Excess<${codec.name}>`;
486
+ };
487
+ /**
488
+ * Compare an object's keys against expected properties and return either the
489
+ * object or a list of excess keys.
490
+ */
491
+ const stripKeys = (obj, props) => {
492
+ const keys = Object.getOwnPropertyNames(obj);
493
+ Object.getOwnPropertyNames(props).forEach((propKey) => {
494
+ const index = keys.indexOf(propKey);
495
+ if (index !== -1) keys.splice(index, 1);
496
+ });
497
+ return keys.length ? either.left(keys) : either.right(obj);
498
+ };
499
+ /**
500
+ * Wrap an `io-ts` codec so validation fails when excess properties are present.
501
+ */
502
+ const noExcess = (codec, name = getNoExcessTypeName(codec)) => {
503
+ const props = getProps(codec);
504
+ return new NoExcessType(name, (value) => either.isRight(stripKeys(value, props)) && codec.is(value), (value, context) => {
505
+ const unknownRecordValidation = t.UnknownRecord.validate(value, context);
506
+ if (either.isLeft(unknownRecordValidation)) return unknownRecordValidation;
507
+ const codecValidation = codec.validate(value, context);
508
+ if (either.isLeft(codecValidation)) return codecValidation;
509
+ return function$1.pipe(stripKeys(codecValidation.right, props), either.mapLeft((keys) => keys.map((key) => ({
510
+ value: codecValidation.right[key],
511
+ context,
512
+ message: `excess key "${key}" found`
513
+ }))));
514
+ }, (value) => codec.encode(stripKeys(value, props).right), codec);
515
+ };
516
+ /**
517
+ * A wrapper type used with `io-ts` to ensure there are not any excess keys.
518
+ */
519
+ var NoExcessType = class extends t.Type {
520
+ _tag = "NoExcessType";
521
+ constructor(name, is, validate, encode, type) {
522
+ super(name, is, validate, encode);
523
+ this.type = type;
524
+ }
525
+ };
526
+ //#endregion
527
+ export { CODEC_ERROR_MESSAGE, FixedLengthArray, FixedLengthString, HttpMethod, INTERFACE_REGEX, NoExcessType, NonEmptyString, aggregateObjects, apply, applyEnum, asyncApply, createDefaultCodec, createEnum, decodeCodec, dictionary, filterEnum, findAllWithRegex, flattenObject, fromEntries, getEntries, getKeys, getStringKeys, getValues, gql, groupBy, invert, invertSafe, isCodecError, listToEnum, makeEnum, noExcess, partialRecord, toJsonSchema, transposeObjectArray, valuesOf };
528
+
529
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["fpFunction","fpFunction","fpFunction"],"sources":["../src/enum.ts","../src/getKeys.ts","../src/apply.ts","../src/codecTools/decodeCodec.ts","../src/codecTools/dictionary.ts","../src/codecTools/FixedLengthString.ts","../src/codecTools/FixedLengthArray.ts","../src/codecTools/partialRecord.ts","../src/codecTools/isCodecError.ts","../src/codecTools/NonEmptyString.ts","../src/codecTools/toJsonSchema.ts","../src/codecTools/createDefaultCodec.ts","../src/enums.ts","../src/getEntries.ts","../src/getValues.ts","../src/groupBy.ts","../src/gql.ts","../src/invert.ts","../src/valuesOf.ts","../src/findAllWithRegex.ts","../src/aggregateObjects.ts","../src/flattenObject.ts","../src/transposeObjectArray.ts","../src/fromEntries.ts","../src/noExcess.ts"],"sourcesContent":["import type { ObjByString } from './types.js';\n\n/**\n * An enumerated value.\n */\nexport type Enumerate<T = string, TKey extends string = string> = {\n [key in TKey]: T;\n};\n\n/**\n * A TypeScript enum with string values.\n */\nexport type TypescriptEnum = { [key in string]: string } | { [key in number]: string };\n\n/**\n * An input when defining an enum can be an object of string -> string or a list\n * of strings.\n */\nexport type EnumInput<T, TKey extends string = string> = Enumerate<T, TKey> | string[];\n\n/**\n * Convert a list of strings to an enum-like object.\n */\nexport function listToEnum(attributes: string[]): Enumerate<string> {\n const initialValue: Enumerate<string> = {};\n return attributes.reduce((accumulator, value) => {\n accumulator[value] = value;\n return accumulator;\n }, initialValue);\n}\n\n/**\n * Merge enum-like inputs into a single enum object.\n */\nexport function createEnum<T = string, TKey extends string = string>(\n ...attributes: EnumInput<T, TKey>[]\n): Enumerate<T, TKey> {\n const objectAttributes = attributes.map((attribute) =>\n Array.isArray(attribute) ? listToEnum(attribute) : attribute,\n );\n\n return Object.assign({}, ...objectAttributes);\n}\n\n/**\n * Filter an enum and return the keys that remain.\n */\nexport function filterEnum<T extends ObjByString>(\n obj: T,\n filterFunc: (value: T[keyof T], key: keyof T, calculatedEnum: Enumerate<T[keyof T]>) => boolean,\n): (keyof T)[] {\n return (Object.keys(obj) as (keyof T)[])\n .filter((key) => filterFunc(obj[key], key, obj))\n .map((key) => key);\n}\n\n/**\n * Make an enum compatible with type inference without changing its runtime\n * shape.\n */\nexport function makeEnum<T extends { [index: string]: Value | Value[] }, Value extends string>(\n value: T,\n): T {\n return value;\n}\n","import type { StringKeys } from './types.js';\n\n/**\n * `Object.keys` for string keys only.\n */\nexport function getStringKeys<T extends object>(obj: T): StringKeys<T>[] {\n return Object.keys(obj).filter((key) => typeof key === 'string') as StringKeys<T>[];\n}\n\n/**\n * `Object.keys` that preserves key types.\n */\nexport function getKeys<T extends object>(obj: T): (keyof T)[] {\n return Object.keys(obj) as (keyof T)[];\n}\n","import { createEnum } from './enum.js';\nimport { getKeys } from './getKeys.js';\nimport type { ObjByString, StringKeys } from './types.js';\n\n/**\n * Apply a function to each value of an object while preserving the key types.\n */\nexport function apply<TInput extends ObjByString, TOutput>(\n obj: TInput,\n applyFunc: (\n value: TInput[keyof TInput],\n key: StringKeys<TInput>,\n fullObj: typeof obj,\n index: number,\n ) => TOutput,\n): { [key in keyof TInput]: TOutput } {\n const result = Object.keys(obj).reduce(\n (accumulator, key, index) =>\n Object.assign(accumulator, {\n [key]: applyFunc(obj[key], key as StringKeys<TInput>, obj, index),\n }),\n {},\n );\n\n return result as { [key in keyof TInput]: TOutput };\n}\n\n/**\n * Async version of `apply`.\n */\nexport async function asyncApply<TInput extends ObjByString, TOutput>(\n obj: TInput,\n applyFunc: (\n value: TInput[keyof TInput],\n key: StringKeys<TInput>,\n fullObj: typeof obj,\n index: number,\n ) => Promise<TOutput>,\n): Promise<{ [key in keyof TInput]: TOutput }> {\n const entries = await Promise.all(\n getKeys(obj).map(async (key, index) => ({\n key,\n value: await applyFunc(obj[key], key as StringKeys<TInput>, obj, index),\n })),\n );\n\n const result = entries.reduce(\n (accumulator, { key, value }) =>\n Object.assign(accumulator, {\n [key]: value,\n }),\n {},\n );\n\n return result as { [key in keyof TInput]: TOutput };\n}\n\n/**\n * Convert a TypeScript enum to a value-to-value map and then call `apply`.\n */\nexport function applyEnum<TEnum extends string, TOutput>(\n enm: { [key in string]: TEnum },\n applyFunc: (value: TEnum, key: TEnum, fullObj: typeof enm, index: number) => TOutput,\n): { [key in TEnum]: TOutput } {\n const obj = createEnum<TEnum, TEnum>(Object.values(enm));\n return apply(obj, applyFunc) as any;\n}\n","import { either, function as fpFunction } from 'fp-ts';\nimport * as t from 'io-ts';\n\n/**\n * Determine the codec paths that are invalid.\n */\nfunction getPaths<A>(validation: t.Validation<A>): string[] {\n return fpFunction.pipe(\n validation,\n either.fold(\n (errors) =>\n errors.map((error) => {\n const lastContext = error.context.at(-1);\n const fullPath = error.context.map(({ key }) => key).join('.');\n return `${fullPath} expected type '${lastContext?.type.name}'`;\n }),\n () => ['no errors'],\n ),\n );\n}\n\n/**\n * Get custom error messages for the errors.\n */\nfunction getCustomErrors<A>(\n validation: t.Validation<A>,\n customErrorFromContext: (validationContext: t.Context) => string,\n): string[] {\n return fpFunction.pipe(\n validation,\n either.fold(\n (errors) => errors.map((error) => customErrorFromContext(error.context)),\n () => ['no errors'],\n ),\n );\n}\n\nexport const CODEC_ERROR_MESSAGE = 'Failed to decode codec:';\n\n/**\n * Decode a codec, returning the decoded value or throwing an error.\n */\nexport function decodeCodec<TCodec extends t.Any>(\n codec: TCodec,\n txt: unknown,\n parse = true,\n customErrorFromContext: ((validationContext: t.Context) => string) | undefined = undefined,\n): t.TypeOf<TCodec> {\n const decoded = codec.decode(parse && typeof txt === 'string' ? JSON.parse(txt) : txt);\n\n if (either.isLeft(decoded)) {\n const errorPaths = getPaths(decoded);\n const customError =\n customErrorFromContext !== undefined\n ? JSON.stringify(getCustomErrors(decoded, customErrorFromContext), null, 2)\n : undefined;\n\n throw new Error(\n `${CODEC_ERROR_MESSAGE} ${JSON.stringify(errorPaths, null, 2)}${customError ?? ''}`,\n );\n }\n\n return decoded.right;\n}\n","import { function as fpFunction } from 'fp-ts';\nimport * as t from 'io-ts';\n\n/**\n * A record with optional keys.\n */\nexport interface DictionaryC<D extends t.Mixed, C extends t.Mixed> extends t.DictionaryType<\n D,\n C,\n {\n [K in t.TypeOf<D>]?: t.TypeOf<C>;\n },\n {\n [K in t.OutputOf<D>]?: t.OutputOf<C>;\n },\n unknown\n> {}\n\n/**\n * Helper to encode/decode a record with partial keys.\n */\nexport const dictionary = <D extends t.Mixed, C extends t.Mixed>(\n keys: D,\n values: C,\n name?: string,\n): DictionaryC<D, C> =>\n fpFunction.unsafeCoerce(t.record(t.union([keys, t.undefined]), values, name));\n","import * as t from 'io-ts';\n\n/**\n * Brand for strings of fixed length.\n */\nexport type FixedLengthStringBrand<N extends number> = {\n /** The expected length of the string. */\n readonly length: N;\n /** Unique symbol to ensure uniqueness of this type across modules/packages. */\n readonly FixedLengthString: unique symbol;\n};\n\n/**\n * Codec for strings constrained to a fixed length.\n */\nexport const FixedLengthString = <N extends number>(\n len: N,\n): t.BrandC<t.StringC, FixedLengthStringBrand<N>> =>\n t.brand(\n t.string,\n (value): value is t.Branded<string, FixedLengthStringBrand<N>> => value.length === len,\n 'FixedLengthString',\n );\n\n/**\n * Branded fixed-length string type.\n */\nexport type FixedLengthString<N extends number> = t.TypeOf<\n t.BrandC<t.StringC, FixedLengthStringBrand<N>>\n>;\n","import * as t from 'io-ts';\n\n/**\n * Brand for arrays with bounded length.\n */\nexport interface FixedLengthArrayBrand<T> extends Array<T> {\n /** Unique symbol to ensure uniqueness of this type across modules/packages. */\n readonly fixedLengthArray: unique symbol;\n /** The minimum length of the array. */\n readonly min: number;\n /** The maximum length of the array. */\n readonly max: number;\n}\n\n/**\n * Codec for arrays constrained to a fixed length range.\n */\nexport const FixedLengthArray = <C extends t.Mixed>(\n min: number,\n max: number,\n codec: C,\n): t.BrandC<t.ArrayC<C>, FixedLengthArrayBrand<C>> =>\n t.brand(\n t.array(codec),\n (value: Array<C>): value is t.Branded<Array<C>, FixedLengthArrayBrand<C>> =>\n min <= value.length && value.length <= max,\n 'fixedLengthArray',\n );\n\n/**\n * Branded fixed-length array type.\n */\nexport type FixedLengthArray<C extends t.Mixed> = t.TypeOf<\n t.BrandC<t.ArrayC<C>, FixedLengthArrayBrand<C>>\n>;\n","import * as t from 'io-ts';\n\n/**\n * Like `t.record`, but where the keys are all optional to include.\n */\nexport interface PartialRecordC<D extends t.Mixed, C extends t.Mixed> extends t.DictionaryType<\n D,\n C,\n {\n [K in t.TypeOf<D>]?: t.TypeOf<C>;\n },\n {\n [K in t.OutputOf<D>]?: t.OutputOf<C>;\n },\n unknown\n> {}\n\n/**\n * Create an `io-ts` compatible partial record.\n */\nexport const partialRecord = <D extends t.Mixed, C extends t.Mixed>(\n domain: D,\n codomain: C,\n name?: string,\n): PartialRecordC<D, C> =>\n t.record(t.union([domain, t.undefined]), codomain, name) as unknown as PartialRecordC<D, C>;\n","/**\n * Checks an error message to see if it is an `io-ts` codec error.\n */\nexport function isCodecError(err: Error): boolean {\n return err.message.startsWith('Failed to decode codec');\n}\n","import * as t from 'io-ts';\n\n/**\n * Brand for non-empty strings.\n */\ntype NonEmptyStringBrand = {\n /** Unique symbol to ensure uniqueness of this type across modules/packages. */\n readonly NonEmptyString: symbol;\n};\n\n/**\n * Codec for non-empty trimmed strings.\n */\nexport const NonEmptyString = t.brand(\n t.string,\n (value): value is t.Branded<string, NonEmptyStringBrand> => value.trim().length !== 0,\n 'NonEmptyString',\n);\n\n/**\n * Branded non-empty string type.\n */\nexport type NonEmptyString = t.TypeOf<typeof NonEmptyString>;\n","import * as t from 'io-ts';\nimport type { JSONSchema7 } from 'json-schema';\n\n/**\n * `io-ts` types compatible with JSON Schema.\n */\ntype MappableType =\n | t.NumberType\n | t.StringType\n | t.NullType\n | t.BooleanType\n | t.LiteralType<any>\n | t.KeyofType<any>\n | t.InterfaceType<any>\n | t.DictionaryType<any, any>\n | t.PartialType<any>\n | t.UnionType<any>\n | t.ArrayType<any>\n | t.TupleType<any>\n | t.IntersectionType<any>\n | t.RefinementType<any>;\n\n/**\n * Convert an `io-ts` codec to a JSON Schema (v7).\n */\nexport const toJsonSchema = (\n rawType: any,\n strict = false,\n alwaysIncludeRequired = false,\n): JSONSchema7 => {\n const type = rawType as MappableType;\n\n if (type._tag === 'StringType') {\n return { type: 'string' };\n }\n\n if (type._tag === 'NumberType') {\n return { type: 'number' };\n }\n\n if (type._tag === 'NullType') {\n return { type: 'null' };\n }\n\n if (type._tag === 'BooleanType') {\n return { type: 'boolean' };\n }\n\n if (type._tag === 'LiteralType') {\n return { const: type.value };\n }\n\n if (type._tag === 'KeyofType') {\n return { type: 'string', enum: Object.keys(type.keys) };\n }\n\n if (type._tag === 'UnionType') {\n return {\n anyOf: type.types.map((subtype: any) => toJsonSchema(subtype, strict, alwaysIncludeRequired)),\n };\n }\n\n if (type._tag === 'IntersectionType' && !alwaysIncludeRequired) {\n return {\n allOf: type.types.map((subtype: any) => toJsonSchema(subtype, strict, alwaysIncludeRequired)),\n };\n }\n\n if (type._tag === 'IntersectionType' && alwaysIncludeRequired) {\n const results = type.types.map((subtype: any) =>\n toJsonSchema(subtype, strict, alwaysIncludeRequired),\n );\n\n if (!results.every((result: any) => result.type === 'object')) {\n throw new Error('InterfaceType must have all children as type=object');\n }\n\n return {\n type: 'object',\n required: results.map((result: any) => result.required).flat(),\n properties: results.reduce(\n (accumulator: any, result: any) => ({ ...accumulator, ...result.properties }),\n {},\n ),\n ...(strict ? { additionalProperties: false } : {}),\n };\n }\n\n if (type._tag === 'InterfaceType') {\n return {\n type: 'object',\n required: Object.keys(type.props),\n properties: Object.fromEntries(\n Object.entries(type.props).map(([key, subtype]) => [\n key,\n toJsonSchema(subtype as t.Type<any>, strict, alwaysIncludeRequired),\n ]),\n ),\n ...(strict ? { additionalProperties: false } : {}),\n };\n }\n\n if (type._tag === 'DictionaryType') {\n return {\n type: 'object',\n additionalProperties: toJsonSchema(type.codomain, strict, alwaysIncludeRequired),\n };\n }\n\n if (type._tag === 'PartialType') {\n return {\n type: 'object',\n ...(alwaysIncludeRequired ? { required: Object.keys(type.props) } : {}),\n properties: Object.fromEntries(\n Object.entries(type.props).map(([key, subtype]) => {\n const result = toJsonSchema(subtype as t.Type<any>, strict, alwaysIncludeRequired);\n return [\n key,\n alwaysIncludeRequired && result.type\n ? {\n ...result,\n type: [result.type as any, 'null'],\n }\n : result,\n ];\n }),\n ),\n ...(strict ? { additionalProperties: false } : {}),\n };\n }\n\n if (type._tag === 'ArrayType') {\n return {\n type: 'array',\n items: toJsonSchema(type.type, strict, alwaysIncludeRequired),\n };\n }\n\n if (type._tag === 'TupleType') {\n return {\n type: 'array',\n items: type.types.map((subtype: any) => toJsonSchema(subtype, strict, alwaysIncludeRequired)),\n };\n }\n\n if (type._tag === 'RefinementType') {\n if (type.name === 'Int') {\n return { type: 'integer' };\n }\n\n return {\n ...toJsonSchema(type.type, strict, alwaysIncludeRequired),\n description: `Predicate: ${type.predicate.name || type.name}`,\n };\n }\n\n return unhandledType(type as never);\n};\n\nconst unhandledType = (_shouldBeNever: never) => ({});\n","import * as t from 'io-ts';\n\n/**\n * Creates a default value for an `io-ts` codec.\n */\nexport const createDefaultCodec = <C extends t.Mixed>(codec: C): t.TypeOf<C> => {\n if (codec instanceof t.UnionType) {\n const arrayType = codec.types.find((type: any) => type instanceof t.ArrayType);\n if (arrayType) {\n return createDefaultCodec(arrayType);\n }\n\n const objectType = codec.types.find(\n (type: any) =>\n type instanceof t.InterfaceType ||\n type instanceof t.PartialType ||\n type instanceof t.IntersectionType ||\n type instanceof t.ArrayType,\n );\n if (objectType) {\n return createDefaultCodec(objectType);\n }\n\n const hasNull = codec.types.some(\n (type: any) => type instanceof t.NullType || type.name === 'null',\n );\n if (hasNull) {\n return null as t.TypeOf<C>;\n }\n\n return createDefaultCodec(codec.types[0]);\n }\n\n if (codec instanceof t.InterfaceType || codec instanceof t.PartialType) {\n const defaults: Record<string, any> = {};\n Object.entries(codec.props).forEach(([key, type]) => {\n defaults[key] = createDefaultCodec(type as any);\n });\n return defaults as t.TypeOf<C>;\n }\n\n if (codec instanceof t.IntersectionType) {\n return codec.types.reduce(\n (accumulator: t.TypeOf<C>, type: any) => ({\n ...accumulator,\n ...createDefaultCodec(type),\n }),\n {},\n );\n }\n\n if (codec instanceof t.ArrayType) {\n const elementType = codec.type;\n const isObjectType =\n elementType instanceof t.InterfaceType ||\n elementType instanceof t.PartialType ||\n elementType instanceof t.IntersectionType;\n\n return (isObjectType ? [createDefaultCodec(elementType)] : []) as t.TypeOf<C>;\n }\n\n if (codec instanceof t.LiteralType) {\n return codec.value as t.TypeOf<C>;\n }\n\n if (codec instanceof t.ObjectType) {\n return {} as t.TypeOf<C>;\n }\n\n switch (codec.name) {\n case 'string':\n return '' as t.TypeOf<C>;\n case 'number':\n return 0 as t.TypeOf<C>;\n case 'boolean':\n return false as t.TypeOf<C>;\n case 'null':\n return null as t.TypeOf<C>;\n case 'undefined':\n return undefined as t.TypeOf<C>;\n default:\n return null as t.TypeOf<C>;\n }\n};\n","import { makeEnum } from './enum.js';\n\n/**\n * The HTTP method types.\n */\nexport const HttpMethod = makeEnum({\n /** A GET request. */\n Get: 'GET',\n /** A POST request. */\n Post: 'POST',\n /** A DELETE request. */\n Delete: 'DELETE',\n /** A PUT request. */\n Put: 'PUT',\n /** A PATCH request. */\n Patch: 'PATCH',\n});\n\n/**\n * The HTTP method string union.\n */\nexport type HttpMethod = (typeof HttpMethod)[keyof typeof HttpMethod];\n","import type { ObjByString } from './types.js';\n\n/**\n * `Object.entries` that preserves entry types.\n */\nexport function getEntries<TKey extends keyof TObj, TObj extends ObjByString>(\n obj: TObj,\n): [TKey, TObj[TKey]][] {\n return Object.entries(obj) as any;\n}\n","/**\n * `Object.values` that preserves value types.\n */\nexport function getValues<TValue>(obj: {\n [key in string | number | symbol]: TValue;\n}): TValue[] {\n return Object.values(obj) as TValue[];\n}\n","/**\n * A typed version of lodash's `groupBy`.\n */\nexport function groupBy<TItem, TKey>(\n iterable: TItem[],\n getKey: (item: TItem) => TKey,\n): Map<TKey, TItem[]> {\n return iterable.reduce((groupedItems, item) => {\n const groupedKey = getKey(item);\n return groupedItems.set(groupedKey, [...(groupedItems.get(groupedKey) ?? []), item]);\n }, new Map<TKey, TItem[]>());\n}\n","/**\n * Identify whether a string looks like a GraphQL interface/type/input\n * declaration.\n */\nexport const INTERFACE_REGEX = /(interface|type|input) [a-zA-Z0-9]* (implements .+?|){([\\s\\S]+?)}/;\n\n/**\n * A `gql` is simply a string branded with the associated GraphQL type.\n */\nexport type Gql<TGraphQLType extends object> = string & {\n /** The TypeScript type definition that relates to the gql string. */\n graphQLType: TGraphQLType;\n};\n\n/**\n * Template tag for GraphQL fragments with a small amount of interpolation\n * support for interface bodies.\n */\nexport function gql<TGraphQLType extends object>(\n strings: TemplateStringsArray,\n ...expressions: (string | number)[]\n): Gql<TGraphQLType> {\n if (expressions.length === 0) {\n return strings[0] as Gql<TGraphQLType>;\n }\n\n const count = strings.length - 1;\n let result = '';\n for (let index = 0; index < count; index += 1) {\n const expression = expressions[index]!;\n const text = typeof expression === 'string' ? expression : expression.toString();\n const useExpression = INTERFACE_REGEX.test(text)\n ? (INTERFACE_REGEX.exec(text) || [])[3]\n : expression;\n result += (strings[index] ?? '') + (useExpression ?? '');\n }\n\n result += strings[count] ?? '';\n return result as Gql<TGraphQLType>;\n}\n","import { getEntries } from './getEntries.js';\n\n/**\n * Invert an object so the values look up the keys. Arrays are expanded and map\n * back to arrays of keys.\n */\nexport function invert<TKey extends string, TValue extends string | string[]>(\n obj: { [key in TKey]?: TValue },\n throwOnDuplicate = true,\n): {\n [key in TValue extends (infer Item)[] ? Item : TValue]: TValue extends any[] ? TKey[] : TKey;\n} {\n const result: any = {};\n\n getEntries(obj).forEach(([key, instance]: [TKey, TValue | undefined]) => {\n if (instance === undefined) {\n throw new Error('inverse found undefined value, this is not supported');\n }\n\n if (Array.isArray(instance)) {\n instance.forEach((listKey) => {\n if (!result[listKey]) {\n result[listKey] = [key];\n } else {\n result[listKey].push(key);\n }\n });\n return;\n }\n\n if (result[instance] && throwOnDuplicate) {\n throw new Error(\n `Encountered duplicate value inverting object: \"${instance}: ${key} and ${result[instance]}\"`,\n );\n }\n\n result[instance] = key;\n });\n\n return result;\n}\n\n/**\n * Safely invert an object into `{ [value]: key[] }`.\n */\nexport function invertSafe<TKey extends string, TValue extends string>(obj: {\n [key in TKey]: TValue | TValue[];\n}): {\n [key in TValue]: TKey[];\n} {\n const result: any = {};\n\n getEntries(obj).forEach(([key, instance]) => {\n if (instance === undefined) {\n throw new Error('inverse found undefined value, this is not supported');\n }\n\n if (Array.isArray(instance)) {\n instance.forEach((listKey) => {\n if (!result[listKey]) {\n result[listKey] = [key];\n } else {\n result[listKey].push(key);\n }\n });\n return;\n }\n\n if (!result[instance]) {\n result[instance] = [key];\n return;\n }\n\n result[instance].push(key);\n });\n\n return result;\n}\n","import * as t from 'io-ts';\n\nimport { invert } from './invert.js';\n\n/**\n * Build an `io-ts` codec over the values of an enum-like object.\n */\nexport function valuesOf<TEnum extends string>(enm: {\n [key in string]: TEnum;\n}): t.KeyofC<{ [key in TEnum]: unknown }> {\n return t.keyof(invert(enm) as any);\n}\n","/**\n * The full match returned when `regex.exec` finds a match.\n */\nexport interface RegExpMatch {\n /** The full regex match. */\n fullMatch: string;\n /** The index in the text where the match was found. */\n matchIndex: number;\n /** Whether the match satisfies an optional stricter regex. */\n isStrict?: boolean;\n}\n\n/**\n * Definition for finding all regex matches and mapping capture groups to keys.\n */\nexport interface FindAllRegExp<TMatchKeys extends string> {\n /** The regex to test. */\n value: RegExp;\n /**\n * A stricter regex used to annotate matches that satisfy a more exact\n * standard.\n */\n strict?: RegExp;\n /** Capture group names mapped by index. */\n matches: readonly TMatchKeys[];\n /** When true, skip validation of matches being the expected length. */\n skipMatchValidation?: boolean;\n}\n\n/**\n * Use a regex with the global flag to find all matches and return the list with\n * capture groups mapped to named properties.\n */\nexport function findAllWithRegex<TMatchKeys extends string>(\n regex: FindAllRegExp<TMatchKeys>,\n text: string,\n): ({ [key in TMatchKeys]: string } & RegExpMatch)[] {\n if (!regex.value.flags.includes('g')) {\n throw new Error('Regex.value must have a g flag');\n }\n\n const matchParams = ['fullMatch', ...regex.matches];\n const results: ({ [key in TMatchKeys]: string } & RegExpMatch)[] = [];\n\n let match = regex.value.exec(text);\n let index = 0;\n\n while (match) {\n if (matchParams.length !== match.length && !regex.skipMatchValidation) {\n throw new Error(\n `Mismatch in match length at index [${index}]: \"${match.length}\" vs expected: \"${matchParams.length}\"`,\n );\n }\n\n const result = match.reduce(\n (accumulator, matchResult, matchIndex) =>\n Object.assign(accumulator, {\n [matchParams[matchIndex] as string]: matchResult,\n }),\n {},\n ) as { [key in TMatchKeys]: string } & RegExpMatch;\n\n result.matchIndex = match.index;\n\n if (regex.strict) {\n result.isStrict = regex.strict.test(result.fullMatch);\n }\n\n results.push(result);\n\n match = regex.value.exec(text);\n index += 1;\n }\n\n return results;\n}\n","/**\n * Aggregates multiple objects into a single object by combining values of\n * matching keys into comma-separated strings.\n */\nexport const aggregateObjects = ({\n objs,\n wrap = false,\n}: {\n /** The objects to aggregate in a single one. */\n objs: any[];\n /** Whether to wrap the concatenated values in `[]`. */\n wrap?: boolean;\n}): any => {\n const allKeys = Array.from(\n new Set(objs.flatMap((obj) => (obj && typeof obj === 'object' ? Object.keys(obj) : []))),\n );\n\n return allKeys.reduce(\n (accumulator, key) => {\n const values = objs\n .map((obj) => (wrap ? `[${obj?.[key] ?? ''}]` : (obj?.[key] ?? '')))\n .join(',');\n accumulator[key] = values;\n return accumulator;\n },\n {} as Record<string, any>,\n );\n};\n","import { aggregateObjects } from './aggregateObjects.js';\n\n/**\n * Flattens a nested object into a single-level object with concatenated key\n * names.\n */\nexport const flattenObject = ({\n obj,\n prefix = '',\n}: {\n /** The object to flatten. */\n obj: any;\n /** The prefix to prepend to keys while recursing. */\n prefix?: string;\n}): any =>\n !obj\n ? {}\n : Object.keys(obj ?? []).reduce(\n (accumulator, key) => {\n const newKey = prefix ? `${prefix}_${key}` : key;\n const entry = obj[key];\n\n if (\n Array.isArray(entry) &&\n entry.length > 0 &&\n entry.some((item) => typeof item === 'object' && item !== null)\n ) {\n const objectEntries = entry.filter((item) => typeof item === 'object' && item !== null);\n const flattenedObjects = objectEntries.map((item) => flattenObject({ obj: item }));\n const aggregated = aggregateObjects({ objs: flattenedObjects });\n Object.entries(aggregated).forEach(([aggregatedKey, value]) => {\n accumulator[`${newKey}_${aggregatedKey}`] = value;\n });\n } else if (typeof entry === 'object' && entry !== null && !Array.isArray(entry)) {\n Object.assign(accumulator, flattenObject({ obj: entry, prefix: newKey }));\n } else {\n accumulator[newKey] = Array.isArray(entry)\n ? entry\n .map((item) => {\n if (typeof item === 'string') {\n return item.replaceAll(',', '');\n }\n\n return item ?? '';\n })\n .join(',')\n : typeof entry === 'string'\n ? entry.replaceAll(',', '')\n : (entry ?? '');\n }\n\n return accumulator;\n },\n {} as Record<string, any>,\n );\n","/**\n * Type representing a transposed array of objects.\n */\ntype TransposedObjectArray<T, K extends keyof T> = {\n [P in K]: Array<T[P]>;\n} & {\n /** Properties not selected for transposition. */\n rest: Array<Omit<T, K>>;\n};\n\n/**\n * Transpose an array of objects by converting selected properties into arrays\n * while keeping the remaining properties grouped in `rest`.\n */\nexport const transposeObjectArray = <T extends object, K extends keyof T>({\n objects,\n properties,\n options = { includeOtherProperties: true },\n}: {\n /** Array of objects to transpose. */\n objects: T[];\n /** Property keys to transpose into arrays. */\n properties: K[];\n /** Options for how to transpose the array. */\n options?: {\n /** Whether to include non-transposed properties in the final result. */\n includeOtherProperties?: boolean;\n };\n}): TransposedObjectArray<T, K> =>\n objects.reduce(\n (accumulator, item) => {\n const result = { ...accumulator } as TransposedObjectArray<T, K>;\n\n properties.forEach((property) => {\n const currentArray = (accumulator[property] || []) as T[K][];\n result[property] = [...currentArray, item[property]] as any;\n });\n\n const restObject = {} as Omit<T, K>;\n Object.entries(item).forEach(([key, value]) => {\n if (!properties.includes(key as K)) {\n (restObject as any)[key] = value;\n }\n });\n\n if (options.includeOtherProperties) {\n result.rest = [...(accumulator.rest || []), restObject];\n }\n\n return result;\n },\n {} as TransposedObjectArray<T, K>,\n );\n","/**\n * `Object.fromEntries` that preserves entry types.\n */\nexport function fromEntries<const TEntries extends ReadonlyArray<readonly [PropertyKey, unknown]>>(\n entries: TEntries,\n): { [K in TEntries[number] as K[0]]: K[1] } {\n return Object.fromEntries(entries) as { [K in TEntries[number] as K[0]]: K[1] };\n}\n","import { either, function as fpFunction } from 'fp-ts';\nimport * as t from 'io-ts';\n\n/**\n * Creates a type guard function that checks if a codec matches a specific tag.\n */\nconst getIsCodec =\n <T extends t.Any>(tag: string) =>\n (codec: t.Any): codec is T =>\n (codec as any)._tag === tag;\n\nconst isInterfaceCodec = getIsCodec<t.InterfaceType<t.Props>>('InterfaceType');\nconst isPartialCodec = getIsCodec<t.PartialType<t.Props>>('PartialType');\n\n/**\n * Extract property definitions from various codec types.\n */\nconst getProps = (codec: t.HasProps): t.Props => {\n switch (codec._tag) {\n case 'RefinementType':\n case 'ReadonlyType':\n return getProps(codec.type);\n case 'InterfaceType':\n case 'StrictType':\n case 'PartialType':\n return codec.props;\n case 'IntersectionType':\n return codec.types.reduce<t.Props>((props, type) => Object.assign(props, getProps(type)), {});\n default:\n return {};\n }\n};\n\n/**\n * Generate a string representation of props for type naming.\n */\nconst getNameFromProps = (props: t.Props): string =>\n Object.keys(props)\n .map((key) => `${key}: ${props[key]!.name}`)\n .join(', ');\n\n/**\n * Wrap a type name with `Partial<>`.\n */\nconst getPartialTypeName = (inner: string): string => `Partial<${inner}>`;\n\n/**\n * Generate a human-readable type name for the no-excess wrapper.\n */\nconst getNoExcessTypeName = (codec: t.Any): string => {\n if (isInterfaceCodec(codec)) {\n return `{| ${getNameFromProps(codec.props)} |}`;\n }\n\n if (isPartialCodec(codec)) {\n return getPartialTypeName(`{| ${getNameFromProps(codec.props)} |}`);\n }\n\n return `Excess<${codec.name}>`;\n};\n\n/**\n * Compare an object's keys against expected properties and return either the\n * object or a list of excess keys.\n */\nconst stripKeys = <T = any>(obj: T, props: t.Props): either.Either<string[], T> => {\n const keys = Object.getOwnPropertyNames(obj);\n const propKeys = Object.getOwnPropertyNames(props);\n\n propKeys.forEach((propKey) => {\n const index = keys.indexOf(propKey);\n if (index !== -1) {\n keys.splice(index, 1);\n }\n });\n\n return keys.length ? either.left(keys) : either.right(obj);\n};\n\n/**\n * Wrap an `io-ts` codec so validation fails when excess properties are present.\n */\nexport const noExcess = <C extends t.HasProps>(\n codec: C,\n name: string = getNoExcessTypeName(codec),\n): NoExcessType<C> => {\n const props: t.Props = getProps(codec);\n\n return new NoExcessType<C>(\n name,\n (value): value is C => either.isRight(stripKeys(value, props)) && codec.is(value),\n (value, context) => {\n const unknownRecordValidation = t.UnknownRecord.validate(value, context);\n if (either.isLeft(unknownRecordValidation)) {\n return unknownRecordValidation;\n }\n\n const codecValidation = codec.validate(value, context);\n if (either.isLeft(codecValidation)) {\n return codecValidation;\n }\n\n return fpFunction.pipe(\n stripKeys<C>(codecValidation.right, props),\n either.mapLeft((keys) =>\n keys.map((key) => ({\n value: codecValidation.right[key],\n context,\n message: `excess key \"${key}\" found`,\n })),\n ),\n );\n },\n (value) => codec.encode((stripKeys(value, props) as either.Right<any>).right),\n codec,\n );\n};\n\n/**\n * A wrapper type used with `io-ts` to ensure there are not any excess keys.\n */\nexport class NoExcessType<C extends t.Any, A = C['_A'], O = A, I = unknown> extends t.Type<\n A,\n O,\n I\n> {\n public readonly _tag = 'NoExcessType' as const;\n\n public constructor(\n name: string,\n is: NoExcessType<C, A, O, I>['is'],\n validate: NoExcessType<C, A, O, I>['validate'],\n encode: NoExcessType<C, A, O, I>['encode'],\n public readonly type: C,\n ) {\n super(name, is, validate, encode);\n }\n}\n"],"mappings":"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"}