UNPKG

spica

Version:

Supervisor, Coroutine, Channel, select, AtomicPromise, Cancellation, Cache, List, Queue, Stack, and some utils.

122 lines (117 loc) 4.61 kB
import { AbsoluteURL, ReadonlyURL } from './url/internal'; export { StandardURL, standardize } from './url/internal'; export { ReadonlyURL } from './url/internal'; type Widen<T> = T extends `${infer _}` ? string : T; export class URL<T extends string> implements Readonly<global.URL> { constructor(url: URL.Href<T> | URL.Resource<T> | URL.Origin<T>, base?: string); constructor(url: URLSegment<string> & T, base: T); constructor(url: T, ...base: T extends URLSegment<string> & infer U ? [U] : T extends AbsoluteURL | `${string}:${string}` ? [string?] : T extends `${infer _}` ? [string] : [T]); constructor(source: string, base?: string) { source = source.trim(); base = base?.trim(); this.url = new ReadonlyURL(source, base!); this.params = undefined; this.source = source; this.base = base; assert(this.url.href.endsWith(`${this.port}${this.pathname}${this.query}${this.fragment}`)); assert(this.href === this.url.href); //assert(this.href.startsWith(this.resource)); assert(this.origin === this.url.origin); assert(this.protocol === this.url.protocol); assert(this.host === this.url.host); assert(this.hostname === this.url.hostname); assert(this.port === this.url.port); } private readonly url: ReadonlyURL; private params?: URLSearchParams; public readonly source: string; public readonly base?: string; public get href(): URL.Href<T> { return this.params?.toString().replace(/^(?=.)/, `${this.url.href.slice(0, -this.url.query.length - this.url.fragment.length || this.url.href.length)}?`).concat(this.fragment) ?? this.url.href as any; } public get resource(): URL.Resource<T> { return this.params?.toString().replace(/^(?=.)/, `${this.url.href.slice(0, -this.url.query.length - this.url.fragment.length || this.url.href.length)}?`) ?? this.url.resource as any; } public get origin(): URL.Origin<T> { return this.url.origin as any; } public get scheme(): URL.Scheme { return this.url.scheme as any; } public get protocol(): URL.Protocol { return this.url.protocol as any; } public get username(): URL.Username { return this.url.username as any; } public get password(): URL.Password { return this.url.password as any; } public get host(): URL.Host<T> { return this.url.host as any; } public get hostname(): URL.Hostname<T> { return this.url.hostname as any; } public get port(): URL.Port { return this.url.port as any; } public get path(): URL.Path<T> { return this.params?.toString().replace(/^(?=.)/, `${this.pathname}?`) ?? this.url.path as any; } public get pathname(): URL.Pathname<T> { return this.url.pathname as any; } public get search(): URL.Search<T> { return this.params?.toString().replace(/^(?=.)/, '?') ?? this.url.search as any; } public get query(): URL.Query<T> { return this.params?.toString().replace(/^(?=.)/, '?') ?? this.url.query as any; } public get hash(): URL.Hash<T> { return this.url.hash as any; } public get fragment(): URL.Fragment<T> { return this.url.fragment as any; } public get searchParams(): URLSearchParams { return this.params ??= new URLSearchParams(this.search); } public toString(): string { return this.url.toString(); } public toJSON(): string { return this.url.toJSON(); } } export namespace URL { export type Href<T extends string> = URLSegment<'href'> & Widen<T>; export type Resource<T extends string> = URLSegment<'resource'> & Widen<T>; export type Origin<T extends string> = URLSegment<'origin'> & Widen<T>; export type Scheme = URLSegment<'scheme'> & string; export type Protocol = URLSegment<'protocol'> & string; export type Username = URLSegment<'username'> & string; export type Password = URLSegment<'password'> & string; export type Host<T extends string> = URLSegment<'host'> & Widen<T>; export type Hostname<T extends string> = URLSegment<'hostname'> & Widen<T>; export type Port = URLSegment<'port'> & string; export type Path<T extends string> = URLSegment<'path'> & Widen<T>; export type Pathname<T extends string> = URLSegment<'pathname'> & Widen<T>; export type Search<T extends string> = URLSegment<'search'> & Widen<T>; export type Query<T extends string> = URLSegment<'query'> & Widen<T>; export type Hash<T extends string> = URLSegment<'hash'> & Widen<T>; export type Fragment<T extends string> = URLSegment<'fragment'> & Widen<T>; } declare class URLSegment<T extends string> { private readonly URL: T; }