mirror of
https://gitverse.ru/kpa39l/telepost.git
synced 2026-09-29 09:55:09 +00:00
152 lines
3.3 KiB
JavaScript
152 lines
3.3 KiB
JavaScript
// Manually “tree shaken” from:
|
|
// <https://github.com/nodejs/node/blob/3e74590/lib/internal/modules/esm/get_format.js>
|
|
// Last checked on: Apr 24, 2023.
|
|
|
|
import {URL, fileURLToPath} from 'node:url'
|
|
import {getPackageType} from './resolve-get-package-type.js'
|
|
import {codes} from './errors.js'
|
|
|
|
const {ERR_UNKNOWN_FILE_EXTENSION} = codes
|
|
|
|
const hasOwnProperty = {}.hasOwnProperty
|
|
|
|
/** @type {Record<string, string>} */
|
|
const extensionFormatMap = {
|
|
// @ts-expect-error: hush.
|
|
__proto__: null,
|
|
'.cjs': 'commonjs',
|
|
'.js': 'module',
|
|
'.json': 'json',
|
|
'.mjs': 'module'
|
|
}
|
|
|
|
/**
|
|
* @param {string | null} mime
|
|
* @returns {string | null}
|
|
*/
|
|
function mimeToFormat(mime) {
|
|
if (
|
|
mime &&
|
|
/\s*(text|application)\/javascript\s*(;\s*charset=utf-?8\s*)?/i.test(mime)
|
|
)
|
|
return 'module'
|
|
if (mime === 'application/json') return 'json'
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* @callback ProtocolHandler
|
|
* @param {URL} parsed
|
|
* @param {{parentURL: string}} context
|
|
* @param {boolean} ignoreErrors
|
|
* @returns {string | null | void}
|
|
*/
|
|
|
|
/**
|
|
* @type {Record<string, ProtocolHandler>}
|
|
*/
|
|
const protocolHandlers = {
|
|
// @ts-expect-error: hush.
|
|
__proto__: null,
|
|
'data:': getDataProtocolModuleFormat,
|
|
'file:': getFileProtocolModuleFormat,
|
|
'http:': getHttpProtocolModuleFormat,
|
|
'https:': getHttpProtocolModuleFormat,
|
|
'node:'() {
|
|
return 'builtin'
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param {URL} parsed
|
|
*/
|
|
function getDataProtocolModuleFormat(parsed) {
|
|
const {1: mime} = /^([^/]+\/[^;,]+)[^,]*?(;base64)?,/.exec(
|
|
parsed.pathname
|
|
) || [null, null, null]
|
|
return mimeToFormat(mime)
|
|
}
|
|
|
|
/**
|
|
* Returns the file extension from a URL.
|
|
*
|
|
* Should give similar result to
|
|
* `require('node:path').extname(require('node:url').fileURLToPath(url))`
|
|
* when used with a `file:` URL.
|
|
*
|
|
* @param {URL} url
|
|
* @returns {string}
|
|
*/
|
|
function extname(url) {
|
|
const pathname = url.pathname
|
|
let index = pathname.length
|
|
|
|
while (index--) {
|
|
const code = pathname.codePointAt(index)
|
|
|
|
if (code === 47 /* `/` */) {
|
|
return ''
|
|
}
|
|
|
|
if (code === 46 /* `.` */) {
|
|
return pathname.codePointAt(index - 1) === 47 /* `/` */
|
|
? ''
|
|
: pathname.slice(index)
|
|
}
|
|
}
|
|
|
|
return ''
|
|
}
|
|
|
|
/**
|
|
* @type {ProtocolHandler}
|
|
*/
|
|
function getFileProtocolModuleFormat(url, _context, ignoreErrors) {
|
|
const ext = extname(url)
|
|
|
|
if (ext === '.js') {
|
|
return getPackageType(url) === 'module' ? 'module' : 'commonjs'
|
|
}
|
|
|
|
const format = extensionFormatMap[ext]
|
|
if (format) return format
|
|
|
|
// Explicit undefined return indicates load hook should rerun format check
|
|
if (ignoreErrors) {
|
|
return undefined
|
|
}
|
|
|
|
const filepath = fileURLToPath(url)
|
|
throw new ERR_UNKNOWN_FILE_EXTENSION(ext, filepath)
|
|
}
|
|
|
|
function getHttpProtocolModuleFormat() {
|
|
// To do: HTTPS imports.
|
|
}
|
|
|
|
/**
|
|
* @param {URL} url
|
|
* @param {{parentURL: string}} context
|
|
* @returns {string | null}
|
|
*/
|
|
export function defaultGetFormatWithoutErrors(url, context) {
|
|
if (!hasOwnProperty.call(protocolHandlers, url.protocol)) {
|
|
return null
|
|
}
|
|
|
|
return protocolHandlers[url.protocol](url, context, true) || null
|
|
}
|
|
|
|
/**
|
|
* @param {string} url
|
|
* @param {{parentURL: string}} context
|
|
* @returns {null | string | void}
|
|
*/
|
|
export function defaultGetFormat(url, context) {
|
|
const parsed = new URL(url)
|
|
|
|
return hasOwnProperty.call(protocolHandlers, parsed.protocol)
|
|
? protocolHandlers[parsed.protocol](parsed, context, false)
|
|
: null
|
|
}
|