diff --git a/changelog.md b/changelog.md index 431d92b..7250299 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # Changelog +## 2024-10-03 - 3.1.0 - feat(Smarturl) +Enhanced documentation and added method for property setting and chaining in Smarturl + +- Added detailed comments to methods and interfaces for better code understanding. +- Introduced a method to set properties in a chainable manner. + ## 2024-10-03 - 3.0.8 - fix(core) Fix code formatting and indentation issues in smarturl.classes.smarturl.ts diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 8d37a3a..e80980d 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smarturl', - version: '3.0.8', + version: '3.1.0', description: 'A library for parsing URLs in a detailed and flexible way.' } diff --git a/ts/smarturl.classes.smarturl.ts b/ts/smarturl.classes.smarturl.ts index 699438c..83477a4 100644 --- a/ts/smarturl.classes.smarturl.ts +++ b/ts/smarturl.classes.smarturl.ts @@ -1,5 +1,7 @@ +// Import necessary plugins (if any are used in the module) import * as plugins from './smarturl.plugins.js'; +// Interface representing the structure of a URL object export interface IUrlObject { href: string; origin: string; @@ -16,31 +18,37 @@ export interface IUrlObject { hash: string; } +// Interface representing the search parameters as a key-value pair object export interface ISearchParams { [key: string]: string; } +// Main Smarturl class implementing the IUrlObject interface export class Smarturl implements IUrlObject { + // Static method to create a Smarturl instance from a URL string public static createFromUrl( urlArg: string, optionsArg?: { searchParams?: ISearchParams; } ): Smarturl { + // Parse the URL string using the built-in URL class const parsedUrlInstance = new URL(urlArg); const searchParams: ISearchParams = {}; - // enrichment + // Array to hold key-value pairs of search parameters const searchParamPairs: { key: string; value: string; }[] = []; + // If the URL has search parameters, parse them into key-value pairs if (parsedUrlInstance.search) { parsedUrlInstance.search - .replace('?', '') - .split('&') + .replace('?', '') // Remove the '?' at the beginning + .split('&') // Split the query string into individual parameters .map((searchParamPair) => { + // Split each parameter into key and value and add to the array searchParamPairs.push({ key: searchParamPair.split('=')[0], value: searchParamPair.split('=')[1], @@ -48,15 +56,19 @@ export class Smarturl implements IUrlObject { }); } + // Convert the array of key-value pairs into an object for (const searchParamPair of searchParamPairs) { searchParams[searchParamPair.key] = searchParamPair.value; } + + // Merge any additional search parameters provided in optionsArg if (optionsArg?.searchParams) { for (const key of Object.keys(optionsArg.searchParams)) { searchParams[key] = optionsArg.searchParams[key]; } } + // Reconstruct the path with updated search parameters let path = parsedUrlInstance.pathname || ''; if (Object.keys(searchParams).length > 0) { path += '?'; @@ -71,8 +83,9 @@ export class Smarturl implements IUrlObject { } } + // Create an IUrlObject containing all parts of the URL const parsedUrl: IUrlObject = { - ...parsedUrlInstance, + ...parsedUrlInstance, // Spread operator to include all properties from parsedUrlInstance href: parsedUrlInstance.href, origin: parsedUrlInstance.origin, protocol: parsedUrlInstance.protocol, @@ -81,33 +94,35 @@ export class Smarturl implements IUrlObject { host: parsedUrlInstance.host, hostname: parsedUrlInstance.hostname, port: parsedUrlInstance.port, - path, + path, // Updated path with new search parameters pathname: parsedUrlInstance.pathname, search: parsedUrlInstance.search, - searchParams, + searchParams, // The searchParams object we constructed hash: parsedUrlInstance.hash, }; + // Infer default ports if none are specified based on the protocol if (!parsedUrl.port && parsedUrl.protocol === 'https:') { - // console.log(`inferring port 443 for "https:"`); parsedUrl.port = '443'; } if (!parsedUrl.port && parsedUrl.protocol === 'http:') { - // console.log(`inferring port 80 for "http:"`); parsedUrl.port = '80'; } + + // Create a new Smarturl instance and assign the parsed URL properties const returnSmarturl = new Smarturl(); - Object.assign(returnSmarturl, parsedUrl); + Object.assign(returnSmarturl, parsedUrl); // Copy all properties from parsedUrl to returnSmarturl return returnSmarturl; } - public static createFromParsedUrl(parsedUrlArg: IUrlObject) { + // Static method to create a Smarturl instance from an existing IUrlObject + public static createFromParsedUrl(parsedUrlArg: IUrlObject): Smarturl { const returnSmarturl = new Smarturl(); - Object.assign(returnSmarturl, parsedUrlArg); + Object.assign(returnSmarturl, parsedUrlArg); // Copy all properties from parsedUrlArg to returnSmarturl return returnSmarturl; } - // INSTANCE + // INSTANCE PROPERTIES (matching IUrlObject interface) href: string; origin: string; protocol: string; @@ -122,19 +137,35 @@ export class Smarturl implements IUrlObject { searchParams: ISearchParams; hash: string; + // Constructor initializes searchParams as an empty object constructor() { this.searchParams = {}; } + // Method to create an independent clone of the current Smarturl instance clone(): Smarturl { const clonedInstance = new Smarturl(); - Object.assign(clonedInstance, this); - clonedInstance.searchParams = { ...this.searchParams }; + Object.assign(clonedInstance, this); // Copy all properties to the new instance + clonedInstance.searchParams = { ...this.searchParams }; // Shallow copy of searchParams to prevent shared references return clonedInstance; } - toString() { - let userpart = ``; + /** + * Typed method to set a property and return the instance for chaining. + * @param prop - The property name to set (must be a key of Smarturl) + * @param value - The value to assign to the property + * @returns The Smarturl instance for method chaining + */ + set(prop: K, value: this[K]): this { + this[prop] = value; // Set the property to the new value + return this; // Return the instance for chaining + } + + // Method to convert the Smarturl instance back into a URL string + toString(): string { + let userpart = ``; // Initialize the user part of the URL (username and password) + + // Construct the user part based on the presence of username and password if (this.username && !this.password) { userpart = `${this.username}@`; } @@ -142,6 +173,7 @@ export class Smarturl implements IUrlObject { userpart = `${this.username}:${this.password}@`; } + // Construct and return the full URL string return `${this.protocol}//${userpart}${this.hostname}:${this.port}${this.path}`; } } \ No newline at end of file