Skip to content

Instantly share code, notes, and snippets.

@kurtbuilds
Created November 23, 2021 17:11
Show Gist options
  • Save kurtbuilds/0761ac9b76947d650e25b01fb1eae91a to your computer and use it in GitHub Desktop.
Save kurtbuilds/0761ac9b76947d650e25b01fb1eae91a to your computer and use it in GitHub Desktop.
import {Configuration, ModelError, PlaidApi, PlaidEnvironments} from "plaid";
import axios, {AxiosRequestConfig, AxiosResponse} from 'axios'
import * as fs from 'fs/promises'
const ENV = process.env
const PLAID_ENV = ENV.PLAID_ENV!
export class PlaidError extends Error {
name = 'PlaidError'
model_error: ModelError
constructor(model_error: ModelError) {
super(model_error.error_code)
this.model_error = model_error
}
}
export const client = new PlaidApi(new Configuration({
basePath: PlaidEnvironments[PLAID_ENV],
baseOptions: {
headers: {
'PLAID-CLIENT-ID': ENV.PLAID_CLIENT_ID,
'PLAID-SECRET': ENV.PLAID_SECRET,
}
}
}))
export function deep_equal(object1: any, object2: any): boolean {
const keys1 = Object.keys(object1)
const keys2 = Object.keys(object2)
if (keys1.length !== keys2.length) {
return false
}
for (const key of keys1) {
const val1 = object1[key]
const val2 = object2[key]
const areObjects = is_object(val1) && is_object(val2)
if (
areObjects && !deep_equal(val1, val2) ||
!areObjects && val1 !== val2
) {
return false
}
}
return true
}
function is_object(o: any): boolean {
return o != null && typeof o === 'object'
}
const FREEZER = {} as any
export function activate_axios_recording_hook() {
FREEZER.unhooked_axios_request = axios.request
axios.request = async function<T = any, R = AxiosResponse<T>>(config: AxiosRequestConfig): Promise<R> {
let url = new URL(config.url!)
let fpath = `data/${url.host}${url.pathname}`
await fs.mkdir(fpath, {recursive: true})
let files = await fs.readdir(fpath)
for (const f of files) {
let data = JSON.parse((await fs.readFile(fpath + '/' + f)).toString())
if (deep_equal(data.request, config)) {
if (data.response.status >= 400) {
throw data
} else {
return data.response
}
}
}
let max = Math.max(0, ...files.map(fname => parseInt(fname))) + 1
let r = await FREEZER.unhooked_axios_request(config)
let out_fpath = `${fpath}/${max}.json`
await fs.writeFile(out_fpath, JSON.stringify({
request: config,
response: {
status: r.status,
statusText: r.statusText,
headers: r.headers,
data: r.data
}
}, null, 2))
console.log(`${out_fpath}: Wrote request to file.`)
return r as any as Promise<R>
}
}
export function disable_axios_recording_hook() {
if (FREEZER.unhooked_axios_request) {
axios.request = FREEZER.unhooked_axios_request
delete FREEZER.unhooked_axios_request
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment