UNPKG

@ara-web/sds

Version:

Write code faster without worry about future debts or scalability in the future

195 lines (167 loc) 5.66 kB
import type { PurlQualifiers } from "packageurl-js"; import { ArrayTraits, type WithGetTextMethod } from "@ara-web/p-hintjens"; import { ModuleLink, type ModuleURL } from "./module-link.js"; import path from "path"; export const NpmProtocol = "npm"; export type AraURL = `ara:` | `sever:` | `reflect:` | `http://${string}` | `https://${string}` | `ws://${string}` | ModuleURL | `this`; export class AraLink<T> { private _protocol: string; private _slugs: string[]; private _resource: string|T; private _properties: object; constructor (protocol: string, resource: string|T, slugs: string[], properties?: object) { this._protocol = protocol; this._resource = resource; if (slugs !== undefined) { this._slugs = slugs; } else { this._slugs = []; } if (properties !== undefined) { this._properties = properties; } else { this._properties = {} } return this; } public copyWithProperties = (properties: object): AraLink<T> => { const araLink = new AraLink(this._protocol, this._resource, this._slugs, properties); return araLink; } public isEmpty = (): boolean => { if (this._resource === undefined || this._resource === null) { return true; } let resourceStr = this._resource.toString(); if (resourceStr.length === 0) { return true; } return false; } public get protocol(): string { return this._protocol; } public get slugs(): string[] { return this._slugs; } public get resource(): (typeof this._resource) { return this._resource; } public get properties(): object { return this._properties; } public isPropertyExist(property: string): boolean { if (this._properties === undefined) { return false; } if (property in this._properties) { return true; } return false; } public property = (property: string): object|undefined => { if (!this.isPropertyExist(property)) { return undefined; } return (this._properties as any)[property] } public toString = () : string => { let resourceUrl: string = ""; if (typeof this.resource === "string") { resourceUrl = this.resource.toString(); } else { if ((this.resource as WithGetTextMethod)["getText"] !== undefined && (this.resource as WithGetTextMethod)["getText"] !== null) { resourceUrl = (this.resource as WithGetTextMethod).getText(); } else { resourceUrl = (this.resource as any).toString(); } } let url = `${this._protocol}:${this.slugs.join('/')}/${resourceUrl}` let properties: string = ""; for (let key in this._properties) { if (properties.length > 0 && properties[properties.length - 1] !== "&") { properties += "&" } properties += `${key}=${(this._properties as any)[key]}` } if (properties.length > 0) { properties = "?" + properties; } return url + properties; } public toModuleLink = (): ModuleLink => { const schema = this._protocol; const namespace = this._slugs.length === 0 ? "" : this._slugs[0] const name: string = this._resource as string; let subPath: string = ""; if (this._slugs !== undefined && this._slugs.length > 1) { subPath = this.slugs.filter((_, index) => (index > 0)).join(path.sep) } const qualifiers: PurlQualifiers = { ...this._properties } const pkgUrl = ModuleLink.newPackageLink( namespace, name, subPath, qualifiers, schema ); return pkgUrl; } public static fromModuleLink = (moduleLink: ModuleLink): AraLink<string> => { if (moduleLink.isFileURL) { const filePath = moduleLink.toAbsFilePath; const resource = path.basename(filePath); const slugs = path.dirname(filePath).split(path.sep); return new AraLink<string>("file", resource, slugs); } const pkgURL = moduleLink.toPackageURL; const protocol = pkgURL.type; const slugs: string[] = []; if (pkgURL.namespace) { slugs.push(pkgURL.namespace); } if (pkgURL.subpath) { slugs.push(...pkgURL.subpath.split(path.sep)) } const resource = pkgURL.name; const araLink = new AraLink<string>(protocol, resource, slugs); if (pkgURL.qualifiers !== undefined) { araLink._properties = pkgURL.qualifiers; } return araLink; } public lastSlug = (): string|undefined => { if (this._slugs.length === 0) { return undefined; } return this._slugs[this._slugs.length - 1]; } /** * Returns true if the link is following the protocol and in the slugs path * @param protocol * @param slugs * @returns */ public isCorrectPath = (protocol: string, slugs: string[]): boolean => { if (this.protocol !== protocol) { return false; } if (this.slugs.length === 0) { return false; } if (!ArrayTraits.isEqualArray(this.slugs, slugs)) { return false; } return true; } }