{"version":3,"file":"EncryptedFetcher.mjs","names":[],"sources":["../src/EncryptedFetcher.ts"],"sourcesContent":["import { AesPkcs5 } from \"./AesPkcs5\";\nimport { IConnection } from \"./IConnection\";\nimport { IEncryptionPassword } from \"./IEncryptionPassword\";\nimport { IFetchRoute } from \"./IFetchRoute\";\nimport { IPropagation } from \"./IPropagation\";\nimport { FetcherBase } from \"./internal/FetcherBase\";\n\n/**\n * Utility class for `fetch` functions used in `@nestia/sdk` with encryption.\n *\n * `EncryptedFetcher` is a utility class designed for SDK functions generated by\n * [`@nestia/sdk`](https://nestia.io/docs/sdk/sdk), interacting with the remote\n * HTTP API encrypted by AES-PKCS algorithm. In other words, this is a\n * collection of dedicated `fetch()` functions for `@nestia/sdk` with\n * encryption.\n *\n * For reference, `EncryptedFetcher` class being used only when target\n * controller method is encrypting body data by `@EncryptedRoute` or\n * `@EncryptedBody` decorators. If those decorators are not used,\n * {@link PlainFetcher} class would be used instead.\n *\n * @author Jeongho Nam - https://github.com/samchon\n */\nexport namespace EncryptedFetcher {\n  /**\n   * Fetch function only for `HEAD` method.\n   *\n   * @param connection Connection information for the remote HTTP server\n   * @param route Route information about the target API\n   * @returns Nothing because of `HEAD` method\n   */\n  export function fetch(\n    connection: IConnection,\n    route: IFetchRoute<\"HEAD\">,\n  ): Promise<void>;\n\n  /**\n   * Fetch function only for `GET` method.\n   *\n   * @param connection Connection information for the remote HTTP server\n   * @param route Route information about the target API\n   * @returns Response body data from the remote API\n   */\n  export function fetch<Output>(\n    connection: IConnection,\n    route: IFetchRoute<\"GET\">,\n  ): Promise<Output>;\n\n  /**\n   * Fetch function for the `POST`, `PUT`, `PATCH` and `DELETE` methods.\n   *\n   * @param connection Connection information for the remote HTTP server\n   * @param route Route information about the target API\n   * @returns Response body data from the remote API\n   */\n  export function fetch<Input, Output>(\n    connection: IConnection,\n    route: IFetchRoute<\"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\">,\n    input?: Input,\n    stringify?: (input: Input) => string,\n  ): Promise<Output>;\n\n  export async function fetch<Input, Output>(\n    connection: IConnection,\n    route: IFetchRoute<\"DELETE\" | \"GET\" | \"HEAD\" | \"PATCH\" | \"POST\" | \"PUT\">,\n    input?: Input,\n    stringify?: (input: Input) => string,\n  ): Promise<Output> {\n    if (\n      (route.request?.encrypted === true || route.response?.encrypted) &&\n      connection.encryption === undefined\n    )\n      throw new Error(\n        \"Error on EncryptedFetcher.fetch(): the encryption password has not been configured.\",\n      );\n    const closure =\n      typeof connection.encryption === \"function\"\n        ? (direction: \"encode\" | \"decode\") =>\n            (\n              headers: Record<string, IConnection.HeaderValue | undefined>,\n              body: string,\n            ) =>\n              (connection.encryption as IEncryptionPassword.Closure)({\n                headers,\n                body,\n                direction,\n              })\n        : () => () => connection.encryption as IEncryptionPassword;\n\n    return FetcherBase.request({\n      className: \"EncryptedFetcher\",\n      encode:\n        route.request?.encrypted === true\n          ? (input, headers) => {\n              const p: IEncryptionPassword = closure(\"encode\")(headers, input);\n              return AesPkcs5.encrypt(\n                (stringify ?? JSON.stringify)(input),\n                p.key,\n                p.iv,\n              );\n            }\n          : (input) => input,\n      decode:\n        route.response?.encrypted === true\n          ? (input, headers) => {\n              const p: IEncryptionPassword = closure(\"decode\")(headers, input);\n              const s: string = AesPkcs5.decrypt(input, p.key, p.iv);\n              return s.length ? JSON.parse(s) : s;\n            }\n          : (input) => input,\n    })(connection, route, input, stringify);\n  }\n\n  export function propagate<Output extends IPropagation<any, any>>(\n    connection: IConnection,\n    route: IFetchRoute<\"GET\" | \"HEAD\">,\n  ): Promise<Output>;\n\n  export function propagate<Input, Output extends IPropagation<any, any>>(\n    connection: IConnection,\n    route: IFetchRoute<\"DELETE\" | \"GET\" | \"HEAD\" | \"PATCH\" | \"POST\" | \"PUT\">,\n    input?: Input,\n    stringify?: (input: Input) => string,\n  ): Promise<Output>;\n\n  export async function propagate<Input, Output extends IPropagation<any, any>>(\n    connection: IConnection,\n    route: IFetchRoute<\"DELETE\" | \"GET\" | \"HEAD\" | \"PATCH\" | \"POST\" | \"PUT\">,\n    input?: Input,\n    stringify?: (input: Input) => string,\n  ): Promise<Output> {\n    if (\n      (route.request?.encrypted === true || route.response?.encrypted) &&\n      connection.encryption === undefined\n    )\n      throw new Error(\n        \"Error on EncryptedFetcher.propagate(): the encryption password has not been configured.\",\n      );\n    const closure =\n      typeof connection.encryption === \"function\"\n        ? (direction: \"encode\" | \"decode\") =>\n            (\n              headers: Record<string, IConnection.HeaderValue | undefined>,\n              body: string,\n            ) =>\n              (connection.encryption as IEncryptionPassword.Closure)({\n                headers,\n                body,\n                direction,\n              })\n        : () => () => connection.encryption as IEncryptionPassword;\n\n    return FetcherBase.propagate({\n      className: \"EncryptedFetcher\",\n      encode:\n        route.request?.encrypted === true\n          ? (input, headers) => {\n              const p: IEncryptionPassword = closure(\"encode\")(headers, input);\n              return AesPkcs5.encrypt(\n                (stringify ?? JSON.stringify)(input),\n                p.key,\n                p.iv,\n              );\n            }\n          : (input) => input,\n      decode:\n        route.response?.encrypted === true\n          ? (input, headers) => {\n              const p: IEncryptionPassword = closure(\"decode\")(headers, input);\n              const s: string = AesPkcs5.decrypt(input, p.key, p.iv);\n              return s.length ? JSON.parse(s) : s;\n            }\n          : (input) => input,\n    })(connection, route, input, stringify) as Promise<Output>;\n  }\n}\n"],"mappings":";;;AAuBO,IAAA;;CAuCE,eAAe,MACpB,YACA,OACA,OACA,WACiB;EACjB,KACG,MAAM,SAAS,cAAc,QAAQ,MAAM,UAAU,cACtD,WAAW,eAAe,KAAA,GAE1B,MAAM,IAAI,MACR,qFACF;EACF,MAAM,UACJ,OAAO,WAAW,eAAe,cAC5B,eAEG,SACA,SAEC,WAAW,WAA2C;GACrD;GACA;GACA;EACF,CAAC,gBACO,WAAW;EAE7B,OAAO,YAAY,QAAQ;GACzB,WAAW;GACX,QACE,MAAM,SAAS,cAAc,QACxB,OAAO,YAAY;IAClB,MAAM,IAAyB,QAAQ,QAAQ,CAAC,CAAC,SAAS,KAAK;IAC/D,OAAO,SAAS,SACb,aAAa,KAAK,UAAA,CAAW,KAAK,GACnC,EAAE,KACF,EAAE,EACJ;GACF,KACC,UAAU;GACjB,QACE,MAAM,UAAU,cAAc,QACzB,OAAO,YAAY;IAClB,MAAM,IAAyB,QAAQ,QAAQ,CAAC,CAAC,SAAS,KAAK;IAC/D,MAAM,IAAY,SAAS,QAAQ,OAAO,EAAE,KAAK,EAAE,EAAE;IACrD,OAAO,EAAE,SAAS,KAAK,MAAM,CAAC,IAAI;GACpC,KACC,UAAU;EACnB,CAAC,CAAC,CAAC,YAAY,OAAO,OAAO,SAAS;CACxC;;CAcO,eAAe,UACpB,YACA,OACA,OACA,WACiB;EACjB,KACG,MAAM,SAAS,cAAc,QAAQ,MAAM,UAAU,cACtD,WAAW,eAAe,KAAA,GAE1B,MAAM,IAAI,MACR,yFACF;EACF,MAAM,UACJ,OAAO,WAAW,eAAe,cAC5B,eAEG,SACA,SAEC,WAAW,WAA2C;GACrD;GACA;GACA;EACF,CAAC,gBACO,WAAW;EAE7B,OAAO,YAAY,UAAU;GAC3B,WAAW;GACX,QACE,MAAM,SAAS,cAAc,QACxB,OAAO,YAAY;IAClB,MAAM,IAAyB,QAAQ,QAAQ,CAAC,CAAC,SAAS,KAAK;IAC/D,OAAO,SAAS,SACb,aAAa,KAAK,UAAA,CAAW,KAAK,GACnC,EAAE,KACF,EAAE,EACJ;GACF,KACC,UAAU;GACjB,QACE,MAAM,UAAU,cAAc,QACzB,OAAO,YAAY;IAClB,MAAM,IAAyB,QAAQ,QAAQ,CAAC,CAAC,SAAS,KAAK;IAC/D,MAAM,IAAY,SAAS,QAAQ,OAAO,EAAE,KAAK,EAAE,EAAE;IACrD,OAAO,EAAE,SAAS,KAAK,MAAM,CAAC,IAAI;GACpC,KACC,UAAU;EACnB,CAAC,CAAC,CAAC,YAAY,OAAO,OAAO,SAAS;CACxC;;GACD,qBAAA,mBAAA,CAAA,EAAD"}