Created
April 21, 2024 18:11
-
-
Save guest271314/72a0ad0220f8b93f10d816bc084f7881 to your computer and use it in GitHub Desktop.
L-Blondy up-fetch bundled with bun buil
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// response-error.ts | |
class ResponseError extends Error { | |
name; | |
response; | |
options; | |
data; | |
constructor(res, data, options) { | |
super(`Request failed with status ${res.status}`); | |
this.data = data; | |
this.name = "ResponseError"; | |
this.response = res; | |
this.options = options; | |
} | |
} | |
var isResponseError = (error) => error instanceof ResponseError; | |
// default-options.ts | |
var defaultOptions = { | |
parseResponse: (res) => res.clone().json().catch(() => res.text()).then((data) => data || null), | |
parseResponseError: async (res, options) => new ResponseError(res, await defaultOptions.parseResponse(res, {}), options), | |
serializeParams: (params) => new URLSearchParams(JSON.parse(JSON.stringify(params))).toString(), | |
serializeBody: (val) => JSON.stringify(val) | |
}; | |
// utils.ts | |
var mergeHeaders = (...headerInits) => { | |
let res = {}; | |
headerInits.forEach((init) => { | |
new Headers(init).forEach((value, key) => { | |
if (value === "null" || value === "undefined") { | |
delete res[key]; | |
} else { | |
res[key] = value; | |
} | |
}); | |
}); | |
return res; | |
}; | |
var buildParams = (upParams, input, fetcherParams) => isRequest(input) ? {} : strip({ | |
...strip(upParams, [ | |
...new URL(input, "http://a").searchParams.keys() | |
]), | |
...fetcherParams | |
}); | |
var strip = (obj, keys = []) => { | |
let copy = { ...obj }; | |
for (let key in copy) { | |
if (keys.includes(key) || copy[key] === undefined) | |
delete copy[key]; | |
} | |
return copy; | |
}; | |
var isJsonifiableObjectOrArray = (body) => { | |
if (!body || typeof body !== "object") | |
return false; | |
return body?.constructor?.name === "Object" || Array.isArray(body) || typeof body?.toJSON === "function"; | |
}; | |
var withPrefix = (prefix, str) => !str ? "" : str.startsWith(prefix) ? str : `${prefix}${str}`; | |
var isRequest = (input) => { | |
return !!input.url; | |
}; | |
var emptyOptions = {}; | |
// build-options.ts | |
var eventListeners = [ | |
"onSuccess", | |
"onBeforeFetch", | |
"onParsingError", | |
"onResponseError", | |
"onRequestError" | |
]; | |
var buildOptions = (input, upOpts = emptyOptions, fetcherOpts = emptyOptions) => ({ | |
...{}, | |
...defaultOptions, | |
...strip(upOpts, eventListeners), | |
...strip(fetcherOpts, eventListeners), | |
headers: mergeHeaders(isJsonifiableObjectOrArray(fetcherOpts.body) ? { "content-type": "application/json" } : {}, upOpts.headers, fetcherOpts.headers), | |
params: buildParams(upOpts.params, input, fetcherOpts.params), | |
rawBody: fetcherOpts.body, | |
get body() { | |
return isJsonifiableObjectOrArray(this.rawBody) ? this.serializeBody(this.rawBody) : this.rawBody; | |
}, | |
get input() { | |
if (isRequest(input)) | |
return input; | |
if (input instanceof URL) | |
return input.toString(); | |
let base = this.baseUrl ? new URL(this.baseUrl) : undefined; | |
let path = [base?.pathname, input.toString()].map((str) => str?.startsWith("/") ? str.slice(1) : str).filter(Boolean).join("/"); | |
let url = new URL(path, base?.origin); | |
let serializedParams = this.serializeParams(this.params); | |
return `${url.href}${withPrefix(url.search ? "&" : "?", serializedParams)}`; | |
} | |
}); | |
// up.ts | |
function up(fetchFn, getUpOptions = () => emptyOptions) { | |
return (input, upfetchOptions = emptyOptions) => { | |
let upOptions = getUpOptions(); | |
let upfetchOpts = typeof upfetchOptions === "function" ? upfetchOptions(upOptions) : upfetchOptions; | |
let options = buildOptions(input, upOptions, upfetchOpts); | |
upfetchOpts.onBeforeFetch?.(options); | |
upOptions.onBeforeFetch?.(options); | |
return fetchFn(options.input, options).catch((error) => { | |
upfetchOpts.onRequestError?.(error, options); | |
upOptions.onRequestError?.(error, options); | |
throw error; | |
}).then(async (res) => { | |
if (res.ok) { | |
let data; | |
try { | |
data = await options.parseResponse(res, options); | |
} catch (error) { | |
upfetchOpts.onParsingError?.(error, options); | |
upOptions.onParsingError?.(error, options); | |
throw error; | |
} | |
upfetchOpts.onSuccess?.(data, options); | |
upOptions.onSuccess?.(data, options); | |
return data; | |
} else { | |
let respError; | |
try { | |
respError = await options.parseResponseError(res, options); | |
} catch (error) { | |
upfetchOpts.onParsingError?.(error, options); | |
upOptions.onParsingError?.(error, options); | |
throw error; | |
} | |
upfetchOpts.onResponseError?.(respError, options); | |
upOptions.onResponseError?.(respError, options); | |
throw respError; | |
} | |
}); | |
}; | |
} | |
// parsers/zod.ts | |
function withZod(schema) { | |
return async (response, options) => schema.parse(await defaultOptions.parseResponse(response, options)); | |
} | |
// ../node_modules/valibot/dist/index.js | |
var getGlobalConfig = function(config) { | |
return { | |
lang: config?.lang ?? store?.lang, | |
message: config?.message, | |
abortEarly: config?.abortEarly ?? store?.abortEarly, | |
abortPipeEarly: config?.abortPipeEarly ?? store?.abortPipeEarly, | |
skipPipe: config?.skipPipe ?? store?.skipPipe | |
}; | |
}; | |
var parse = function(schema, input, config) { | |
const result = schema._parse(input, getGlobalConfig(config)); | |
if (result.issues) { | |
throw new ValiError(result.issues); | |
} | |
return result.output; | |
}; | |
var ValiError = class extends Error { | |
issues; | |
constructor(issues) { | |
super(issues[0].message); | |
this.name = "ValiError"; | |
this.issues = issues; | |
} | |
}; | |
var BrandSymbol = Symbol("brand"); | |
var store; | |
// parsers/valibot.ts | |
function withValibot(schema) { | |
return async (response, options) => parse(schema, await defaultOptions.parseResponse(response, options)); | |
} | |
export { | |
withZod, | |
withValibot, | |
up, | |
isResponseError, | |
defaultOptions, | |
ResponseError | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment