Orginize
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* Install holepunch fetch on globalThis when the host has no native fetch (Pear/Bare).
|
||||
* Dynamic `import('bare-fetch')` from deep modules can fail on Pear; resolving to an
|
||||
* absolute URL via import.meta.resolve first avoids that.
|
||||
*/
|
||||
|
||||
/** @type {boolean} */
|
||||
let installTried = false
|
||||
|
||||
/**
|
||||
* Legacy bundles stored the whole CJS interop object on `ctx.bare.fetch` instead of
|
||||
* the default export; unwrap when needed.
|
||||
* @param {unknown} x
|
||||
* @returns {typeof fetch | null}
|
||||
*/
|
||||
export function coerceBareFetchExport(x) {
|
||||
if (typeof x === 'function') return /** @type {typeof fetch} */ (x)
|
||||
if (x && typeof x === 'object' && typeof /** @type {{ default?: unknown }} */ (x).default === 'function')
|
||||
return /** @type {typeof fetch} */ (/** @type {{ default: typeof fetch }} */ (x).default)
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} f
|
||||
*/
|
||||
function applyFetchToGlobals(f) {
|
||||
globalThis.fetch = f
|
||||
if (f.Request) globalThis.Request = f.Request
|
||||
if (f.Response) globalThis.Response = f.Response
|
||||
if (f.Headers) globalThis.Headers = f.Headers
|
||||
if (typeof global !== 'undefined') {
|
||||
global.fetch = f
|
||||
if (f.Request) global.Request = f.Request
|
||||
if (f.Response) global.Response = f.Response
|
||||
if (f.Headers) global.Headers = f.Headers
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamic `import(specifier)` from nested modules can fail on Pear ("Cannot find referrer");
|
||||
* resolving to an absolute URL via `import.meta.resolve` first fixes that. Tries parent-aware
|
||||
* resolve when supported, then bare specifier.
|
||||
* @param {string} specifier
|
||||
* @returns {Promise<Record<string, unknown>>}
|
||||
*/
|
||||
export async function importResolvedOrBare(specifier) {
|
||||
if (typeof import.meta.resolve === 'function') {
|
||||
try {
|
||||
return await import(
|
||||
import.meta.resolve(specifier, import.meta.url)
|
||||
)
|
||||
} catch {
|
||||
try {
|
||||
return await import(import.meta.resolve(specifier))
|
||||
} catch {
|
||||
/* fall through */
|
||||
}
|
||||
}
|
||||
}
|
||||
return await import(specifier)
|
||||
}
|
||||
|
||||
/**
|
||||
* Use fetch from the system image **`/lib/bare/bundles/fetch.js`** (merged into `ctx.bare`)
|
||||
* when the host has no global fetch (typical Pear/Bare).
|
||||
* @param {Record<string, unknown>} bareLibrary
|
||||
* @returns {boolean} true if globals were updated
|
||||
*/
|
||||
export function primeGlobalFetchFromBareLibrary(bareLibrary) {
|
||||
if (typeof globalThis.fetch === 'function') return false
|
||||
const f = coerceBareFetchExport(bareLibrary && bareLibrary.fetch)
|
||||
if (f) {
|
||||
applyFetchToGlobals(f)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer policy-wrapped **`ctx.httpFetch`**, then **`ctx.bare.fetch`** (drive bundle), then global fetch.
|
||||
* @param {Record<string, unknown>} ctx
|
||||
* @returns {typeof fetch | null}
|
||||
*/
|
||||
export function resolveBareOsFetchFn(ctx) {
|
||||
if (typeof ctx.httpFetch === 'function')
|
||||
return /** @type {typeof fetch} */ (ctx.httpFetch)
|
||||
const bare = coerceBareFetchExport(ctx.bare && ctx.bare.fetch)
|
||||
if (bare) return bare.bind(ctx.bare)
|
||||
if (typeof globalThis.fetch === 'function')
|
||||
return globalThis.fetch.bind(globalThis)
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} [ctx]
|
||||
*/
|
||||
export async function ensureBareFetchGlobals(ctx) {
|
||||
if (typeof globalThis.fetch === 'function') return
|
||||
const fromBare = coerceBareFetchExport(ctx?.bare && ctx.bare.fetch)
|
||||
if (fromBare) {
|
||||
applyFetchToGlobals(fromBare)
|
||||
return
|
||||
}
|
||||
if (installTried) return
|
||||
installTried = true
|
||||
|
||||
try {
|
||||
const m = await importResolvedOrBare('bare-fetch')
|
||||
const f = m.default
|
||||
if (typeof f === 'function') applyFetchToGlobals(f)
|
||||
} catch {
|
||||
/* bare-fetch optional when not on Bare / not bundled */
|
||||
}
|
||||
|
||||
if (typeof globalThis.fetch === 'function') return
|
||||
|
||||
try {
|
||||
const m = await importResolvedOrBare('bare-https')
|
||||
const f = m.default?.fetch || m.fetch
|
||||
if (typeof f === 'function') {
|
||||
globalThis.fetch = f
|
||||
if (typeof global !== 'undefined') global.fetch = f
|
||||
}
|
||||
} catch {
|
||||
/* bare-https optional */
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user