@empathyco/x-adapter 8.0.0-alpha.8 → 8.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 (36) hide show
  1. package/README.md +683 -5
  2. package/dist/cjs/http-clients/fetch.http-client.js +2 -2
  3. package/dist/cjs/http-clients/fetch.http-client.js.map +1 -1
  4. package/dist/cjs/mappers/schema-mapper.factory.js +3 -4
  5. package/dist/cjs/mappers/schema-mapper.factory.js.map +1 -1
  6. package/dist/cjs/schemas/types.js.map +1 -1
  7. package/dist/cjs/schemas/utils.js +7 -5
  8. package/dist/cjs/schemas/utils.js.map +1 -1
  9. package/dist/cjs/utils/index.js +0 -1
  10. package/dist/cjs/utils/index.js.map +1 -1
  11. package/dist/cjs/utils/interpolate.js +3 -3
  12. package/dist/cjs/utils/interpolate.js.map +1 -1
  13. package/dist/esm/http-clients/fetch.http-client.js +3 -3
  14. package/dist/esm/http-clients/fetch.http-client.js.map +1 -1
  15. package/dist/esm/mappers/schema-mapper.factory.js +4 -5
  16. package/dist/esm/mappers/schema-mapper.factory.js.map +1 -1
  17. package/dist/esm/schemas/types.js.map +1 -1
  18. package/dist/esm/schemas/utils.js +7 -5
  19. package/dist/esm/schemas/utils.js.map +1 -1
  20. package/dist/esm/utils/index.js +0 -1
  21. package/dist/esm/utils/index.js.map +1 -1
  22. package/dist/esm/utils/interpolate.js +3 -3
  23. package/dist/esm/utils/interpolate.js.map +1 -1
  24. package/dist/types/endpoint-adapter/types.d.ts +1 -1
  25. package/dist/types/http-clients/types.d.ts +1 -1
  26. package/dist/types/mappers/schema-mapper.factory.d.ts +2 -2
  27. package/dist/types/mappers/types.d.ts +1 -1
  28. package/dist/types/schemas/types.d.ts +14 -12
  29. package/dist/types/schemas/utils.d.ts +1 -1
  30. package/dist/types/utils/index.d.ts +0 -1
  31. package/package.json +18 -14
  32. package/dist/cjs/utils/extract-value.js +0 -28
  33. package/dist/cjs/utils/extract-value.js.map +0 -1
  34. package/dist/esm/utils/extract-value.js +0 -24
  35. package/dist/esm/utils/extract-value.js.map +0 -1
  36. package/dist/types/utils/extract-value.d.ts +0 -12
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/fetch.http-client.ts"],"names":[],"mappings":";;;AAAA,gDAA4D;AAE5D,mCAA2C;AAE3C;;;;;;;;;GASG;AACI,MAAM,eAAe,GAAe,CACzC,QAAQ,EACR,EAAE,EAAE,GAAG,QAAQ,EAAE,UAAU,GAAG,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,UAAU,EAAE,gBAAgB,GAAG,KAAK,EAAE,GAAG,EAAE,EAChG,EAAE;IACF,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,cAAc,GAAG,IAAA,oBAAU,EAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAA,gBAAQ,EAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAC7E,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpF,OAAO,KAAK,CAAC,GAAG,EAAE;QAChB,GAAG,UAAU;QACb,GAAG,cAAc;QACjB,GAAG,MAAM;KACV,CAAC,CAAC,IAAI,CAAC,cAAM,CAAC,CAAC;AAClB,CAAC,CAAC;AAdW,QAAA,eAAe,mBAc1B;AAEF;;GAEG;AACH,MAAM,uBAAuB,GAAgC,EAAE,CAAC;AAEhE;;;;;;;GAOG;AACH,SAAS,yBAAyB,CAAC,EAAU;;IAC3C,MAAA,uBAAuB,CAAC,EAAE,CAAC,0CAAE,KAAK,EAAE,CAAC;IACrC,uBAAuB,CAAC,EAAE,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;IACpD,OAAO,uBAAuB,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AAC5C,CAAC","sourcesContent":["import { Dictionary, flatObject } from '@empathyco/x-utils';\nimport { HttpClient } from './types';\nimport { buildUrl, toJson } from './utils';\n\n/**\n * The `fetchHttpClient()` function is a http client implementation using the `fetch` WebAPI.\n *\n * @param endpoint - The endpoint to make the request to.\n * @param options - The request options.\n *\n * @returns A `Promise` object.\n *\n * @public\n */\nexport const fetchHttpClient: HttpClient = (\n endpoint,\n { id = endpoint, cancelable = true, parameters = {}, properties, sendParamsInBody = false } = {}\n) => {\n const signal = cancelable ? { signal: abortAndGetNewAbortSignal(id) } : {};\n const flatParameters = flatObject(parameters);\n const url = sendParamsInBody ? endpoint : buildUrl(endpoint, flatParameters);\n const bodyParameters = sendParamsInBody ? { body: JSON.stringify(parameters) } : {};\n\n return fetch(url, {\n ...properties,\n ...bodyParameters,\n ...signal\n }).then(toJson);\n};\n\n/**\n * Dictionary with the request id as key and an `AbortController` as value.\n */\nconst requestAbortControllers: Dictionary<AbortController> = {};\n\n/**\n * Function that cancels previous request with the same `id` and returns a new `AbortSignal` for\n * the new request.\n *\n * @param id - The identifier of the request to cancel and create a new `AbortSignal`.\n *\n * @returns The new `AbortSignal`.\n */\nfunction abortAndGetNewAbortSignal(id: string): AbortSignal {\n requestAbortControllers[id]?.abort();\n requestAbortControllers[id] = new AbortController();\n return requestAbortControllers[id].signal;\n}\n"]}
1
+ {"version":3,"file":"fetch.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/fetch.http-client.ts"],"names":[],"mappings":";;;AAAA,gDAAwE;AAExE,mCAA2C;AAE3C;;;;;;;;;GASG;AACI,MAAM,eAAe,GAAe,CACzC,QAAQ,EACR,EAAE,EAAE,GAAG,QAAQ,EAAE,UAAU,GAAG,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,UAAU,EAAE,gBAAgB,GAAG,KAAK,EAAE,GAAG,EAAE,EAChG,EAAE;IACF,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,cAAc,GAAG,IAAA,oBAAU,EAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAA,gBAAQ,EAAC,QAAQ,EAAE,IAAA,oBAAU,EAAC,cAAc,CAAC,CAAC,CAAC;IACzF,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAA,oBAAU,EAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhG,OAAO,KAAK,CAAC,GAAG,EAAE;QAChB,GAAG,UAAU;QACb,GAAG,cAAc;QACjB,GAAG,MAAM;KACV,CAAC,CAAC,IAAI,CAAC,cAAM,CAAC,CAAC;AAClB,CAAC,CAAC;AAdW,QAAA,eAAe,mBAc1B;AAEF;;GAEG;AACH,MAAM,uBAAuB,GAAgC,EAAE,CAAC;AAEhE;;;;;;;GAOG;AACH,SAAS,yBAAyB,CAAC,EAAU;;IAC3C,MAAA,uBAAuB,CAAC,EAAE,CAAC,0CAAE,KAAK,EAAE,CAAC;IACrC,uBAAuB,CAAC,EAAE,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;IACpD,OAAO,uBAAuB,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AAC5C,CAAC","sourcesContent":["import { Dictionary, cleanEmpty, flatObject } from '@empathyco/x-utils';\nimport { HttpClient } from './types';\nimport { buildUrl, toJson } from './utils';\n\n/**\n * The `fetchHttpClient()` function is a http client implementation using the `fetch` WebAPI.\n *\n * @param endpoint - The endpoint to make the request to.\n * @param options - The request options.\n *\n * @returns A `Promise` object.\n *\n * @public\n */\nexport const fetchHttpClient: HttpClient = (\n endpoint,\n { id = endpoint, cancelable = true, parameters = {}, properties, sendParamsInBody = false } = {}\n) => {\n const signal = cancelable ? { signal: abortAndGetNewAbortSignal(id) } : {};\n const flatParameters = flatObject(parameters);\n const url = sendParamsInBody ? endpoint : buildUrl(endpoint, cleanEmpty(flatParameters));\n const bodyParameters = sendParamsInBody ? { body: JSON.stringify(cleanEmpty(parameters)) } : {};\n\n return fetch(url, {\n ...properties,\n ...bodyParameters,\n ...signal\n }).then(toJson);\n};\n\n/**\n * Dictionary with the request id as key and an `AbortController` as value.\n */\nconst requestAbortControllers: Dictionary<AbortController> = {};\n\n/**\n * Function that cancels previous request with the same `id` and returns a new `AbortSignal` for\n * the new request.\n *\n * @param id - The identifier of the request to cancel and create a new `AbortSignal`.\n *\n * @returns The new `AbortSignal`.\n */\nfunction abortAndGetNewAbortSignal(id: string): AbortSignal {\n requestAbortControllers[id]?.abort();\n requestAbortControllers[id] = new AbortController();\n return requestAbortControllers[id].signal;\n}\n"]}
@@ -4,7 +4,6 @@ exports.schemaMapperFactory = void 0;
4
4
  const x_deep_merge_1 = require("@empathyco/x-deep-merge");
5
5
  const x_utils_1 = require("@empathyco/x-utils");
6
6
  const utils_1 = require("../schemas/utils");
7
- const extract_value_1 = require("../utils/extract-value");
8
7
  /**
9
8
  * The 'schemaMapperFactory' function creates a {@link Mapper | mapper function} for a given
10
9
  * {@link Schema | schema}.
@@ -37,7 +36,7 @@ function mapSchema(source, schema, context) {
37
36
  }
38
37
  return (0, x_utils_1.reduce)(schema, (target, key, transformer) => {
39
38
  if (typeof transformer === 'string' && (0, x_utils_1.isPath)(source, transformer)) {
40
- target[key] = (0, extract_value_1.extractValue)(source, transformer);
39
+ target[key] = (0, x_utils_1.getSafePropertyChain)(source, transformer);
41
40
  }
42
41
  else if ((0, x_utils_1.isFunction)(transformer) && !(0, utils_1.isInternalMethod)(transformer.name)) {
43
42
  target[key] = transformer(source, context);
@@ -69,7 +68,7 @@ function mapSchema(source, schema, context) {
69
68
  * @internal
70
69
  */
71
70
  function applySubSchemaTransformer(source, { $subSchema, $path, $context }, rawContext, schema) {
72
- const subSource = (0, extract_value_1.extractValue)(source, $path);
71
+ const subSource = (0, x_utils_1.getSafePropertyChain)(source, $path);
73
72
  if (!subSource) {
74
73
  return;
75
74
  }
@@ -81,7 +80,7 @@ function applySubSchemaTransformer(source, { $subSchema, $path, $context }, rawC
81
80
  }
82
81
  extendedContext[key] = (0, x_utils_1.isFunction)(value)
83
82
  ? value(source)
84
- : (0, extract_value_1.extractValue)(source, value);
83
+ : (0, x_utils_1.getSafePropertyChain)(source, value);
85
84
  });
86
85
  }
87
86
  const context = (0, x_deep_merge_1.deepMerge)({}, rawContext, $context, extendedContext);
@@ -1 +1 @@
1
- {"version":3,"file":"schema-mapper.factory.js","sourceRoot":"","sources":["../../../src/mappers/schema-mapper.factory.ts"],"names":[],"mappings":";;;AAAA,0DAAoD;AACpD,gDAQ4B;AAE5B,4CAAyE;AACzE,0DAAsD;AAGtD;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CACjC,MAA8B;IAE9B,OAAO,SAAS,MAAM,CAAC,MAAc,EAAE,OAAsB;QAC3D,OAAO,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC;AAND,kDAMC;AAED;;;;;;;;;GASG;AACH,SAAS,SAAS,CAChB,MAAc,EACd,MAA8B,EAC9B,OAAsB;IAEtB,IAAI,CAAC,MAAM,EAAE;QACX,qCAAqC;QACrC,OAAO,CAAC,IAAI,CAAC,+BAA+B,EAAE,IAAA,2BAAmB,EAAC,MAAM,CAAC,CAAC,CAAC;QAC3E,OAAO,SAAgB,CAAC;KACzB;IACD,OAAO,IAAA,gBAAM,EACX,MAAM,EACN,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE;QAE3B,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,IAAA,gBAAM,EAAC,MAAM,EAAE,WAAW,CAAC,EAAE;YAClE,MAAM,CAAC,GAAG,CAAC,GAAG,IAAA,4BAAY,EAAC,MAAM,EAAE,WAAW,CAAc,CAAC;SAC9D;aAAM,IAAI,IAAA,oBAAU,EAAC,WAAW,CAAC,IAAI,CAAC,IAAA,wBAAgB,EAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YACzE,MAAM,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SAC5C;aAAM,IAAI,IAAA,kBAAQ,EAAC,WAAW,CAAC,EAAE;YAChC,MAAM,KAAK,GACT,YAAY,IAAI,WAAW;gBACzB,CAAC,CAAE,yBAAyB,CACxB,MAAM,EACN,WAAsD,EACtD,OAAO,EACP,MAA8C,CACjC;gBACjB,CAAC,CAAC,SAAS,CAAoB,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;YAEjE,IAAI,KAAK,EAAE;gBACT,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;aACrB;SACF;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,EACD,EAAY,CACb,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,yBAAyB,CAChC,MAAc,EACd,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAwC,EACrE,UAAyB,EACzB,MAA8B;IAE9B,MAAM,SAAS,GAAG,IAAA,4BAAY,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAE9C,IAAI,CAAC,SAAS,EAAE;QACd,OAAO;KACR;IAED,MAAM,eAAe,GAAe,EAAE,CAAC;IACvC,IAAI,QAAQ,EAAE;QACZ,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YAChD,IAAI,CAAC,mBAAmB,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;gBAClE,OAAO;aACR;YACD,eAAe,CAAC,GAAG,CAAC,GAAG,IAAA,oBAAU,EAAC,KAAK,CAAC;gBACtC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;gBACf,CAAC,CAAC,IAAA,4BAAY,EAAC,MAAM,EAAE,KAAmC,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;KACJ;IAED,MAAM,OAAO,GAAG,IAAA,wBAAS,EAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;IACrE,IAAI,SAA4C,CAAC;IACjD,IAAI,UAAU,KAAK,OAAO,EAAE;QAC1B,SAAS,GAAG,MAAM,CAAC;KACpB;SAAM,IAAI,IAAA,oBAAU,EAAC,UAAU,CAAC,EAAE;QACjC,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;KAChC;SAAM;QACL,SAAS,GAAG,UAAU,CAAC;KACxB;IACD,OAAO,IAAA,iBAAO,EAAC,SAAS,CAAC;QACvB,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAW,CAAC;QACtE,CAAC,CAAC,SAAS,CACP,SAAS,EACT,SAA6C,EAC7C,OAAO,CACR,CAAC;AACR,CAAC","sourcesContent":["import { deepMerge } from '@empathyco/x-deep-merge';\nimport {\n Dictionary,\n ExtractPath,\n isArray,\n isFunction,\n isObject,\n isPath,\n reduce\n} from '@empathyco/x-utils';\nimport { Schema, SubSchemaTransformer } from '../schemas/types';\nimport { createMutableSchema, isInternalMethod } from '../schemas/utils';\nimport { extractValue } from '../utils/extract-value';\nimport { Mapper, MapperContext } from './types';\n\n/**\n * The 'schemaMapperFactory' function creates a {@link Mapper | mapper function} for a given\n * {@link Schema | schema}.\n *\n * @param schema - The {@link Schema | schema} to apply in the {@link Mapper | mapper function}.\n * @returns A {@link Mapper | mapper function} that applies the given {@link Schema | schema}.\n * @public\n */\nexport function schemaMapperFactory<Source, Target>(\n schema: Schema<Source, Target>\n): Mapper<Source, Target> {\n return function mapper(source: Source, context: MapperContext): Target {\n return mapSchema(source, schema, context);\n };\n}\n\n/**\n * The `mapSchema()` function creates a new object populated with the transformations defined by a\n * {@link Schema} applied to a source object.\n *\n * @param source - The object to apply the transformations to.\n * @param schema - The object that defines the transformations to apply.\n * @param context - The {@link MapperContext | mapper context} to feed the transformations with.\n * @returns A new object with each element being the result of the applied transformation.\n * @internal\n */\nfunction mapSchema<Source, Target>(\n source: Source,\n schema: Schema<Source, Target>,\n context: MapperContext\n): Target {\n if (!source) {\n //eslint-disable-next-line no-console\n console.warn('This schema cannot be applied', createMutableSchema(schema));\n return undefined as any;\n }\n return reduce(\n schema,\n (target, key, transformer) => {\n type TargetKey = Target[keyof Target];\n if (typeof transformer === 'string' && isPath(source, transformer)) {\n target[key] = extractValue(source, transformer) as TargetKey;\n } else if (isFunction(transformer) && !isInternalMethod(transformer.name)) {\n target[key] = transformer(source, context);\n } else if (isObject(transformer)) {\n const value =\n '$subSchema' in transformer\n ? (applySubSchemaTransformer<Source, TargetKey>(\n source,\n transformer as SubSchemaTransformer<Source, TargetKey>,\n context,\n schema as unknown as Schema<Source, TargetKey>\n ) as TargetKey)\n : mapSchema<Source, TargetKey>(source, transformer, context);\n\n if (value) {\n target[key] = value;\n }\n }\n return target;\n },\n {} as Target\n );\n}\n\n/**\n * The `applySubSchemaTransformer()` function executes a `mapSchema()` function applying the defined\n * {@link SubSchemaTransformer.$subSchema}.\n *\n * @param source - The object to feed the schema.\n * @param subSchemaTransformer - The {@link SubSchemaTransformer} object with a $path, $subSchema\n * and $context options.\n * @param subSchemaTransformer.$path\n * @param subSchemaTransformer.$subSchema\n * @param rawContext - The {@link MapperContext | mapper context} to feed the mapSchema function.\n * @param subSchemaTransformer.$context\n * @param schema - The {@link Schema} to apply.\n * @returns The result of calling `mapSchema()` with the source, schema and context arguments.\n * @internal\n */\nfunction applySubSchemaTransformer<Source, Target>(\n source: Source,\n { $subSchema, $path, $context }: SubSchemaTransformer<Source, Target>,\n rawContext: MapperContext,\n schema: Schema<Source, Target>\n): Target | Target[] | undefined {\n const subSource = extractValue(source, $path);\n\n if (!subSource) {\n return;\n }\n\n const extendedContext: Dictionary = {};\n if ($context) {\n Object.entries($context).forEach(([key, value]) => {\n if (['requestParameters', 'endpoint', 'mappedValue'].includes(key)) {\n return;\n }\n extendedContext[key] = isFunction(value)\n ? value(source)\n : extractValue(source, value as ExtractPath<typeof source>);\n });\n }\n\n const context = deepMerge({}, rawContext, $context, extendedContext);\n let subSchema: typeof $subSchema | typeof schema;\n if ($subSchema === '$self') {\n subSchema = schema;\n } else if (isFunction($subSchema)) {\n subSchema = $subSchema(source);\n } else {\n subSchema = $subSchema;\n }\n return isArray(subSource)\n ? subSource.map(item => mapSchema(item, subSchema, context) as Target)\n : mapSchema<typeof subSource, Target>(\n subSource,\n subSchema as Schema<typeof subSource, Target>,\n context\n );\n}\n"]}
1
+ {"version":3,"file":"schema-mapper.factory.js","sourceRoot":"","sources":["../../../src/mappers/schema-mapper.factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { deepMerge } from '@empathyco/x-deep-merge';\nimport {\n Dictionary,\n ExtractPath,\n getSafePropertyChain,\n isArray,\n isFunction,\n isObject,\n isPath,\n reduce\n} from '@empathyco/x-utils';\nimport { MutableSchema, Schema, SubSchemaTransformer } from '../schemas/types';\nimport { createMutableSchema, isInternalMethod } from '../schemas/utils';\nimport { Mapper, MapperContext } from './types';\n\n/**\n * The 'schemaMapperFactory' function creates a {@link Mapper | mapper function} for a given\n * {@link Schema | schema}.\n *\n * @param schema - The {@link Schema | schema} to apply in the {@link Mapper | mapper function}.\n * @returns A {@link Mapper | mapper function} that applies the given {@link Schema | schema}.\n * @public\n */\nexport function schemaMapperFactory<Source, Target>(\n schema: Schema<Source, Target> | MutableSchema<Source, Target>\n): Mapper<Source, Target> {\n return function mapper(source: Source, context: MapperContext): Target {\n return mapSchema(source, schema, context);\n };\n}\n\n/**\n * The `mapSchema()` function creates a new object populated with the transformations defined by a\n * {@link Schema} applied to a source object.\n *\n * @param source - The object to apply the transformations to.\n * @param schema - The object that defines the transformations to apply.\n * @param context - The {@link MapperContext | mapper context} to feed the transformations with.\n * @returns A new object with each element being the result of the applied transformation.\n * @internal\n */\nfunction mapSchema<Source, Target>(\n source: Source,\n schema: Schema<Source, Target>,\n context: MapperContext\n): Target {\n if (!source) {\n //eslint-disable-next-line no-console\n console.warn('This schema cannot be applied', createMutableSchema(schema));\n return undefined as any;\n }\n return reduce(\n schema,\n (target, key, transformer) => {\n type TargetKey = Target[keyof Target];\n if (typeof transformer === 'string' && isPath(source, transformer)) {\n target[key] = getSafePropertyChain(source, transformer) as TargetKey;\n } else if (isFunction(transformer) && !isInternalMethod(transformer.name)) {\n target[key] = transformer(source, context);\n } else if (isObject(transformer)) {\n const value =\n '$subSchema' in transformer\n ? (applySubSchemaTransformer<Source, TargetKey>(\n source,\n transformer as SubSchemaTransformer<Source, TargetKey>,\n context,\n schema as unknown as Schema<Source, TargetKey>\n ) as TargetKey)\n : mapSchema<Source, TargetKey>(source, transformer, context);\n\n if (value) {\n target[key] = value;\n }\n }\n return target;\n },\n {} as Target\n );\n}\n\n/**\n * The `applySubSchemaTransformer()` function executes a `mapSchema()` function applying the defined\n * {@link SubSchemaTransformer.$subSchema}.\n *\n * @param source - The object to feed the schema.\n * @param subSchemaTransformer - The {@link SubSchemaTransformer} object with a $path, $subSchema\n * and $context options.\n * @param subSchemaTransformer.$path\n * @param subSchemaTransformer.$subSchema\n * @param rawContext - The {@link MapperContext | mapper context} to feed the mapSchema function.\n * @param subSchemaTransformer.$context\n * @param schema - The {@link Schema} to apply.\n * @returns The result of calling `mapSchema()` with the source, schema and context arguments.\n * @internal\n */\nfunction applySubSchemaTransformer<Source, Target>(\n source: Source,\n { $subSchema, $path, $context }: SubSchemaTransformer<Source, Target>,\n rawContext: MapperContext,\n schema: Schema<Source, Target>\n): Target | Target[] | undefined {\n const subSource = getSafePropertyChain(source, $path);\n\n if (!subSource) {\n return;\n }\n\n const extendedContext: Dictionary = {};\n if ($context) {\n Object.entries($context).forEach(([key, value]) => {\n if (['requestParameters', 'endpoint', 'mappedValue'].includes(key)) {\n return;\n }\n extendedContext[key] = isFunction(value)\n ? value(source)\n : getSafePropertyChain(source, value as ExtractPath<typeof source>);\n });\n }\n\n const context = deepMerge({}, rawContext, $context, extendedContext);\n let subSchema: typeof $subSchema | typeof schema;\n if ($subSchema === '$self') {\n subSchema = schema;\n } else if (isFunction($subSchema)) {\n subSchema = $subSchema(source);\n } else {\n subSchema = $subSchema;\n }\n return isArray(subSource)\n ? subSource.map(item => mapSchema(item, subSchema, context) as Target)\n : mapSchema<typeof subSource, Target>(\n subSource,\n subSchema as Schema<typeof subSource, Target>,\n context\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/schemas/types.ts"],"names":[],"mappings":"","sourcesContent":["import {\n AnyFunction,\n ExtractPath,\n ExtractPathByType,\n ExtractType,\n Primitive\n} from '@empathyco/x-utils';\nimport { MapperContext } from '../mappers/types';\n\n// TODO: EX-5830 - Enhance Schema type to support optional properties in the Source object\n/**\n * Template object to transform a source object to a target object.\n *\n * @remarks The source object must not have optional properties, as it could cause infinite\n * type instantiations.\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * price: {\n * max: number;\n * min: number;\n * };\n * images: string[];\n * }\n *\n * interface Target {\n * identifier: string;\n * maxPrice: number;\n * minPrice: number;\n * img: string[]\n * }\n *\n * const schema: Schema<Source, Target> = {\n * identifier: 'id',\n * maxPrice: 'price.max',\n * minPrice: ({ price }) => Math.min(0, price.min),\n * img: 'images'\n * };\n * ```\n * @public\n */\nexport type Schema<Source = any, Target = any> = {\n [TargetKey in keyof Target]: SchemaTransformer<Source, Target, TargetKey>;\n};\n\n/**\n * A {@link Schema | schema} with extended functionality to: completely replace\n * the original schema, partially override it or create a new one.\n *\n * @param OriginalSchema - The {@link Schema | schema} that will be mutable.\n * @public\n */\nexport type MutableSchema<OriginalSchema extends Schema> = OriginalSchema & {\n /**\n * Replaces all usages of the original {@link Schema | schema} with the given one.\n *\n * @param newSchema - The {@link Schema | schema} to use instead of the original one.\n * @returns The new {@link Schema | schema} that will be used.\n */\n $replace: <Source, Target>(\n newSchema: Schema<Source, Target>\n ) => MutableSchema<Schema<Source, Target>>;\n /**\n * Merges the original {@link Schema | schema} with the given one.\n *\n * @param newSchema - The {@link Schema | schema} to use to merge with the original one.\n * @returns The {@link Schema | schema} returned by the merge.\n */\n $override: <Source, Target>(\n newSchema: Schema<Source, Target>\n ) => MutableSchema<Schema<Source, Target>>;\n /**\n * Creates a new {@link Schema | schema} using the original one as starting point.\n * The original {@link Schema | schema} will remain unchanged.\n *\n * @param newSchema - The {@link Schema | schema} to be used to extend the original one.\n * @returns The {@link Schema | schema} created.\n */\n $extends: <Source, Target>(\n newSchema: Schema<Source, Target>\n ) => MutableSchema<Schema<Source, Target>>;\n /**\n * Returns a string representing of the {@link Schema | schema}.\n *\n * @param includeInternalMethods - Flag to include in the string representation\n * the internal methods. Disabled by default.\n * @returns The string representation.\n */\n toString: (includeInternalMethods?: boolean) => string;\n};\n\n/**\n * The possible transformers to apply to the target key.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @param TargetKey - The target key to apply the transformation.\n * @public\n */\nexport type SchemaTransformer<Source, Target, TargetKey extends keyof Target> =\n | PathTransformer<Source, Target[TargetKey]>\n | FunctionTransformer<Source, Target[TargetKey]>\n | SubSchemaTransformer<Source, Target[TargetKey]>\n | Schema<Source, Exclude<Target[TargetKey], AnyFunction | Primitive>>;\n\n/**\n * A function with the source object and mapper context as parameters that returns the value of a\n * target's property.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * count: number;\n * }\n *\n * interface Target {\n * title: string;\n * hits: number;\n * }\n *\n * const subSchema: Schema<Source, Target> = {\n * title: 'id',\n * hits: 'count'\n * };\n *\n * const wrongSubSchema: Schema<Source, Target> = {\n * // @ts-expect-error\n * title: 'count', // This raises a TS error\n * hits: 'count'\n * };\n * ```\n * @public\n */\nexport type PathTransformer<Source, Target> = ExtractPathByType<Source, Target>;\n\n/**\n * A function with the source object and mapper context as parameters that returns the value of a\n * target's property.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * count: number;\n * }\n *\n * interface Target {\n * title: string;\n * hits: number;\n * }\n *\n * const subSchema: Schema<Source, Target> = {\n * title: source => source.id,\n * hits: (source, context) => context.requestParameters.query === 'example'\n * ? source.count\n * : 0\n * };\n * ```\n * @public\n */\nexport type FunctionTransformer<Source, Target> = (\n source: Source,\n context?: MapperContext\n) => Target;\n\n/**\n * An object containing a schema narrowing its source object based on the given path.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * facets: {\n * name: string;\n * count: number;\n * };\n * images: string[];\n * }\n *\n * interface Target {\n * identifier: string;\n * filters: {\n * id: string;\n * numFound: number;\n * };\n * img: string[]\n * }\n *\n * const subSchema: SubSchemaTransformer<Source, Target['filters']> = {\n * $path: 'facets',\n * $subSchema: {\n * id: 'name',\n * numFound: 'count'\n * }\n * };\n * ```\n * @public\n */\nexport type SubSchemaTransformer<Source, Target> = {\n [Path in ExtractPath<Source>]: {\n $context?: MapperContext;\n $path: Path;\n $subSchema:\n | SubSchema<Source, Target, Path>\n | '$self'\n | ((source: Source) => SubSchema<Source, Target, Path>);\n };\n}[ExtractPath<Source>];\n\n/**\n * A {@link Schema | schema} that will be applied to an inner path of an object.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @param Path - The path where the schema will be applied.\n * @public\n */\nexport type SubSchema<Source, Target, Path extends ExtractPath<Source>> = ExtractType<\n Source,\n Path\n> extends (infer SourceArrayType)[]\n ? Target extends (infer TargetArrayType)[]\n ? Schema<SourceArrayType, TargetArrayType>\n : never\n : Target extends []\n ? never\n : Schema<ExtractType<Source, Path>, Target>;\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/schemas/types.ts"],"names":[],"mappings":"","sourcesContent":["import {\n AnyFunction,\n DeepPartial,\n ExtractPath,\n ExtractPathByType,\n ExtractType,\n Primitive\n} from '@empathyco/x-utils';\nimport { MapperContext } from '../mappers/types';\n\n// TODO: EX-5830 - Enhance Schema type to support optional properties in the Source object\n/**\n * Template object to transform a source object to a target object.\n *\n * @remarks The source object must not have optional properties, as it could cause infinite\n * type instantiations.\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * price: {\n * max: number;\n * min: number;\n * };\n * images: string[];\n * }\n *\n * interface Target {\n * identifier: string;\n * maxPrice: number;\n * minPrice: number;\n * img: string[]\n * }\n *\n * const schema: Schema<Source, Target> = {\n * identifier: 'id',\n * maxPrice: 'price.max',\n * minPrice: ({ price }) => Math.min(0, price.min),\n * img: 'images'\n * };\n * ```\n * @public\n */\nexport type Schema<Source = any, Target = any> = {\n [TargetKey in keyof Target]: SchemaTransformer<Source, Target, TargetKey>;\n};\n\n/**\n * A {@link Schema | schema} with extended functionality to: completely replace\n * the original schema, partially override it or create a new one.\n *\n * @param OriginalSchema - The {@link Schema | schema} that will be mutable.\n * @public\n */\nexport type MutableSchema<Source, Target> = Schema<Source, Target> & {\n /**\n * Replaces all usages of the original {@link Schema | schema} with the given one.\n *\n * @param newSchema - The {@link Schema | schema} to use instead of the original one.\n * @returns The new {@link Schema | schema} that will be used.\n */\n $replace<NewSource, NewTarget>(\n newSchema: Schema<NewSource, NewTarget>\n ): MutableSchema<NewSource, NewTarget>;\n /**\n * Merges the original {@link Schema | schema} with the given one.\n *\n * @param newSchema - The {@link Schema | schema} to use to merge with the original one.\n * @returns The {@link Schema | schema} returned by the merge.\n */\n // eslint-disable-next-line @typescript-eslint/ban-types\n $override<NewSource, NewTarget = {}>(\n newSchema: DeepPartial<Schema<Source & NewSource, Target>> &\n Schema<Source & NewSource, NewTarget>\n ): MutableSchema<Source & NewSource, Target & NewTarget>;\n /**\n * Creates a new {@link Schema | schema} using the original one as starting point.\n * The original {@link Schema | schema} will remain unchanged.\n *\n * @param newSchema - The {@link Schema | schema} to be used to extend the original one.\n * Both schema's Target and Source can be unique or also be extending from another one.\n * @returns The {@link Schema | schema} created.\n */\n $extends<NewSource extends Source, NewTarget extends Target>(\n newSchema: DeepPartial<Schema<Source & NewSource, Target>> &\n Schema<Source & NewSource, Omit<NewTarget, keyof Target>>\n ): MutableSchema<Source & NewSource, Target & NewTarget>;\n // eslint-disable-next-line @typescript-eslint/ban-types\n $extends<NewSource, NewTarget = {}>(\n newSchema: DeepPartial<Schema<Source & NewSource, Target>> &\n Schema<Source & NewSource, NewTarget>\n ): MutableSchema<Source & NewSource, Target & NewTarget>;\n /**\n * Returns a string representing of the {@link Schema | schema}.\n *\n * @param includeInternalMethods - Flag to include in the string representation\n * the internal methods. Disabled by default.\n * @returns The string representation.\n */\n toString(includeInternalMethods?: boolean): string;\n};\n/**\n * The possible transformers to apply to the target key.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @param TargetKey - The target key to apply the transformation.\n * @public\n */\nexport type SchemaTransformer<Source, Target, TargetKey extends keyof Target> =\n | PathTransformer<Source, Target[TargetKey]>\n | FunctionTransformer<Source, Target[TargetKey]>\n | SubSchemaTransformer<Source, Target[TargetKey]>\n | Schema<Source, Exclude<Target[TargetKey], AnyFunction | Primitive>>;\n\n/**\n * A function with the source object and mapper context as parameters that returns the value of a\n * target's property.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * count: number;\n * }\n *\n * interface Target {\n * title: string;\n * hits: number;\n * }\n *\n * const subSchema: Schema<Source, Target> = {\n * title: 'id',\n * hits: 'count'\n * };\n *\n * const wrongSubSchema: Schema<Source, Target> = {\n * // @ts-expect-error\n * title: 'count', // This raises a TS error\n * hits: 'count'\n * };\n * ```\n * @public\n */\nexport type PathTransformer<Source, Target> = ExtractPathByType<Source, Target>;\n\n/**\n * A function with the source object and mapper context as parameters that returns the value of a\n * target's property.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * count: number;\n * }\n *\n * interface Target {\n * title: string;\n * hits: number;\n * }\n *\n * const subSchema: Schema<Source, Target> = {\n * title: source => source.id,\n * hits: (source, context) => context.requestParameters.query === 'example'\n * ? source.count\n * : 0\n * };\n * ```\n * @public\n */\nexport type FunctionTransformer<Source, Target> = (\n source: Source,\n context?: MapperContext\n) => Target;\n\n/**\n * An object containing a schema narrowing its source object based on the given path.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * facets: {\n * name: string;\n * count: number;\n * };\n * images: string[];\n * }\n *\n * interface Target {\n * identifier: string;\n * filters: {\n * id: string;\n * numFound: number;\n * };\n * img: string[]\n * }\n *\n * const subSchema: SubSchemaTransformer<Source, Target['filters']> = {\n * $path: 'facets',\n * $subSchema: {\n * id: 'name',\n * numFound: 'count'\n * }\n * };\n * ```\n * @public\n */\nexport type SubSchemaTransformer<Source, Target> = {\n [Path in ExtractPath<Source>]: {\n $context?: MapperContext;\n $path: Path;\n $subSchema:\n | SubSchema<Source, Target, Path>\n | '$self'\n | ((source: Source) => SubSchema<Source, Target, Path>);\n };\n}[ExtractPath<Source>];\n\n/**\n * A {@link Schema | schema} that will be applied to an inner path of an object.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @param Path - The path where the schema will be applied.\n * @public\n */\nexport type SubSchema<Source, Target, Path extends ExtractPath<Source>> = ExtractType<\n Source,\n Path\n> extends (infer SourceArrayType)[]\n ? Target extends (infer TargetArrayType)[]\n ? Schema<SourceArrayType, TargetArrayType>\n : never\n : Target extends []\n ? never\n : Schema<ExtractType<Source, Path>, Target>;\n"]}
@@ -19,23 +19,25 @@ const mutableSchemasInternalMethods = ['$replace', '$override', '$extends', 'toS
19
19
  function createMutableSchema(schema) {
20
20
  return {
21
21
  ...schema,
22
- $replace: function (newSchema) {
23
- Object.keys(this).forEach(key => {
22
+ $replace(newSchema) {
23
+ (0, x_utils_1.forEach)(this, key => {
24
24
  if (isInternalMethod(key)) {
25
25
  return;
26
26
  }
27
27
  delete this[key];
28
28
  });
29
29
  Object.assign(this, newSchema);
30
+ /* We are replacing the schema with a completely new schema , so it makes sense that TS
31
+ complains that the old schema and the new one are not the same. */
30
32
  return this;
31
33
  },
32
- $override: function (newSchema) {
34
+ $override(newSchema) {
33
35
  return (0, x_deep_merge_1.deepMerge)(this, newSchema);
34
36
  },
35
- $extends: function (newSchema) {
37
+ $extends(newSchema) {
36
38
  return (0, x_deep_merge_1.deepMerge)({}, this, newSchema);
37
39
  },
38
- toString: function (includeInternalMethods = false) {
40
+ toString(includeInternalMethods = false) {
39
41
  return serialize(this, !!includeInternalMethods);
40
42
  }
41
43
  };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/schemas/utils.ts"],"names":[],"mappings":";;;AAAA,0DAAoD;AACpD,gDAAmE;AAGnE;;GAEG;AACH,MAAM,6BAA6B,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAExF;;;;;;;;GAQG;AACH,SAAgB,mBAAmB,CAAmB,MAAS;IAC7D,OAAO;QACL,GAAG,MAAM;QACT,QAAQ,EAAE,UACR,SAAiC;YAEjC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC9B,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE;oBACzB,OAAO;iBACR;gBACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,SAAS,EAAE,UACT,SAAiC;YAEjC,OAAO,IAAA,wBAAS,EAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACpC,CAAC;QACD,QAAQ,EAAE,UACR,SAAiC;YAEjC,OAAO,IAAA,wBAAS,EAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACxC,CAAC;QACD,QAAQ,EAAE,UAAU,sBAAsB,GAAG,KAAK;YAChD,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,sBAAsB,CAAC,CAAC;QACnD,CAAC;KACF,CAAC;AACJ,CAAC;AA7BD,kDA6BC;AAED;;;;;;;;;GASG;AACH,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,OAAO,6BAA6B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC;AAFD,4CAEC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAChB,IAA6B,EAC7B,sBAA+B,EAC/B,IAAI,GAAG,CAAC;IAER,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAA,iBAAO,EAAC,IAAI,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAC3B,IAAI,IAAA,kBAAQ,EAAC,KAAK,CAAC,EAAE;YACnB,MAAM,IAAI,GAAG,WAAW,GAAG,GAAG,QAAQ,SAAS,CAC7C,KAAK,EACL,sBAAsB,EACtB,EAAE,IAAI,CACP,GAAG,WAAW,MAAM,CAAC;SACvB;aAAM,IAAI,CAAC,IAAA,oBAAU,EAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,sBAAsB,EAAE;YACjF,4EAA4E;YAC5E,MAAM,IAAI,GAAG,WAAW,GAAG,GAAG,KAAK,KAAK,KAAK,CAAC;SAC/C;IACH,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { deepMerge } from '@empathyco/x-deep-merge';\nimport { forEach, isFunction, isObject } from '@empathyco/x-utils';\nimport { MutableSchema, Schema } from './types';\n\n/**\n * Collection of internal method names for {@link MutableSchema | mutable schemas}.\n */\nconst mutableSchemasInternalMethods = ['$replace', '$override', '$extends', 'toString'];\n\n/**\n * Creates a {@link MutableSchema | mutable schema } version of a given {@link Schema | schema}.\n *\n * @param schema - The {@link Schema | schema} to make mutable.\n *\n * @returns A {@link MutableSchema | mutable schema} version of the given {@link Schema | schema}.\n *\n * @public\n */\nexport function createMutableSchema<T extends Schema>(schema: T): MutableSchema<T> {\n return {\n ...schema,\n $replace: function <Source = any, Target = any>(\n newSchema: Schema<Source, Target>\n ): MutableSchema<Schema<Source, Target>> {\n Object.keys(this).forEach(key => {\n if (isInternalMethod(key)) {\n return;\n }\n delete this[key];\n });\n Object.assign(this, newSchema);\n return this;\n },\n $override: function <Source = any, Target = any>(\n newSchema: Schema<Source, Target>\n ): MutableSchema<Schema<Source, Target>> {\n return deepMerge(this, newSchema);\n },\n $extends: function <Source = any, Target = any>(\n newSchema: Schema<Source, Target>\n ): MutableSchema<Schema<Source, Target>> {\n return deepMerge({}, this, newSchema);\n },\n toString: function (includeInternalMethods = false) {\n return serialize(this, !!includeInternalMethods);\n }\n };\n}\n\n/**\n * Checks if the given key is a {@link MutableSchema | mutableSchema} method.\n *\n * @param name - The key to check.\n *\n * @returns True if it is a {@link MutableSchema | mutableSchema} method,\n * false otherwise.\n *\n * @public\n */\nexport function isInternalMethod(name: string): boolean {\n return mutableSchemasInternalMethods.includes(name);\n}\n\n/**\n * Returns a string representing of the given object.\n *\n * @param data - The object to get the string representation from.\n * @param includeInternalMethods - Flag to include in the string representation\n * the internal methods. Disabled by default.\n * @param deep - The level of indentation.\n * @returns The string representation.\n */\nfunction serialize(\n data: Record<string, unknown>,\n includeInternalMethods: boolean,\n deep = 0\n): string {\n const indentation = ' '.repeat(deep);\n let output = '';\n forEach(data, (key, value) => {\n if (isObject(value)) {\n output += `${indentation}${key}: {\\n${serialize(\n value,\n includeInternalMethods,\n ++deep\n )}${indentation}},\\n`;\n } else if (!isFunction(value) || !isInternalMethod(key) || includeInternalMethods) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n output += `${indentation}${key}: ${value},\\n`;\n }\n });\n return output;\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/schemas/utils.ts"],"names":[],"mappings":";;;AAAA,0DAAoD;AACpD,gDAAmE;AAGnE;;GAEG;AACH,MAAM,6BAA6B,GAAa,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAElG;;;;;;;;GAQG;AACH,SAAgB,mBAAmB,CACjC,MAA8B;IAE9B,OAAO;QACL,GAAG,MAAM;QACT,QAAQ,CAAC,SAAS;YAChB,IAAA,iBAAO,EAAC,IAAI,EAAE,GAAG,CAAC,EAAE;gBAClB,IAAI,gBAAgB,CAAC,GAAa,CAAC,EAAE;oBACnC,OAAO;iBACR;gBACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAC/B;+EACmE;YACnE,OAAO,IAAW,CAAC;QACrB,CAAC;QACD,SAAS,CAAC,SAAS;YACjB,OAAO,IAAA,wBAAS,EAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACpC,CAAC;QACD,QAAQ,CAAC,SAAkB;YACzB,OAAO,IAAA,wBAAS,EAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACxC,CAAC;QACD,QAAQ,CAAC,sBAAsB,GAAG,KAAK;YACrC,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,sBAAsB,CAAC,CAAC;QACnD,CAAC;KACF,CAAC;AACJ,CAAC;AA3BD,kDA2BC;AAED;;;;;;;;;GASG;AACH,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,OAAO,6BAA6B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC;AAFD,4CAEC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAChB,IAA6B,EAC7B,sBAA+B,EAC/B,IAAI,GAAG,CAAC;IAER,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAA,iBAAO,EAAC,IAAI,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAC3B,IAAI,IAAA,kBAAQ,EAAC,KAAK,CAAC,EAAE;YACnB,MAAM,IAAI,GAAG,WAAW,GAAG,GAAG,QAAQ,SAAS,CAC7C,KAAK,EACL,sBAAsB,EACtB,EAAE,IAAI,CACP,GAAG,WAAW,MAAM,CAAC;SACvB;aAAM,IAAI,CAAC,IAAA,oBAAU,EAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,sBAAsB,EAAE;YACjF,4EAA4E;YAC5E,MAAM,IAAI,GAAG,WAAW,GAAG,GAAG,KAAK,KAAK,KAAK,CAAC;SAC/C;IACH,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { deepMerge } from '@empathyco/x-deep-merge';\nimport { forEach, isFunction, isObject } from '@empathyco/x-utils';\nimport { MutableSchema, Schema } from './types';\n\n/**\n * Collection of internal method names for {@link MutableSchema | mutable schemas}.\n */\nconst mutableSchemasInternalMethods: string[] = ['$replace', '$override', '$extends', 'toString'];\n\n/**\n * Creates a {@link MutableSchema | mutable schema } version of a given {@link Schema | schema}.\n *\n * @param schema - The {@link Schema | schema} to make mutable.\n *\n * @returns A {@link MutableSchema | mutable schema} version of the given {@link Schema | schema}.\n *\n * @public\n */\nexport function createMutableSchema<Source, Target>(\n schema: Schema<Source, Target>\n): MutableSchema<Source, Target> {\n return {\n ...schema,\n $replace(newSchema) {\n forEach(this, key => {\n if (isInternalMethod(key as string)) {\n return;\n }\n delete this[key];\n });\n Object.assign(this, newSchema);\n /* We are replacing the schema with a completely new schema , so it makes sense that TS\n complains that the old schema and the new one are not the same. */\n return this as any;\n },\n $override(newSchema) {\n return deepMerge(this, newSchema);\n },\n $extends(newSchema: unknown) {\n return deepMerge({}, this, newSchema);\n },\n toString(includeInternalMethods = false) {\n return serialize(this, !!includeInternalMethods);\n }\n };\n}\n\n/**\n * Checks if the given key is a {@link MutableSchema | mutableSchema} method.\n *\n * @param name - The key to check.\n *\n * @returns True if it is a {@link MutableSchema | mutableSchema} method,\n * false otherwise.\n *\n * @public\n */\nexport function isInternalMethod(name: string): boolean {\n return mutableSchemasInternalMethods.includes(name);\n}\n\n/**\n * Returns a string representing of the given object.\n *\n * @param data - The object to get the string representation from.\n * @param includeInternalMethods - Flag to include in the string representation\n * the internal methods. Disabled by default.\n * @param deep - The level of indentation.\n * @returns The string representation.\n */\nfunction serialize(\n data: Record<string, unknown>,\n includeInternalMethods: boolean,\n deep = 0\n): string {\n const indentation = ' '.repeat(deep);\n let output = '';\n forEach(data, (key, value) => {\n if (isObject(value)) {\n output += `${indentation}${key}: {\\n${serialize(\n value,\n includeInternalMethods,\n ++deep\n )}${indentation}},\\n`;\n } else if (!isFunction(value) || !isInternalMethod(key) || includeInternalMethods) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n output += `${indentation}${key}: ${value},\\n`;\n }\n });\n return output;\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./extract-value"), exports);
5
4
  tslib_1.__exportStar(require("./interpolate"), exports);
6
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC;AAChC,wDAA8B","sourcesContent":["export * from './extract-value';\nexport * from './interpolate';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":";;;AAAA,wDAA8B","sourcesContent":["export * from './interpolate';\n"]}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.interpolate = void 0;
4
- const extract_value_1 = require("./extract-value");
4
+ const x_utils_1 = require("@empathyco/x-utils");
5
5
  /**
6
6
  * Syntax to detect and extract string parameters. A string parameter contains a property name
7
7
  * with an optional header or tail to concatenate wrapped in curly braces (`{}`).
@@ -92,11 +92,11 @@ const STRING_PARAMETER_CONTENT = new RegExp(`^${HEAD_OR_TAIL}([^(]+)${HEAD_OR_TA
92
92
  */
93
93
  function interpolate(string, parameters) {
94
94
  return string.replace(STRING_PARAMETERS, (_match, propertyToReplace) => propertyToReplace.replace(STRING_PARAMETER_CONTENT, (_match, head = '', property, tail = '') => {
95
- const value = (0, extract_value_1.extractValue)(parameters, property);
95
+ const value = (0, x_utils_1.getSafePropertyChain)(parameters, property);
96
96
  /* As the replacer function has a very dynamic signature, it is typed as a function with
97
97
  * `any` arguments. This makes it impossible for TS to infer the correct `string`
98
98
  * type that we are using as default values here. */
99
- return value != null ? `${String(head)}${String(value)}${String(tail)}` : '';
99
+ return value ? `${String(head)}${String(value)}${String(tail)}` : '';
100
100
  }));
101
101
  }
102
102
  exports.interpolate = interpolate;
@@ -1 +1 @@
1
- {"version":3,"file":"interpolate.js","sourceRoot":"","sources":["../../../src/utils/interpolate.ts"],"names":[],"mappings":";;;AAAA,mDAA+C;AAE/C;;;;;;;;;;;;;GAaG;AACH,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,YAAY,GAAG,iBAAiB,CAAC;AACvC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,wBAAwB,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,UAAU,YAAY,GAAG,EAAE,GAAG,CAAC,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,SAAgB,WAAW,CAAC,MAAc,EAAE,UAAmC;IAC7E,OAAO,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,iBAAyB,EAAE,EAAE,CAC7E,iBAAiB,CAAC,OAAO,CACvB,wBAAwB,EACxB,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,QAAgB,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE;QACjD,MAAM,KAAK,GAAG,IAAA,4BAAY,EAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACjD;;4DAEoD;QACpD,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,CAAC,CACF,CACF,CAAC;AACJ,CAAC;AAbD,kCAaC","sourcesContent":["import { extractValue } from './extract-value';\n\n/**\n * Syntax to detect and extract string parameters. A string parameter contains a property name\n * with an optional header or tail to concatenate wrapped in curly braces (`{}`).\n * The different parts of a string parameter are explained in {@link STRING_PARAMETER_CONTENT}.\n *\n * @example Different string parameters\n * ```js\n * \"\\{env\\}\" // No optional head or tail.\n * \"\\{(.)env\\}\" // Optional `.` head.\n * \"\\{env(-api)\\}\" // Optional `-api` tail.\n * \"\\{(api-)env(.)\\}\" // Optional `api-` head and `.` tail.\n * ```\n * @internal\n */\nconst STRING_PARAMETERS = /{([^}]+)}/g;\n\n/**\n * Shape of the optional head and tail parts of the {@link STRING_PARAMETER_CONTENT} regex.\n * This can be anything wrapped into parentheses.\n *\n * @internal\n */\nconst HEAD_OR_TAIL = '(?:\\\\((.+)\\\\))?';\n/**\n * Syntax of a single string parameter. A string parameter shape is composed by\n * the name of the property that should be replaced. This property name can be preceded\n * or followed by an optional string to prepend or to append to the property value\n * in case it is defined.\n *\n * @example Valid string parameters content\n * ```js\n * \"env\" // No optional head or tail to concatenate.\n * \"(.)env\" // The `.` character will be prepended as long as the `env` property is defined.\n * \"env(-api)\" // The `-api` string will be appended as long as the `env` property is defined.\n * \"(api-)env(.)\" // The `api-` string and the `.` character will be added as long as\n * // the `env` property is defined.\n * ```\n * @internal\n */\nconst STRING_PARAMETER_CONTENT = new RegExp(`^${HEAD_OR_TAIL}([^(]+)${HEAD_OR_TAIL}$`, 'g');\n\n/**\n * Interpolates different parameters into a string.\n * The provided string can set the parameters to replace wrapping a parameter name in curly\n * braces. This will then be replaced by the parameter value as long as it is defined. If it\n * is not provided, the parameter name will just be removed from the final string.\n *\n * @param string - The string to interpolate different parameters in.\n * @param parameters - Value of the different parameters to interpolate.\n * @returns The interpolated string.\n * @example Different usages of the interpolate function.\n * ```js\n * interpolate('https://{env}.empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://live.empathy.co/demo'\n *\n * interpolate('https://{(api-)env}.empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api-live.empathy.co/demo'\n *\n * interpolate('https://api.{env(.)}empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api.live.empathy.co/demo'\n *\n * interpolate('https://{(api-)env(.)}empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api-live.empathy.co/demo'\n *\n * interpolate('https://{env}.empathy.co/{instance}', {\n * env: 'live'\n * }) // 'https://live.empathy.co/'\n *\n * interpolate('https://search{(api-)env}.empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://search.empathy.co/demo'\n *\n * interpolate('https://api.{env(.)}empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://api.empathy.co/demo'\n *\n * interpolate('https://search.{(api-)env(.)}empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://search.empathy.co/demo'\n * ```\n * @public\n */\nexport function interpolate(string: string, parameters: Record<string, unknown>): string {\n return string.replace(STRING_PARAMETERS, (_match, propertyToReplace: string) =>\n propertyToReplace.replace(\n STRING_PARAMETER_CONTENT,\n (_match, head = '', property: string, tail = '') => {\n const value = extractValue(parameters, property);\n /* As the replacer function has a very dynamic signature, it is typed as a function with\n * `any` arguments. This makes it impossible for TS to infer the correct `string`\n * type that we are using as default values here. */\n return value != null ? `${String(head)}${String(value)}${String(tail)}` : '';\n }\n )\n );\n}\n"]}
1
+ {"version":3,"file":"interpolate.js","sourceRoot":"","sources":["../../../src/utils/interpolate.ts"],"names":[],"mappings":";;;AAAA,gDAA0D;AAE1D;;;;;;;;;;;;;GAaG;AACH,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,YAAY,GAAG,iBAAiB,CAAC;AACvC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,wBAAwB,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,UAAU,YAAY,GAAG,EAAE,GAAG,CAAC,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,SAAgB,WAAW,CAAC,MAAc,EAAE,UAAmC;IAC7E,OAAO,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,iBAAyB,EAAE,EAAE,CAC7E,iBAAiB,CAAC,OAAO,CACvB,wBAAwB,EACxB,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,QAAgB,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE;QACjD,MAAM,KAAK,GAAG,IAAA,8BAAoB,EAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACzD;;4DAEoD;QACpD,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,CAAC,CACF,CACF,CAAC;AACJ,CAAC;AAbD,kCAaC","sourcesContent":["import { getSafePropertyChain } from '@empathyco/x-utils';\n\n/**\n * Syntax to detect and extract string parameters. A string parameter contains a property name\n * with an optional header or tail to concatenate wrapped in curly braces (`{}`).\n * The different parts of a string parameter are explained in {@link STRING_PARAMETER_CONTENT}.\n *\n * @example Different string parameters\n * ```js\n * \"\\{env\\}\" // No optional head or tail.\n * \"\\{(.)env\\}\" // Optional `.` head.\n * \"\\{env(-api)\\}\" // Optional `-api` tail.\n * \"\\{(api-)env(.)\\}\" // Optional `api-` head and `.` tail.\n * ```\n * @internal\n */\nconst STRING_PARAMETERS = /{([^}]+)}/g;\n\n/**\n * Shape of the optional head and tail parts of the {@link STRING_PARAMETER_CONTENT} regex.\n * This can be anything wrapped into parentheses.\n *\n * @internal\n */\nconst HEAD_OR_TAIL = '(?:\\\\((.+)\\\\))?';\n/**\n * Syntax of a single string parameter. A string parameter shape is composed by\n * the name of the property that should be replaced. This property name can be preceded\n * or followed by an optional string to prepend or to append to the property value\n * in case it is defined.\n *\n * @example Valid string parameters content\n * ```js\n * \"env\" // No optional head or tail to concatenate.\n * \"(.)env\" // The `.` character will be prepended as long as the `env` property is defined.\n * \"env(-api)\" // The `-api` string will be appended as long as the `env` property is defined.\n * \"(api-)env(.)\" // The `api-` string and the `.` character will be added as long as\n * // the `env` property is defined.\n * ```\n * @internal\n */\nconst STRING_PARAMETER_CONTENT = new RegExp(`^${HEAD_OR_TAIL}([^(]+)${HEAD_OR_TAIL}$`, 'g');\n\n/**\n * Interpolates different parameters into a string.\n * The provided string can set the parameters to replace wrapping a parameter name in curly\n * braces. This will then be replaced by the parameter value as long as it is defined. If it\n * is not provided, the parameter name will just be removed from the final string.\n *\n * @param string - The string to interpolate different parameters in.\n * @param parameters - Value of the different parameters to interpolate.\n * @returns The interpolated string.\n * @example Different usages of the interpolate function.\n * ```js\n * interpolate('https://{env}.empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://live.empathy.co/demo'\n *\n * interpolate('https://{(api-)env}.empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api-live.empathy.co/demo'\n *\n * interpolate('https://api.{env(.)}empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api.live.empathy.co/demo'\n *\n * interpolate('https://{(api-)env(.)}empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api-live.empathy.co/demo'\n *\n * interpolate('https://{env}.empathy.co/{instance}', {\n * env: 'live'\n * }) // 'https://live.empathy.co/'\n *\n * interpolate('https://search{(api-)env}.empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://search.empathy.co/demo'\n *\n * interpolate('https://api.{env(.)}empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://api.empathy.co/demo'\n *\n * interpolate('https://search.{(api-)env(.)}empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://search.empathy.co/demo'\n * ```\n * @public\n */\nexport function interpolate(string: string, parameters: Record<string, unknown>): string {\n return string.replace(STRING_PARAMETERS, (_match, propertyToReplace: string) =>\n propertyToReplace.replace(\n STRING_PARAMETER_CONTENT,\n (_match, head = '', property: string, tail = '') => {\n const value = getSafePropertyChain(parameters, property);\n /* As the replacer function has a very dynamic signature, it is typed as a function with\n * `any` arguments. This makes it impossible for TS to infer the correct `string`\n * type that we are using as default values here. */\n return value ? `${String(head)}${String(value)}${String(tail)}` : '';\n }\n )\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { flatObject } from '@empathyco/x-utils';
1
+ import { cleanEmpty, flatObject } from '@empathyco/x-utils';
2
2
  import { buildUrl, toJson } from './utils';
3
3
  /**
4
4
  * The `fetchHttpClient()` function is a http client implementation using the `fetch` WebAPI.
@@ -13,8 +13,8 @@ import { buildUrl, toJson } from './utils';
13
13
  export const fetchHttpClient = (endpoint, { id = endpoint, cancelable = true, parameters = {}, properties, sendParamsInBody = false } = {}) => {
14
14
  const signal = cancelable ? { signal: abortAndGetNewAbortSignal(id) } : {};
15
15
  const flatParameters = flatObject(parameters);
16
- const url = sendParamsInBody ? endpoint : buildUrl(endpoint, flatParameters);
17
- const bodyParameters = sendParamsInBody ? { body: JSON.stringify(parameters) } : {};
16
+ const url = sendParamsInBody ? endpoint : buildUrl(endpoint, cleanEmpty(flatParameters));
17
+ const bodyParameters = sendParamsInBody ? { body: JSON.stringify(cleanEmpty(parameters)) } : {};
18
18
  return fetch(url, {
19
19
  ...properties,
20
20
  ...bodyParameters,
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/fetch.http-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE3C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,eAAe,GAAe,CACzC,QAAQ,EACR,EAAE,EAAE,GAAG,QAAQ,EAAE,UAAU,GAAG,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,UAAU,EAAE,gBAAgB,GAAG,KAAK,EAAE,GAAG,EAAE,EAChG,EAAE;IACF,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,cAAc,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAC7E,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpF,OAAO,KAAK,CAAC,GAAG,EAAE;QAChB,GAAG,UAAU;QACb,GAAG,cAAc;QACjB,GAAG,MAAM;KACV,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,uBAAuB,GAAgC,EAAE,CAAC;AAEhE;;;;;;;GAOG;AACH,SAAS,yBAAyB,CAAC,EAAU;;IAC3C,MAAA,uBAAuB,CAAC,EAAE,CAAC,0CAAE,KAAK,EAAE,CAAC;IACrC,uBAAuB,CAAC,EAAE,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;IACpD,OAAO,uBAAuB,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AAC5C,CAAC","sourcesContent":["import { Dictionary, flatObject } from '@empathyco/x-utils';\nimport { HttpClient } from './types';\nimport { buildUrl, toJson } from './utils';\n\n/**\n * The `fetchHttpClient()` function is a http client implementation using the `fetch` WebAPI.\n *\n * @param endpoint - The endpoint to make the request to.\n * @param options - The request options.\n *\n * @returns A `Promise` object.\n *\n * @public\n */\nexport const fetchHttpClient: HttpClient = (\n endpoint,\n { id = endpoint, cancelable = true, parameters = {}, properties, sendParamsInBody = false } = {}\n) => {\n const signal = cancelable ? { signal: abortAndGetNewAbortSignal(id) } : {};\n const flatParameters = flatObject(parameters);\n const url = sendParamsInBody ? endpoint : buildUrl(endpoint, flatParameters);\n const bodyParameters = sendParamsInBody ? { body: JSON.stringify(parameters) } : {};\n\n return fetch(url, {\n ...properties,\n ...bodyParameters,\n ...signal\n }).then(toJson);\n};\n\n/**\n * Dictionary with the request id as key and an `AbortController` as value.\n */\nconst requestAbortControllers: Dictionary<AbortController> = {};\n\n/**\n * Function that cancels previous request with the same `id` and returns a new `AbortSignal` for\n * the new request.\n *\n * @param id - The identifier of the request to cancel and create a new `AbortSignal`.\n *\n * @returns The new `AbortSignal`.\n */\nfunction abortAndGetNewAbortSignal(id: string): AbortSignal {\n requestAbortControllers[id]?.abort();\n requestAbortControllers[id] = new AbortController();\n return requestAbortControllers[id].signal;\n}\n"]}
1
+ {"version":3,"file":"fetch.http-client.js","sourceRoot":"","sources":["../../../src/http-clients/fetch.http-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE3C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,eAAe,GAAe,CACzC,QAAQ,EACR,EAAE,EAAE,GAAG,QAAQ,EAAE,UAAU,GAAG,IAAI,EAAE,UAAU,GAAG,EAAE,EAAE,UAAU,EAAE,gBAAgB,GAAG,KAAK,EAAE,GAAG,EAAE,EAChG,EAAE;IACF,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3E,MAAM,cAAc,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;IACzF,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhG,OAAO,KAAK,CAAC,GAAG,EAAE;QAChB,GAAG,UAAU;QACb,GAAG,cAAc;QACjB,GAAG,MAAM;KACV,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,uBAAuB,GAAgC,EAAE,CAAC;AAEhE;;;;;;;GAOG;AACH,SAAS,yBAAyB,CAAC,EAAU;;IAC3C,MAAA,uBAAuB,CAAC,EAAE,CAAC,0CAAE,KAAK,EAAE,CAAC;IACrC,uBAAuB,CAAC,EAAE,CAAC,GAAG,IAAI,eAAe,EAAE,CAAC;IACpD,OAAO,uBAAuB,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AAC5C,CAAC","sourcesContent":["import { Dictionary, cleanEmpty, flatObject } from '@empathyco/x-utils';\nimport { HttpClient } from './types';\nimport { buildUrl, toJson } from './utils';\n\n/**\n * The `fetchHttpClient()` function is a http client implementation using the `fetch` WebAPI.\n *\n * @param endpoint - The endpoint to make the request to.\n * @param options - The request options.\n *\n * @returns A `Promise` object.\n *\n * @public\n */\nexport const fetchHttpClient: HttpClient = (\n endpoint,\n { id = endpoint, cancelable = true, parameters = {}, properties, sendParamsInBody = false } = {}\n) => {\n const signal = cancelable ? { signal: abortAndGetNewAbortSignal(id) } : {};\n const flatParameters = flatObject(parameters);\n const url = sendParamsInBody ? endpoint : buildUrl(endpoint, cleanEmpty(flatParameters));\n const bodyParameters = sendParamsInBody ? { body: JSON.stringify(cleanEmpty(parameters)) } : {};\n\n return fetch(url, {\n ...properties,\n ...bodyParameters,\n ...signal\n }).then(toJson);\n};\n\n/**\n * Dictionary with the request id as key and an `AbortController` as value.\n */\nconst requestAbortControllers: Dictionary<AbortController> = {};\n\n/**\n * Function that cancels previous request with the same `id` and returns a new `AbortSignal` for\n * the new request.\n *\n * @param id - The identifier of the request to cancel and create a new `AbortSignal`.\n *\n * @returns The new `AbortSignal`.\n */\nfunction abortAndGetNewAbortSignal(id: string): AbortSignal {\n requestAbortControllers[id]?.abort();\n requestAbortControllers[id] = new AbortController();\n return requestAbortControllers[id].signal;\n}\n"]}
@@ -1,7 +1,6 @@
1
1
  import { deepMerge } from '@empathyco/x-deep-merge';
2
- import { isArray, isFunction, isObject, isPath, reduce } from '@empathyco/x-utils';
2
+ import { getSafePropertyChain, isArray, isFunction, isObject, isPath, reduce } from '@empathyco/x-utils';
3
3
  import { createMutableSchema, isInternalMethod } from '../schemas/utils';
4
- import { extractValue } from '../utils/extract-value';
5
4
  /**
6
5
  * The 'schemaMapperFactory' function creates a {@link Mapper | mapper function} for a given
7
6
  * {@link Schema | schema}.
@@ -33,7 +32,7 @@ function mapSchema(source, schema, context) {
33
32
  }
34
33
  return reduce(schema, (target, key, transformer) => {
35
34
  if (typeof transformer === 'string' && isPath(source, transformer)) {
36
- target[key] = extractValue(source, transformer);
35
+ target[key] = getSafePropertyChain(source, transformer);
37
36
  }
38
37
  else if (isFunction(transformer) && !isInternalMethod(transformer.name)) {
39
38
  target[key] = transformer(source, context);
@@ -65,7 +64,7 @@ function mapSchema(source, schema, context) {
65
64
  * @internal
66
65
  */
67
66
  function applySubSchemaTransformer(source, { $subSchema, $path, $context }, rawContext, schema) {
68
- const subSource = extractValue(source, $path);
67
+ const subSource = getSafePropertyChain(source, $path);
69
68
  if (!subSource) {
70
69
  return;
71
70
  }
@@ -77,7 +76,7 @@ function applySubSchemaTransformer(source, { $subSchema, $path, $context }, rawC
77
76
  }
78
77
  extendedContext[key] = isFunction(value)
79
78
  ? value(source)
80
- : extractValue(source, value);
79
+ : getSafePropertyChain(source, value);
81
80
  });
82
81
  }
83
82
  const context = deepMerge({}, rawContext, $context, extendedContext);
@@ -1 +1 @@
1
- {"version":3,"file":"schema-mapper.factory.js","sourceRoot":"","sources":["../../../src/mappers/schema-mapper.factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { deepMerge } from '@empathyco/x-deep-merge';\nimport {\n Dictionary,\n ExtractPath,\n isArray,\n isFunction,\n isObject,\n isPath,\n reduce\n} from '@empathyco/x-utils';\nimport { Schema, SubSchemaTransformer } from '../schemas/types';\nimport { createMutableSchema, isInternalMethod } from '../schemas/utils';\nimport { extractValue } from '../utils/extract-value';\nimport { Mapper, MapperContext } from './types';\n\n/**\n * The 'schemaMapperFactory' function creates a {@link Mapper | mapper function} for a given\n * {@link Schema | schema}.\n *\n * @param schema - The {@link Schema | schema} to apply in the {@link Mapper | mapper function}.\n * @returns A {@link Mapper | mapper function} that applies the given {@link Schema | schema}.\n * @public\n */\nexport function schemaMapperFactory<Source, Target>(\n schema: Schema<Source, Target>\n): Mapper<Source, Target> {\n return function mapper(source: Source, context: MapperContext): Target {\n return mapSchema(source, schema, context);\n };\n}\n\n/**\n * The `mapSchema()` function creates a new object populated with the transformations defined by a\n * {@link Schema} applied to a source object.\n *\n * @param source - The object to apply the transformations to.\n * @param schema - The object that defines the transformations to apply.\n * @param context - The {@link MapperContext | mapper context} to feed the transformations with.\n * @returns A new object with each element being the result of the applied transformation.\n * @internal\n */\nfunction mapSchema<Source, Target>(\n source: Source,\n schema: Schema<Source, Target>,\n context: MapperContext\n): Target {\n if (!source) {\n //eslint-disable-next-line no-console\n console.warn('This schema cannot be applied', createMutableSchema(schema));\n return undefined as any;\n }\n return reduce(\n schema,\n (target, key, transformer) => {\n type TargetKey = Target[keyof Target];\n if (typeof transformer === 'string' && isPath(source, transformer)) {\n target[key] = extractValue(source, transformer) as TargetKey;\n } else if (isFunction(transformer) && !isInternalMethod(transformer.name)) {\n target[key] = transformer(source, context);\n } else if (isObject(transformer)) {\n const value =\n '$subSchema' in transformer\n ? (applySubSchemaTransformer<Source, TargetKey>(\n source,\n transformer as SubSchemaTransformer<Source, TargetKey>,\n context,\n schema as unknown as Schema<Source, TargetKey>\n ) as TargetKey)\n : mapSchema<Source, TargetKey>(source, transformer, context);\n\n if (value) {\n target[key] = value;\n }\n }\n return target;\n },\n {} as Target\n );\n}\n\n/**\n * The `applySubSchemaTransformer()` function executes a `mapSchema()` function applying the defined\n * {@link SubSchemaTransformer.$subSchema}.\n *\n * @param source - The object to feed the schema.\n * @param subSchemaTransformer - The {@link SubSchemaTransformer} object with a $path, $subSchema\n * and $context options.\n * @param subSchemaTransformer.$path\n * @param subSchemaTransformer.$subSchema\n * @param rawContext - The {@link MapperContext | mapper context} to feed the mapSchema function.\n * @param subSchemaTransformer.$context\n * @param schema - The {@link Schema} to apply.\n * @returns The result of calling `mapSchema()` with the source, schema and context arguments.\n * @internal\n */\nfunction applySubSchemaTransformer<Source, Target>(\n source: Source,\n { $subSchema, $path, $context }: SubSchemaTransformer<Source, Target>,\n rawContext: MapperContext,\n schema: Schema<Source, Target>\n): Target | Target[] | undefined {\n const subSource = extractValue(source, $path);\n\n if (!subSource) {\n return;\n }\n\n const extendedContext: Dictionary = {};\n if ($context) {\n Object.entries($context).forEach(([key, value]) => {\n if (['requestParameters', 'endpoint', 'mappedValue'].includes(key)) {\n return;\n }\n extendedContext[key] = isFunction(value)\n ? value(source)\n : extractValue(source, value as ExtractPath<typeof source>);\n });\n }\n\n const context = deepMerge({}, rawContext, $context, extendedContext);\n let subSchema: typeof $subSchema | typeof schema;\n if ($subSchema === '$self') {\n subSchema = schema;\n } else if (isFunction($subSchema)) {\n subSchema = $subSchema(source);\n } else {\n subSchema = $subSchema;\n }\n return isArray(subSource)\n ? subSource.map(item => mapSchema(item, subSchema, context) as Target)\n : mapSchema<typeof subSource, Target>(\n subSource,\n subSchema as Schema<typeof subSource, Target>,\n context\n );\n}\n"]}
1
+ {"version":3,"file":"schema-mapper.factory.js","sourceRoot":"","sources":["../../../src/mappers/schema-mapper.factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { deepMerge } from '@empathyco/x-deep-merge';\nimport {\n Dictionary,\n ExtractPath,\n getSafePropertyChain,\n isArray,\n isFunction,\n isObject,\n isPath,\n reduce\n} from '@empathyco/x-utils';\nimport { MutableSchema, Schema, SubSchemaTransformer } from '../schemas/types';\nimport { createMutableSchema, isInternalMethod } from '../schemas/utils';\nimport { Mapper, MapperContext } from './types';\n\n/**\n * The 'schemaMapperFactory' function creates a {@link Mapper | mapper function} for a given\n * {@link Schema | schema}.\n *\n * @param schema - The {@link Schema | schema} to apply in the {@link Mapper | mapper function}.\n * @returns A {@link Mapper | mapper function} that applies the given {@link Schema | schema}.\n * @public\n */\nexport function schemaMapperFactory<Source, Target>(\n schema: Schema<Source, Target> | MutableSchema<Source, Target>\n): Mapper<Source, Target> {\n return function mapper(source: Source, context: MapperContext): Target {\n return mapSchema(source, schema, context);\n };\n}\n\n/**\n * The `mapSchema()` function creates a new object populated with the transformations defined by a\n * {@link Schema} applied to a source object.\n *\n * @param source - The object to apply the transformations to.\n * @param schema - The object that defines the transformations to apply.\n * @param context - The {@link MapperContext | mapper context} to feed the transformations with.\n * @returns A new object with each element being the result of the applied transformation.\n * @internal\n */\nfunction mapSchema<Source, Target>(\n source: Source,\n schema: Schema<Source, Target>,\n context: MapperContext\n): Target {\n if (!source) {\n //eslint-disable-next-line no-console\n console.warn('This schema cannot be applied', createMutableSchema(schema));\n return undefined as any;\n }\n return reduce(\n schema,\n (target, key, transformer) => {\n type TargetKey = Target[keyof Target];\n if (typeof transformer === 'string' && isPath(source, transformer)) {\n target[key] = getSafePropertyChain(source, transformer) as TargetKey;\n } else if (isFunction(transformer) && !isInternalMethod(transformer.name)) {\n target[key] = transformer(source, context);\n } else if (isObject(transformer)) {\n const value =\n '$subSchema' in transformer\n ? (applySubSchemaTransformer<Source, TargetKey>(\n source,\n transformer as SubSchemaTransformer<Source, TargetKey>,\n context,\n schema as unknown as Schema<Source, TargetKey>\n ) as TargetKey)\n : mapSchema<Source, TargetKey>(source, transformer, context);\n\n if (value) {\n target[key] = value;\n }\n }\n return target;\n },\n {} as Target\n );\n}\n\n/**\n * The `applySubSchemaTransformer()` function executes a `mapSchema()` function applying the defined\n * {@link SubSchemaTransformer.$subSchema}.\n *\n * @param source - The object to feed the schema.\n * @param subSchemaTransformer - The {@link SubSchemaTransformer} object with a $path, $subSchema\n * and $context options.\n * @param subSchemaTransformer.$path\n * @param subSchemaTransformer.$subSchema\n * @param rawContext - The {@link MapperContext | mapper context} to feed the mapSchema function.\n * @param subSchemaTransformer.$context\n * @param schema - The {@link Schema} to apply.\n * @returns The result of calling `mapSchema()` with the source, schema and context arguments.\n * @internal\n */\nfunction applySubSchemaTransformer<Source, Target>(\n source: Source,\n { $subSchema, $path, $context }: SubSchemaTransformer<Source, Target>,\n rawContext: MapperContext,\n schema: Schema<Source, Target>\n): Target | Target[] | undefined {\n const subSource = getSafePropertyChain(source, $path);\n\n if (!subSource) {\n return;\n }\n\n const extendedContext: Dictionary = {};\n if ($context) {\n Object.entries($context).forEach(([key, value]) => {\n if (['requestParameters', 'endpoint', 'mappedValue'].includes(key)) {\n return;\n }\n extendedContext[key] = isFunction(value)\n ? value(source)\n : getSafePropertyChain(source, value as ExtractPath<typeof source>);\n });\n }\n\n const context = deepMerge({}, rawContext, $context, extendedContext);\n let subSchema: typeof $subSchema | typeof schema;\n if ($subSchema === '$self') {\n subSchema = schema;\n } else if (isFunction($subSchema)) {\n subSchema = $subSchema(source);\n } else {\n subSchema = $subSchema;\n }\n return isArray(subSource)\n ? subSource.map(item => mapSchema(item, subSchema, context) as Target)\n : mapSchema<typeof subSource, Target>(\n subSource,\n subSchema as Schema<typeof subSource, Target>,\n context\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/schemas/types.ts"],"names":[],"mappings":"","sourcesContent":["import {\n AnyFunction,\n ExtractPath,\n ExtractPathByType,\n ExtractType,\n Primitive\n} from '@empathyco/x-utils';\nimport { MapperContext } from '../mappers/types';\n\n// TODO: EX-5830 - Enhance Schema type to support optional properties in the Source object\n/**\n * Template object to transform a source object to a target object.\n *\n * @remarks The source object must not have optional properties, as it could cause infinite\n * type instantiations.\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * price: {\n * max: number;\n * min: number;\n * };\n * images: string[];\n * }\n *\n * interface Target {\n * identifier: string;\n * maxPrice: number;\n * minPrice: number;\n * img: string[]\n * }\n *\n * const schema: Schema<Source, Target> = {\n * identifier: 'id',\n * maxPrice: 'price.max',\n * minPrice: ({ price }) => Math.min(0, price.min),\n * img: 'images'\n * };\n * ```\n * @public\n */\nexport type Schema<Source = any, Target = any> = {\n [TargetKey in keyof Target]: SchemaTransformer<Source, Target, TargetKey>;\n};\n\n/**\n * A {@link Schema | schema} with extended functionality to: completely replace\n * the original schema, partially override it or create a new one.\n *\n * @param OriginalSchema - The {@link Schema | schema} that will be mutable.\n * @public\n */\nexport type MutableSchema<OriginalSchema extends Schema> = OriginalSchema & {\n /**\n * Replaces all usages of the original {@link Schema | schema} with the given one.\n *\n * @param newSchema - The {@link Schema | schema} to use instead of the original one.\n * @returns The new {@link Schema | schema} that will be used.\n */\n $replace: <Source, Target>(\n newSchema: Schema<Source, Target>\n ) => MutableSchema<Schema<Source, Target>>;\n /**\n * Merges the original {@link Schema | schema} with the given one.\n *\n * @param newSchema - The {@link Schema | schema} to use to merge with the original one.\n * @returns The {@link Schema | schema} returned by the merge.\n */\n $override: <Source, Target>(\n newSchema: Schema<Source, Target>\n ) => MutableSchema<Schema<Source, Target>>;\n /**\n * Creates a new {@link Schema | schema} using the original one as starting point.\n * The original {@link Schema | schema} will remain unchanged.\n *\n * @param newSchema - The {@link Schema | schema} to be used to extend the original one.\n * @returns The {@link Schema | schema} created.\n */\n $extends: <Source, Target>(\n newSchema: Schema<Source, Target>\n ) => MutableSchema<Schema<Source, Target>>;\n /**\n * Returns a string representing of the {@link Schema | schema}.\n *\n * @param includeInternalMethods - Flag to include in the string representation\n * the internal methods. Disabled by default.\n * @returns The string representation.\n */\n toString: (includeInternalMethods?: boolean) => string;\n};\n\n/**\n * The possible transformers to apply to the target key.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @param TargetKey - The target key to apply the transformation.\n * @public\n */\nexport type SchemaTransformer<Source, Target, TargetKey extends keyof Target> =\n | PathTransformer<Source, Target[TargetKey]>\n | FunctionTransformer<Source, Target[TargetKey]>\n | SubSchemaTransformer<Source, Target[TargetKey]>\n | Schema<Source, Exclude<Target[TargetKey], AnyFunction | Primitive>>;\n\n/**\n * A function with the source object and mapper context as parameters that returns the value of a\n * target's property.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * count: number;\n * }\n *\n * interface Target {\n * title: string;\n * hits: number;\n * }\n *\n * const subSchema: Schema<Source, Target> = {\n * title: 'id',\n * hits: 'count'\n * };\n *\n * const wrongSubSchema: Schema<Source, Target> = {\n * // @ts-expect-error\n * title: 'count', // This raises a TS error\n * hits: 'count'\n * };\n * ```\n * @public\n */\nexport type PathTransformer<Source, Target> = ExtractPathByType<Source, Target>;\n\n/**\n * A function with the source object and mapper context as parameters that returns the value of a\n * target's property.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * count: number;\n * }\n *\n * interface Target {\n * title: string;\n * hits: number;\n * }\n *\n * const subSchema: Schema<Source, Target> = {\n * title: source => source.id,\n * hits: (source, context) => context.requestParameters.query === 'example'\n * ? source.count\n * : 0\n * };\n * ```\n * @public\n */\nexport type FunctionTransformer<Source, Target> = (\n source: Source,\n context?: MapperContext\n) => Target;\n\n/**\n * An object containing a schema narrowing its source object based on the given path.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * facets: {\n * name: string;\n * count: number;\n * };\n * images: string[];\n * }\n *\n * interface Target {\n * identifier: string;\n * filters: {\n * id: string;\n * numFound: number;\n * };\n * img: string[]\n * }\n *\n * const subSchema: SubSchemaTransformer<Source, Target['filters']> = {\n * $path: 'facets',\n * $subSchema: {\n * id: 'name',\n * numFound: 'count'\n * }\n * };\n * ```\n * @public\n */\nexport type SubSchemaTransformer<Source, Target> = {\n [Path in ExtractPath<Source>]: {\n $context?: MapperContext;\n $path: Path;\n $subSchema:\n | SubSchema<Source, Target, Path>\n | '$self'\n | ((source: Source) => SubSchema<Source, Target, Path>);\n };\n}[ExtractPath<Source>];\n\n/**\n * A {@link Schema | schema} that will be applied to an inner path of an object.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @param Path - The path where the schema will be applied.\n * @public\n */\nexport type SubSchema<Source, Target, Path extends ExtractPath<Source>> = ExtractType<\n Source,\n Path\n> extends (infer SourceArrayType)[]\n ? Target extends (infer TargetArrayType)[]\n ? Schema<SourceArrayType, TargetArrayType>\n : never\n : Target extends []\n ? never\n : Schema<ExtractType<Source, Path>, Target>;\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/schemas/types.ts"],"names":[],"mappings":"","sourcesContent":["import {\n AnyFunction,\n DeepPartial,\n ExtractPath,\n ExtractPathByType,\n ExtractType,\n Primitive\n} from '@empathyco/x-utils';\nimport { MapperContext } from '../mappers/types';\n\n// TODO: EX-5830 - Enhance Schema type to support optional properties in the Source object\n/**\n * Template object to transform a source object to a target object.\n *\n * @remarks The source object must not have optional properties, as it could cause infinite\n * type instantiations.\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * price: {\n * max: number;\n * min: number;\n * };\n * images: string[];\n * }\n *\n * interface Target {\n * identifier: string;\n * maxPrice: number;\n * minPrice: number;\n * img: string[]\n * }\n *\n * const schema: Schema<Source, Target> = {\n * identifier: 'id',\n * maxPrice: 'price.max',\n * minPrice: ({ price }) => Math.min(0, price.min),\n * img: 'images'\n * };\n * ```\n * @public\n */\nexport type Schema<Source = any, Target = any> = {\n [TargetKey in keyof Target]: SchemaTransformer<Source, Target, TargetKey>;\n};\n\n/**\n * A {@link Schema | schema} with extended functionality to: completely replace\n * the original schema, partially override it or create a new one.\n *\n * @param OriginalSchema - The {@link Schema | schema} that will be mutable.\n * @public\n */\nexport type MutableSchema<Source, Target> = Schema<Source, Target> & {\n /**\n * Replaces all usages of the original {@link Schema | schema} with the given one.\n *\n * @param newSchema - The {@link Schema | schema} to use instead of the original one.\n * @returns The new {@link Schema | schema} that will be used.\n */\n $replace<NewSource, NewTarget>(\n newSchema: Schema<NewSource, NewTarget>\n ): MutableSchema<NewSource, NewTarget>;\n /**\n * Merges the original {@link Schema | schema} with the given one.\n *\n * @param newSchema - The {@link Schema | schema} to use to merge with the original one.\n * @returns The {@link Schema | schema} returned by the merge.\n */\n // eslint-disable-next-line @typescript-eslint/ban-types\n $override<NewSource, NewTarget = {}>(\n newSchema: DeepPartial<Schema<Source & NewSource, Target>> &\n Schema<Source & NewSource, NewTarget>\n ): MutableSchema<Source & NewSource, Target & NewTarget>;\n /**\n * Creates a new {@link Schema | schema} using the original one as starting point.\n * The original {@link Schema | schema} will remain unchanged.\n *\n * @param newSchema - The {@link Schema | schema} to be used to extend the original one.\n * Both schema's Target and Source can be unique or also be extending from another one.\n * @returns The {@link Schema | schema} created.\n */\n $extends<NewSource extends Source, NewTarget extends Target>(\n newSchema: DeepPartial<Schema<Source & NewSource, Target>> &\n Schema<Source & NewSource, Omit<NewTarget, keyof Target>>\n ): MutableSchema<Source & NewSource, Target & NewTarget>;\n // eslint-disable-next-line @typescript-eslint/ban-types\n $extends<NewSource, NewTarget = {}>(\n newSchema: DeepPartial<Schema<Source & NewSource, Target>> &\n Schema<Source & NewSource, NewTarget>\n ): MutableSchema<Source & NewSource, Target & NewTarget>;\n /**\n * Returns a string representing of the {@link Schema | schema}.\n *\n * @param includeInternalMethods - Flag to include in the string representation\n * the internal methods. Disabled by default.\n * @returns The string representation.\n */\n toString(includeInternalMethods?: boolean): string;\n};\n/**\n * The possible transformers to apply to the target key.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @param TargetKey - The target key to apply the transformation.\n * @public\n */\nexport type SchemaTransformer<Source, Target, TargetKey extends keyof Target> =\n | PathTransformer<Source, Target[TargetKey]>\n | FunctionTransformer<Source, Target[TargetKey]>\n | SubSchemaTransformer<Source, Target[TargetKey]>\n | Schema<Source, Exclude<Target[TargetKey], AnyFunction | Primitive>>;\n\n/**\n * A function with the source object and mapper context as parameters that returns the value of a\n * target's property.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * count: number;\n * }\n *\n * interface Target {\n * title: string;\n * hits: number;\n * }\n *\n * const subSchema: Schema<Source, Target> = {\n * title: 'id',\n * hits: 'count'\n * };\n *\n * const wrongSubSchema: Schema<Source, Target> = {\n * // @ts-expect-error\n * title: 'count', // This raises a TS error\n * hits: 'count'\n * };\n * ```\n * @public\n */\nexport type PathTransformer<Source, Target> = ExtractPathByType<Source, Target>;\n\n/**\n * A function with the source object and mapper context as parameters that returns the value of a\n * target's property.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * count: number;\n * }\n *\n * interface Target {\n * title: string;\n * hits: number;\n * }\n *\n * const subSchema: Schema<Source, Target> = {\n * title: source => source.id,\n * hits: (source, context) => context.requestParameters.query === 'example'\n * ? source.count\n * : 0\n * };\n * ```\n * @public\n */\nexport type FunctionTransformer<Source, Target> = (\n source: Source,\n context?: MapperContext\n) => Target;\n\n/**\n * An object containing a schema narrowing its source object based on the given path.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @example\n * ```typescript\n * interface Source {\n * id: string;\n * facets: {\n * name: string;\n * count: number;\n * };\n * images: string[];\n * }\n *\n * interface Target {\n * identifier: string;\n * filters: {\n * id: string;\n * numFound: number;\n * };\n * img: string[]\n * }\n *\n * const subSchema: SubSchemaTransformer<Source, Target['filters']> = {\n * $path: 'facets',\n * $subSchema: {\n * id: 'name',\n * numFound: 'count'\n * }\n * };\n * ```\n * @public\n */\nexport type SubSchemaTransformer<Source, Target> = {\n [Path in ExtractPath<Source>]: {\n $context?: MapperContext;\n $path: Path;\n $subSchema:\n | SubSchema<Source, Target, Path>\n | '$self'\n | ((source: Source) => SubSchema<Source, Target, Path>);\n };\n}[ExtractPath<Source>];\n\n/**\n * A {@link Schema | schema} that will be applied to an inner path of an object.\n *\n * @param Source - The source object.\n * @param Target - The target object.\n * @param Path - The path where the schema will be applied.\n * @public\n */\nexport type SubSchema<Source, Target, Path extends ExtractPath<Source>> = ExtractType<\n Source,\n Path\n> extends (infer SourceArrayType)[]\n ? Target extends (infer TargetArrayType)[]\n ? Schema<SourceArrayType, TargetArrayType>\n : never\n : Target extends []\n ? never\n : Schema<ExtractType<Source, Path>, Target>;\n"]}
@@ -16,23 +16,25 @@ const mutableSchemasInternalMethods = ['$replace', '$override', '$extends', 'toS
16
16
  export function createMutableSchema(schema) {
17
17
  return {
18
18
  ...schema,
19
- $replace: function (newSchema) {
20
- Object.keys(this).forEach(key => {
19
+ $replace(newSchema) {
20
+ forEach(this, key => {
21
21
  if (isInternalMethod(key)) {
22
22
  return;
23
23
  }
24
24
  delete this[key];
25
25
  });
26
26
  Object.assign(this, newSchema);
27
+ /* We are replacing the schema with a completely new schema , so it makes sense that TS
28
+ complains that the old schema and the new one are not the same. */
27
29
  return this;
28
30
  },
29
- $override: function (newSchema) {
31
+ $override(newSchema) {
30
32
  return deepMerge(this, newSchema);
31
33
  },
32
- $extends: function (newSchema) {
34
+ $extends(newSchema) {
33
35
  return deepMerge({}, this, newSchema);
34
36
  },
35
- toString: function (includeInternalMethods = false) {
37
+ toString(includeInternalMethods = false) {
36
38
  return serialize(this, !!includeInternalMethods);
37
39
  }
38
40
  };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/schemas/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnE;;GAEG;AACH,MAAM,6BAA6B,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAExF;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAmB,MAAS;IAC7D,OAAO;QACL,GAAG,MAAM;QACT,QAAQ,EAAE,UACR,SAAiC;YAEjC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC9B,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE;oBACzB,OAAO;iBACR;gBACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,SAAS,EAAE,UACT,SAAiC;YAEjC,OAAO,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACpC,CAAC;QACD,QAAQ,EAAE,UACR,SAAiC;YAEjC,OAAO,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACxC,CAAC;QACD,QAAQ,EAAE,UAAU,sBAAsB,GAAG,KAAK;YAChD,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,sBAAsB,CAAC,CAAC;QACnD,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,6BAA6B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAChB,IAA6B,EAC7B,sBAA+B,EAC/B,IAAI,GAAG,CAAC;IAER,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAC3B,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE;YACnB,MAAM,IAAI,GAAG,WAAW,GAAG,GAAG,QAAQ,SAAS,CAC7C,KAAK,EACL,sBAAsB,EACtB,EAAE,IAAI,CACP,GAAG,WAAW,MAAM,CAAC;SACvB;aAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,sBAAsB,EAAE;YACjF,4EAA4E;YAC5E,MAAM,IAAI,GAAG,WAAW,GAAG,GAAG,KAAK,KAAK,KAAK,CAAC;SAC/C;IACH,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { deepMerge } from '@empathyco/x-deep-merge';\nimport { forEach, isFunction, isObject } from '@empathyco/x-utils';\nimport { MutableSchema, Schema } from './types';\n\n/**\n * Collection of internal method names for {@link MutableSchema | mutable schemas}.\n */\nconst mutableSchemasInternalMethods = ['$replace', '$override', '$extends', 'toString'];\n\n/**\n * Creates a {@link MutableSchema | mutable schema } version of a given {@link Schema | schema}.\n *\n * @param schema - The {@link Schema | schema} to make mutable.\n *\n * @returns A {@link MutableSchema | mutable schema} version of the given {@link Schema | schema}.\n *\n * @public\n */\nexport function createMutableSchema<T extends Schema>(schema: T): MutableSchema<T> {\n return {\n ...schema,\n $replace: function <Source = any, Target = any>(\n newSchema: Schema<Source, Target>\n ): MutableSchema<Schema<Source, Target>> {\n Object.keys(this).forEach(key => {\n if (isInternalMethod(key)) {\n return;\n }\n delete this[key];\n });\n Object.assign(this, newSchema);\n return this;\n },\n $override: function <Source = any, Target = any>(\n newSchema: Schema<Source, Target>\n ): MutableSchema<Schema<Source, Target>> {\n return deepMerge(this, newSchema);\n },\n $extends: function <Source = any, Target = any>(\n newSchema: Schema<Source, Target>\n ): MutableSchema<Schema<Source, Target>> {\n return deepMerge({}, this, newSchema);\n },\n toString: function (includeInternalMethods = false) {\n return serialize(this, !!includeInternalMethods);\n }\n };\n}\n\n/**\n * Checks if the given key is a {@link MutableSchema | mutableSchema} method.\n *\n * @param name - The key to check.\n *\n * @returns True if it is a {@link MutableSchema | mutableSchema} method,\n * false otherwise.\n *\n * @public\n */\nexport function isInternalMethod(name: string): boolean {\n return mutableSchemasInternalMethods.includes(name);\n}\n\n/**\n * Returns a string representing of the given object.\n *\n * @param data - The object to get the string representation from.\n * @param includeInternalMethods - Flag to include in the string representation\n * the internal methods. Disabled by default.\n * @param deep - The level of indentation.\n * @returns The string representation.\n */\nfunction serialize(\n data: Record<string, unknown>,\n includeInternalMethods: boolean,\n deep = 0\n): string {\n const indentation = ' '.repeat(deep);\n let output = '';\n forEach(data, (key, value) => {\n if (isObject(value)) {\n output += `${indentation}${key}: {\\n${serialize(\n value,\n includeInternalMethods,\n ++deep\n )}${indentation}},\\n`;\n } else if (!isFunction(value) || !isInternalMethod(key) || includeInternalMethods) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n output += `${indentation}${key}: ${value},\\n`;\n }\n });\n return output;\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/schemas/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnE;;GAEG;AACH,MAAM,6BAA6B,GAAa,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;AAElG;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAA8B;IAE9B,OAAO;QACL,GAAG,MAAM;QACT,QAAQ,CAAC,SAAS;YAChB,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE;gBAClB,IAAI,gBAAgB,CAAC,GAAa,CAAC,EAAE;oBACnC,OAAO;iBACR;gBACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAC/B;+EACmE;YACnE,OAAO,IAAW,CAAC;QACrB,CAAC;QACD,SAAS,CAAC,SAAS;YACjB,OAAO,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACpC,CAAC;QACD,QAAQ,CAAC,SAAkB;YACzB,OAAO,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;QACxC,CAAC;QACD,QAAQ,CAAC,sBAAsB,GAAG,KAAK;YACrC,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,sBAAsB,CAAC,CAAC;QACnD,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,6BAA6B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAChB,IAA6B,EAC7B,sBAA+B,EAC/B,IAAI,GAAG,CAAC;IAER,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,OAAO,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAC3B,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE;YACnB,MAAM,IAAI,GAAG,WAAW,GAAG,GAAG,QAAQ,SAAS,CAC7C,KAAK,EACL,sBAAsB,EACtB,EAAE,IAAI,CACP,GAAG,WAAW,MAAM,CAAC;SACvB;aAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,sBAAsB,EAAE;YACjF,4EAA4E;YAC5E,MAAM,IAAI,GAAG,WAAW,GAAG,GAAG,KAAK,KAAK,KAAK,CAAC;SAC/C;IACH,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["import { deepMerge } from '@empathyco/x-deep-merge';\nimport { forEach, isFunction, isObject } from '@empathyco/x-utils';\nimport { MutableSchema, Schema } from './types';\n\n/**\n * Collection of internal method names for {@link MutableSchema | mutable schemas}.\n */\nconst mutableSchemasInternalMethods: string[] = ['$replace', '$override', '$extends', 'toString'];\n\n/**\n * Creates a {@link MutableSchema | mutable schema } version of a given {@link Schema | schema}.\n *\n * @param schema - The {@link Schema | schema} to make mutable.\n *\n * @returns A {@link MutableSchema | mutable schema} version of the given {@link Schema | schema}.\n *\n * @public\n */\nexport function createMutableSchema<Source, Target>(\n schema: Schema<Source, Target>\n): MutableSchema<Source, Target> {\n return {\n ...schema,\n $replace(newSchema) {\n forEach(this, key => {\n if (isInternalMethod(key as string)) {\n return;\n }\n delete this[key];\n });\n Object.assign(this, newSchema);\n /* We are replacing the schema with a completely new schema , so it makes sense that TS\n complains that the old schema and the new one are not the same. */\n return this as any;\n },\n $override(newSchema) {\n return deepMerge(this, newSchema);\n },\n $extends(newSchema: unknown) {\n return deepMerge({}, this, newSchema);\n },\n toString(includeInternalMethods = false) {\n return serialize(this, !!includeInternalMethods);\n }\n };\n}\n\n/**\n * Checks if the given key is a {@link MutableSchema | mutableSchema} method.\n *\n * @param name - The key to check.\n *\n * @returns True if it is a {@link MutableSchema | mutableSchema} method,\n * false otherwise.\n *\n * @public\n */\nexport function isInternalMethod(name: string): boolean {\n return mutableSchemasInternalMethods.includes(name);\n}\n\n/**\n * Returns a string representing of the given object.\n *\n * @param data - The object to get the string representation from.\n * @param includeInternalMethods - Flag to include in the string representation\n * the internal methods. Disabled by default.\n * @param deep - The level of indentation.\n * @returns The string representation.\n */\nfunction serialize(\n data: Record<string, unknown>,\n includeInternalMethods: boolean,\n deep = 0\n): string {\n const indentation = ' '.repeat(deep);\n let output = '';\n forEach(data, (key, value) => {\n if (isObject(value)) {\n output += `${indentation}${key}: {\\n${serialize(\n value,\n includeInternalMethods,\n ++deep\n )}${indentation}},\\n`;\n } else if (!isFunction(value) || !isInternalMethod(key) || includeInternalMethods) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n output += `${indentation}${key}: ${value},\\n`;\n }\n });\n return output;\n}\n"]}
@@ -1,3 +1,2 @@
1
- export * from './extract-value';
2
1
  export * from './interpolate';
3
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC","sourcesContent":["export * from './extract-value';\nexport * from './interpolate';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC","sourcesContent":["export * from './interpolate';\n"]}
@@ -1,4 +1,4 @@
1
- import { extractValue } from './extract-value';
1
+ import { getSafePropertyChain } from '@empathyco/x-utils';
2
2
  /**
3
3
  * Syntax to detect and extract string parameters. A string parameter contains a property name
4
4
  * with an optional header or tail to concatenate wrapped in curly braces (`{}`).
@@ -89,11 +89,11 @@ const STRING_PARAMETER_CONTENT = new RegExp(`^${HEAD_OR_TAIL}([^(]+)${HEAD_OR_TA
89
89
  */
90
90
  export function interpolate(string, parameters) {
91
91
  return string.replace(STRING_PARAMETERS, (_match, propertyToReplace) => propertyToReplace.replace(STRING_PARAMETER_CONTENT, (_match, head = '', property, tail = '') => {
92
- const value = extractValue(parameters, property);
92
+ const value = getSafePropertyChain(parameters, property);
93
93
  /* As the replacer function has a very dynamic signature, it is typed as a function with
94
94
  * `any` arguments. This makes it impossible for TS to infer the correct `string`
95
95
  * type that we are using as default values here. */
96
- return value != null ? `${String(head)}${String(value)}${String(tail)}` : '';
96
+ return value ? `${String(head)}${String(value)}${String(tail)}` : '';
97
97
  }));
98
98
  }
99
99
  //# sourceMappingURL=interpolate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"interpolate.js","sourceRoot":"","sources":["../../../src/utils/interpolate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;;;;;;;;;GAaG;AACH,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,YAAY,GAAG,iBAAiB,CAAC;AACvC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,wBAAwB,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,UAAU,YAAY,GAAG,EAAE,GAAG,CAAC,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,UAAmC;IAC7E,OAAO,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,iBAAyB,EAAE,EAAE,CAC7E,iBAAiB,CAAC,OAAO,CACvB,wBAAwB,EACxB,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,QAAgB,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE;QACjD,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACjD;;4DAEoD;QACpD,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,CAAC,CACF,CACF,CAAC;AACJ,CAAC","sourcesContent":["import { extractValue } from './extract-value';\n\n/**\n * Syntax to detect and extract string parameters. A string parameter contains a property name\n * with an optional header or tail to concatenate wrapped in curly braces (`{}`).\n * The different parts of a string parameter are explained in {@link STRING_PARAMETER_CONTENT}.\n *\n * @example Different string parameters\n * ```js\n * \"\\{env\\}\" // No optional head or tail.\n * \"\\{(.)env\\}\" // Optional `.` head.\n * \"\\{env(-api)\\}\" // Optional `-api` tail.\n * \"\\{(api-)env(.)\\}\" // Optional `api-` head and `.` tail.\n * ```\n * @internal\n */\nconst STRING_PARAMETERS = /{([^}]+)}/g;\n\n/**\n * Shape of the optional head and tail parts of the {@link STRING_PARAMETER_CONTENT} regex.\n * This can be anything wrapped into parentheses.\n *\n * @internal\n */\nconst HEAD_OR_TAIL = '(?:\\\\((.+)\\\\))?';\n/**\n * Syntax of a single string parameter. A string parameter shape is composed by\n * the name of the property that should be replaced. This property name can be preceded\n * or followed by an optional string to prepend or to append to the property value\n * in case it is defined.\n *\n * @example Valid string parameters content\n * ```js\n * \"env\" // No optional head or tail to concatenate.\n * \"(.)env\" // The `.` character will be prepended as long as the `env` property is defined.\n * \"env(-api)\" // The `-api` string will be appended as long as the `env` property is defined.\n * \"(api-)env(.)\" // The `api-` string and the `.` character will be added as long as\n * // the `env` property is defined.\n * ```\n * @internal\n */\nconst STRING_PARAMETER_CONTENT = new RegExp(`^${HEAD_OR_TAIL}([^(]+)${HEAD_OR_TAIL}$`, 'g');\n\n/**\n * Interpolates different parameters into a string.\n * The provided string can set the parameters to replace wrapping a parameter name in curly\n * braces. This will then be replaced by the parameter value as long as it is defined. If it\n * is not provided, the parameter name will just be removed from the final string.\n *\n * @param string - The string to interpolate different parameters in.\n * @param parameters - Value of the different parameters to interpolate.\n * @returns The interpolated string.\n * @example Different usages of the interpolate function.\n * ```js\n * interpolate('https://{env}.empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://live.empathy.co/demo'\n *\n * interpolate('https://{(api-)env}.empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api-live.empathy.co/demo'\n *\n * interpolate('https://api.{env(.)}empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api.live.empathy.co/demo'\n *\n * interpolate('https://{(api-)env(.)}empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api-live.empathy.co/demo'\n *\n * interpolate('https://{env}.empathy.co/{instance}', {\n * env: 'live'\n * }) // 'https://live.empathy.co/'\n *\n * interpolate('https://search{(api-)env}.empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://search.empathy.co/demo'\n *\n * interpolate('https://api.{env(.)}empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://api.empathy.co/demo'\n *\n * interpolate('https://search.{(api-)env(.)}empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://search.empathy.co/demo'\n * ```\n * @public\n */\nexport function interpolate(string: string, parameters: Record<string, unknown>): string {\n return string.replace(STRING_PARAMETERS, (_match, propertyToReplace: string) =>\n propertyToReplace.replace(\n STRING_PARAMETER_CONTENT,\n (_match, head = '', property: string, tail = '') => {\n const value = extractValue(parameters, property);\n /* As the replacer function has a very dynamic signature, it is typed as a function with\n * `any` arguments. This makes it impossible for TS to infer the correct `string`\n * type that we are using as default values here. */\n return value != null ? `${String(head)}${String(value)}${String(tail)}` : '';\n }\n )\n );\n}\n"]}
1
+ {"version":3,"file":"interpolate.js","sourceRoot":"","sources":["../../../src/utils/interpolate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,YAAY,GAAG,iBAAiB,CAAC;AACvC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,wBAAwB,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,UAAU,YAAY,GAAG,EAAE,GAAG,CAAC,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,UAAmC;IAC7E,OAAO,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,iBAAyB,EAAE,EAAE,CAC7E,iBAAiB,CAAC,OAAO,CACvB,wBAAwB,EACxB,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,QAAgB,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE;QACjD,MAAM,KAAK,GAAG,oBAAoB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACzD;;4DAEoD;QACpD,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,CAAC,CACF,CACF,CAAC;AACJ,CAAC","sourcesContent":["import { getSafePropertyChain } from '@empathyco/x-utils';\n\n/**\n * Syntax to detect and extract string parameters. A string parameter contains a property name\n * with an optional header or tail to concatenate wrapped in curly braces (`{}`).\n * The different parts of a string parameter are explained in {@link STRING_PARAMETER_CONTENT}.\n *\n * @example Different string parameters\n * ```js\n * \"\\{env\\}\" // No optional head or tail.\n * \"\\{(.)env\\}\" // Optional `.` head.\n * \"\\{env(-api)\\}\" // Optional `-api` tail.\n * \"\\{(api-)env(.)\\}\" // Optional `api-` head and `.` tail.\n * ```\n * @internal\n */\nconst STRING_PARAMETERS = /{([^}]+)}/g;\n\n/**\n * Shape of the optional head and tail parts of the {@link STRING_PARAMETER_CONTENT} regex.\n * This can be anything wrapped into parentheses.\n *\n * @internal\n */\nconst HEAD_OR_TAIL = '(?:\\\\((.+)\\\\))?';\n/**\n * Syntax of a single string parameter. A string parameter shape is composed by\n * the name of the property that should be replaced. This property name can be preceded\n * or followed by an optional string to prepend or to append to the property value\n * in case it is defined.\n *\n * @example Valid string parameters content\n * ```js\n * \"env\" // No optional head or tail to concatenate.\n * \"(.)env\" // The `.` character will be prepended as long as the `env` property is defined.\n * \"env(-api)\" // The `-api` string will be appended as long as the `env` property is defined.\n * \"(api-)env(.)\" // The `api-` string and the `.` character will be added as long as\n * // the `env` property is defined.\n * ```\n * @internal\n */\nconst STRING_PARAMETER_CONTENT = new RegExp(`^${HEAD_OR_TAIL}([^(]+)${HEAD_OR_TAIL}$`, 'g');\n\n/**\n * Interpolates different parameters into a string.\n * The provided string can set the parameters to replace wrapping a parameter name in curly\n * braces. This will then be replaced by the parameter value as long as it is defined. If it\n * is not provided, the parameter name will just be removed from the final string.\n *\n * @param string - The string to interpolate different parameters in.\n * @param parameters - Value of the different parameters to interpolate.\n * @returns The interpolated string.\n * @example Different usages of the interpolate function.\n * ```js\n * interpolate('https://{env}.empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://live.empathy.co/demo'\n *\n * interpolate('https://{(api-)env}.empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api-live.empathy.co/demo'\n *\n * interpolate('https://api.{env(.)}empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api.live.empathy.co/demo'\n *\n * interpolate('https://{(api-)env(.)}empathy.co/{instance}', {\n * env: 'live',\n * instance: 'demo'\n * }) // 'https://api-live.empathy.co/demo'\n *\n * interpolate('https://{env}.empathy.co/{instance}', {\n * env: 'live'\n * }) // 'https://live.empathy.co/'\n *\n * interpolate('https://search{(api-)env}.empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://search.empathy.co/demo'\n *\n * interpolate('https://api.{env(.)}empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://api.empathy.co/demo'\n *\n * interpolate('https://search.{(api-)env(.)}empathy.co/{instance}', {\n * instance: 'demo'\n * }) // 'https://search.empathy.co/demo'\n * ```\n * @public\n */\nexport function interpolate(string: string, parameters: Record<string, unknown>): string {\n return string.replace(STRING_PARAMETERS, (_match, propertyToReplace: string) =>\n propertyToReplace.replace(\n STRING_PARAMETER_CONTENT,\n (_match, head = '', property: string, tail = '') => {\n const value = getSafePropertyChain(parameters, property);\n /* As the replacer function has a very dynamic signature, it is typed as a function with\n * `any` arguments. This makes it impossible for TS to infer the correct `string`\n * type that we are using as default values here. */\n return value ? `${String(head)}${String(value)}${String(tail)}` : '';\n }\n )\n );\n}\n"]}
@@ -38,7 +38,7 @@ export interface ExtendableEndpointAdapter<Request, Response> extends EndpointAd
38
38
  * @returns A brand-new {@link ExtendableEndpointAdapter} instance.
39
39
  * @public
40
40
  */
41
- export declare type EndpointAdapterFactory = <Request, Response>(options: EndpointAdapterOptions<Request, Response>) => ExtendableEndpointAdapter<Request, Response>;
41
+ export type EndpointAdapterFactory = <Request, Response>(options: EndpointAdapterOptions<Request, Response>) => ExtendableEndpointAdapter<Request, Response>;
42
42
  /**
43
43
  * Options to create an adapter with.
44
44
  *
@@ -7,7 +7,7 @@ import { Dictionary } from '@empathyco/x-utils';
7
7
  * @returns A promise wrapped object containing the response.
8
8
  * @public
9
9
  */
10
- export declare type HttpClient = <Response = unknown>(endpoint: string, options?: Omit<RequestOptions, 'endpoint'>) => Promise<Readonly<Response>>;
10
+ export type HttpClient = <Response = unknown>(endpoint: string, options?: Omit<RequestOptions, 'endpoint'>) => Promise<Readonly<Response>>;
11
11
  /**
12
12
  * A record of options to make the request with.
13
13
  *
@@ -1,4 +1,4 @@
1
- import { Schema } from '../schemas/types';
1
+ import { MutableSchema, Schema } from '../schemas/types';
2
2
  import { Mapper } from './types';
3
3
  /**
4
4
  * The 'schemaMapperFactory' function creates a {@link Mapper | mapper function} for a given
@@ -8,4 +8,4 @@ import { Mapper } from './types';
8
8
  * @returns A {@link Mapper | mapper function} that applies the given {@link Schema | schema}.
9
9
  * @public
10
10
  */
11
- export declare function schemaMapperFactory<Source, Target>(schema: Schema<Source, Target>): Mapper<Source, Target>;
11
+ export declare function schemaMapperFactory<Source, Target>(schema: Schema<Source, Target> | MutableSchema<Source, Target>): Mapper<Source, Target>;
@@ -5,7 +5,7 @@
5
5
  * @returns A new value created using the data in the `context` or in the `from` parameters.
6
6
  * @public
7
7
  */
8
- export declare type Mapper<From, To> = (from: Readonly<From>, context: MapperContext) => To;
8
+ export type Mapper<From, To> = (from: Readonly<From>, context: MapperContext) => To;
9
9
  /**
10
10
  * The context is an object that can be used to share information between the invocation of
11
11
  * different mappers or the process that they are being executed on.