123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- import { combineLatest, Observable } from "rxjs"
- import { map } from "rxjs/operators"
- import { FormDataKeyValue, HoppRESTRequest } from "../types/HoppRESTRequest"
- import parseTemplateString from "../templating"
- import { Environment, getGlobalVariables } from "~/newstore/environments"
- export interface EffectiveHoppRESTRequest extends HoppRESTRequest {
- /**
- * The effective final URL.
- *
- * This contains path, params and environment variables all applied to it
- */
- effectiveFinalURL: string
- effectiveFinalHeaders: { key: string; value: string }[]
- effectiveFinalParams: { key: string; value: string }[]
- effectiveFinalBody: FormData | string | null
- }
- function getFinalBodyFromRequest(
- request: HoppRESTRequest,
- env: Environment
- ): FormData | string | null {
- if (request.body.contentType === null) {
- return null
- }
- if (request.body.contentType === "multipart/form-data") {
- const formData = new FormData()
- request.body.body
- .filter((x) => x.key !== "" && x.active) // Remove empty keys
- .map(
- (x) =>
- <FormDataKeyValue>{
- active: x.active,
- isFile: x.isFile,
- key: parseTemplateString(x.key, env.variables),
- value: x.isFile
- ? x.value
- : parseTemplateString(x.value, env.variables),
- }
- )
- .forEach((entry) => {
- if (!entry.isFile) formData.append(entry.key, entry.value)
- else entry.value.forEach((blob) => formData.append(entry.key, blob))
- })
- return formData
- } else return request.body.body
- }
- /**
- * Outputs an executable request format with environment variables applied
- *
- * @param request The request to source from
- * @param environment The environment to apply
- *
- * @returns An object with extra fields defining a complete request
- */
- export function getEffectiveRESTRequest(
- request: HoppRESTRequest,
- environment: Environment
- ): EffectiveHoppRESTRequest {
- const envVariables = [...environment.variables, ...getGlobalVariables()]
- const effectiveFinalHeaders = request.headers
- .filter(
- (x) =>
- x.key !== "" && // Remove empty keys
- x.active // Only active
- )
- .map((x) => ({
- // Parse out environment template strings
- active: true,
- key: parseTemplateString(x.key, envVariables),
- value: parseTemplateString(x.value, envVariables),
- }))
- // Authentication
- if (request.auth.authActive) {
- // TODO: Support a better b64 implementation than btoa ?
- if (request.auth.authType === "basic") {
- const username = parseTemplateString(request.auth.username, envVariables)
- const password = parseTemplateString(request.auth.password, envVariables)
- effectiveFinalHeaders.push({
- active: true,
- key: "Authorization",
- value: `Basic ${btoa(`${username}:${password}`)}`,
- })
- } else if (
- request.auth.authType === "bearer" ||
- request.auth.authType === "oauth-2"
- ) {
- effectiveFinalHeaders.push({
- active: true,
- key: "Authorization",
- value: `Bearer ${parseTemplateString(
- request.auth.token,
- envVariables
- )}`,
- })
- }
- }
- const effectiveFinalBody = getFinalBodyFromRequest(request, environment)
- if (request.body.contentType)
- effectiveFinalHeaders.push({
- active: true,
- key: "content-type",
- value: request.body.contentType,
- })
- return {
- ...request,
- effectiveFinalURL: parseTemplateString(request.endpoint, envVariables),
- effectiveFinalHeaders,
- effectiveFinalParams: request.params
- .filter(
- (x) =>
- x.key !== "" && // Remove empty keys
- x.active // Only active
- )
- .map((x) => ({
- active: true,
- key: parseTemplateString(x.key, envVariables),
- value: parseTemplateString(x.value, envVariables),
- })),
- effectiveFinalBody,
- }
- }
- /**
- * Creates an Observable Stream that emits HoppRESTRequests whenever
- * the input streams emit a value
- *
- * @param request$ The request stream containing request data
- * @param environment$ The environment stream containing environment data to apply
- *
- * @returns Observable Stream for the Effective Request Object
- */
- export function getEffectiveRESTRequestStream(
- request$: Observable<HoppRESTRequest>,
- environment$: Observable<Environment>
- ): Observable<EffectiveHoppRESTRequest> {
- return combineLatest([request$, environment$]).pipe(
- map(([request, env]) => getEffectiveRESTRequest(request, env))
- )
- }
|