import { path as deno_path } from '../external/std.ts' import * as Mime from 'https://deno.land/x/media_types/mod.ts' export enum UniversalPathPrefix { HTTP = 'http://', HTTPS = 'https://', Local = 'file://', } export type PathLike = string | UniversalPath export function universal_path(...parts: PathLike[]): UniversalPath { let [main, ...concats] = parts if ( !(main instanceof UniversalPath) ) main = new UniversalPath(main) return main.concat(...concats) } export class UniversalPath { protected _prefix!: UniversalPathPrefix protected _local!: string constructor( protected readonly initial: string, ) { this.set_prefix() this.set_local() } protected set_prefix() { if ( this.initial.toLowerCase().startsWith('http://') ) { this._prefix = UniversalPathPrefix.HTTP } else if ( this.initial.toLowerCase().startsWith('https://') ) { this._prefix = UniversalPathPrefix.HTTPS } else { this._prefix = UniversalPathPrefix.Local } } protected set_local() { this._local = this.initial if ( this.initial.toLowerCase().startsWith(this._prefix) ) { this._local = this._local.slice(this._prefix.length) } if ( this._prefix === UniversalPathPrefix.Local && !this._local.startsWith('/') ) { this._local = deno_path.resolve(this._local) } } get prefix() { return this._prefix } get is_local() { return this._prefix === UniversalPathPrefix.Local } get is_remote() { return this._prefix !== UniversalPathPrefix.Local } get unqualified() { return this._local } get to_local() { if ( this.is_local ) { return this._local } else { return `${this.prefix}${this._local}` } } get to_remote() { return `${this.prefix}${this._local}` } public concat(...paths: PathLike[]): UniversalPath { const resolved = deno_path.join(this.unqualified, ...(paths.map(p => typeof p === 'string' ? p : p.unqualified))) return new UniversalPath(`${this.prefix}${resolved}`) } public append(path: PathLike): this { this._local += String(path) return this } toString() { return `${this.prefix}${this._local}` } get ext() { return deno_path.extname(this._local) } get mime_type() { return Mime.lookup(this.ext) } get content_type() { return Mime.contentType(this.ext) } get charset() { if ( this.mime_type ) { return Mime.charset(this.mime_type) } } }