typeshi 2.1.3 → 2.1.5

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.
@@ -24,24 +24,35 @@ export declare class Restrict {
24
24
  static toPicked: typeof picked;
25
25
  }
26
26
  /**
27
- * **`values`** are either:
28
- * - a `function` where only need to pass in single value to get the transformed value `T[K]`
29
- * - an object with two props: `transform` & `args` where `args` is the array of arguments
30
- * passed into `transform` using the spread operator.
27
+ * define a `TransformationSchema<T, S>` to use in `sanitizeAndMap`, where entries from
28
+ * a `source` object `S` are mapped to a new object `T`
29
+ *
30
+ * `values` are either:
31
+ * 1. a `function` where only need to pass in `source[K]` to get the transformed value `T[K]`
32
+ * 2. {@link TransformOptions}, an object with props:
33
+ * - `sourceKey (keyof S, optional)` - indicates that should transform `source[sourceKey]` to `T[K]`.
34
+ * `sourceKey = TransformOptions.sourceKey ?? K`
35
+ * - `transform (function, optional)` - `function` that uses `source[sourceKey]` & `args` to compute `T[K]`
36
+ * - `args (any[], optional)` - the array of arguments passed into `transform` using the spread operator, i.e. `transform(source[sourceKey], ...args)`
37
+ * - `defaultValue (T[K], optional)` - assign this value to `K` **only when** `transform` is `undefined`
38
+ * and `source[sourceKey]` is `undefined`
31
39
  */
32
- export type TransformationSchema<T> = {
33
- [K in keyof T]?: ((val: any) => T[K]) | {
34
- transform: (val: any, ...args: any[]) => T[K];
35
- args: any[];
36
- };
40
+ export type TransformationSchema<T extends object, S extends Record<keyof any, unknown> = any> = {
41
+ [K in keyof T]?: ((val: S[keyof S]) => T[K]) | TransformOptions<T, K, S>;
42
+ };
43
+ export type TransformOptions<T extends object, K extends keyof T, S extends Record<keyof any, unknown> = any> = {
44
+ transform?: (val: S[keyof S], ...args: any[]) => T[K];
45
+ args?: any[];
46
+ defaultValue?: T[K];
47
+ sourceKey?: keyof S;
37
48
  };
38
49
  /**
39
- * @param obj `any` - source object (e.g., Request Body)
40
- * @param schema {@link TransformationSchema}`<T>` - map of keys to transformation functions
41
- * @param passThroughKeys `(keyof T)[]` - keys to move over without transformation (Identity mapping)
50
+ * @param obj `S` - source object (e.g., Request Body)
51
+ * @param schema {@link TransformationSchema}`<T, S>` - map of keys to transformation functions.
52
+ * @param passThroughKeys `(keyof T)[] (optional)` - keys to move over without transformation (Identity mapping)
42
53
  * @returns **`data`** `T` - new object with keys/values from generated from `schema` & `passThroughKeys`
43
54
  */
44
- export declare function sanitizeAndMap<T extends object>(obj: any, schema: TransformationSchema<T>, passThroughKeys?: (keyof T)[]): T;
55
+ export declare function sanitizeAndMap<T extends object, S extends Record<keyof any, unknown> = any>(obj: S, schema: TransformationSchema<T, S>, passThroughKeys?: (keyof T)[]): T;
45
56
  /**
46
57
  * @returns `Object.prototype.hasOwnProperty.call(obj, key) && obj[key] !== undefined;`
47
58
  */
@@ -42,23 +42,31 @@ Restrict.keys = hasValidKeysOnly;
42
42
  */
43
43
  Restrict.toPicked = picked;
44
44
  /**
45
- * @param obj `any` - source object (e.g., Request Body)
46
- * @param schema {@link TransformationSchema}`<T>` - map of keys to transformation functions
47
- * @param passThroughKeys `(keyof T)[]` - keys to move over without transformation (Identity mapping)
45
+ * @param obj `S` - source object (e.g., Request Body)
46
+ * @param schema {@link TransformationSchema}`<T, S>` - map of keys to transformation functions.
47
+ * @param passThroughKeys `(keyof T)[] (optional)` - keys to move over without transformation (Identity mapping)
48
48
  * @returns **`data`** `T` - new object with keys/values from generated from `schema` & `passThroughKeys`
49
49
  */
50
50
  function sanitizeAndMap(obj, schema, passThroughKeys = []) {
51
51
  const data = {};
52
52
  // 1. Handle explicit transformations
53
53
  for (const key in schema) {
54
- if (schema[key] && hasDefinedEntry(obj, key)) {
55
- if ((0, typeValidation_1.isFunction)(schema[key])) {
56
- data[key] = schema[key](obj[key]);
54
+ const schemaValue = schema[key];
55
+ if (!schemaValue)
56
+ continue;
57
+ const sourceKey = 'sourceKey' in schemaValue && schemaValue.sourceKey ? schemaValue.sourceKey : key;
58
+ if (hasDefinedEntry(obj, sourceKey)) {
59
+ if ((0, typeValidation_1.isFunction)(schemaValue)) { // schemaValue is ((val: S[keyof S]) => T[K])
60
+ data[key] = schemaValue(obj[sourceKey]);
57
61
  }
58
- else {
59
- data[key] = schema[key].transform(obj[key], ...schema[key].args);
62
+ else if ((0, typeValidation_1.isFunction)(schemaValue.transform)) { // schemaValue is { transform?: (val: S[keyof S], ...args: any[]) => T[K]; args?: any[]; sourceKey?: keyof S}
63
+ data[key] = schemaValue.transform(obj[sourceKey], ...(schemaValue.args ?? []));
60
64
  }
61
65
  }
66
+ else if (!(0, typeValidation_1.isFunction)(schemaValue) && 'defaultValue' in schemaValue) {
67
+ // `obj[K]` is `undefined`, can apply defaultValue
68
+ data[key] = schemaValue.defaultValue;
69
+ }
62
70
  }
63
71
  // 2. Handle simple pass-throughs (Identity mapping)
64
72
  for (const key of passThroughKeys) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typeshi",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "description": "TypeScript utility modules",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",