Loading CHANGES.md +19 −6 Original line number Diff line number Diff line Loading @@ -41,6 +41,19 @@ To be released. - The `--allow-private-address` or `-p` option allows looking up WebFinger information for private addresses (e.g., `localhost`). - Added useful functions for Fediverse handles at `@fedify/fedify/vocab`. This functions simplify working with Fediverse handles and URLs. - `FediverseHandle`: An interface representing a Fediverse handle. - `username`: The username part of the handle. - `host`: The host part of the handle. - `parseFediverseHandle`: A function to parse a Fediverse handle into its components. - If the input is a valid Fediverse handle, it returns a `FediverseHandle` object. - Else, it returns `null`. - `isFediverseHandle`: A function to check if a string is a valid Fediverse handle. - `convertFediverseHandle`: A function to convert a Fediverse handle to a URL. - If the input is a valid Fediverse handle, it returns a `URL` object. - Else, it returns `null`. Version 1.7.2 ------------- Loading fedify/vocab/handle.ts 0 → 100644 +94 −0 Original line number Diff line number Diff line /** * Regular expression to match a fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. */ const handleRegexp = /^@?((?:[-A-Za-z0-9._~!$&'()*+,;=]|%[A-Fa-f0-9]{2})+)@([^@]+)$/; /** * Represents a fediverse handle, which consists of a username and a host. * The username can be alphanumeric and may include special characters, * while the host is typically a domain name. */ export interface FediverseHandle { /** * The username part of the fediverse handle. * It can include alphanumeric characters and some special characters. */ readonly username: string; /** * The host part of the fediverse handle, typically a domain name. * It is the part after the `@` symbol in the handle. */ readonly host: string; } /** * Parses a fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. * * @param handle - The fediverse handle string to parse. * @returns A {@link FediverseHandle} object with `username` and `host` if the input is valid; otherwise `null`. * @since 1.8.0 * @example * ```typescript * const handle = parseFediverseHandle("@username@example.com"); * console.log(handle?.username); // "username" * console.log(handle?.host); // "example.com" * ``` */ export function parseFediverseHandle( handle: string, ): FediverseHandle | null { const match = handleRegexp.exec(handle); if (match) { return { username: match[1], host: match[2], }; } return null; } /** * Checks if a string is a valid fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. * * @param handle - The string to test as a fediverse handle. * @returns `true` if the string matches the fediverse handle pattern; otherwise `false`. * @since 1.8.0 * @example * ```typescript * console.log(isFediverseHandle("@username@example.com")); // true * console.log(isFediverseHandle("username@example.com")); // true * console.log(isFediverseHandle("@username@")); // false * ``` */ export function isFediverseHandle( handle: string, ): handle is `${string}@${string}` { return handleRegexp.test(handle); } /** * Converts a fediverse handle in the format `@user@server` or `user@server` * to an `acct:` URI, which is a URL-like identifier for ActivityPub actors. * * @param handle - The fediverse handle string to convert. * @returns A `URL` object representing the `acct:` URI if conversion succeeds; otherwise `null`. * @since 1.8.0 * @example * ```typescript * const identifier = convertFediverseHandle("@username@example.com"); * console.log(identifier?.href); // "acct:username@example.com" * ``` */ export function convertFediverseHandle(handle: string): URL | null { const parsed = parseFediverseHandle(handle); if (!parsed) return null; const identifier = new URL(`acct:${parsed.username}@${parsed.host}`); return identifier; } fedify/vocab/lookup.ts +2 −89 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import { type GetUserAgentOptions, } from "../runtime/docloader.ts"; import { lookupWebFinger } from "../webfinger/lookup.ts"; import { convertFediverseHandle } from "./handle.ts"; import { getTypeId } from "./type.ts"; import { type Collection, type Link, Object } from "./vocab.ts"; Loading Loading @@ -47,92 +48,6 @@ export interface LookupObjectOptions { tracerProvider?: TracerProvider; } /** * Regular expression to match a fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. */ const handleRegexp = /^@?((?:[-A-Za-z0-9._~!$&'()*+,;=]|%[A-Fa-f0-9]{2})+)@([^@]+)$/; /** * Represents a fediverse handle, which consists of a username and a host. * The username can be alphanumeric and may include special characters, * while the host is typically a domain name. */ export interface FediverseHandle { /** * The username part of the fediverse handle. * It can include alphanumeric characters and some special characters. */ readonly username: string; /** * The host part of the fediverse handle, typically a domain name. * It is the part after the `@` symbol in the handle. */ readonly host: string; } /** * Parses a fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. * * @example * ```typescript * const handle = parseFediverseHandle("@username@example.com"); * console.log(handle?.username); // "username" * console.log(handle?.host); // "example.com" * ``` */ export function parseFediverseHandle( handle: string, ): FediverseHandle | undefined { const match = handleRegexp.exec(handle); if (match) { return { username: match[1], host: match[2], }; } return undefined; } /** * Checks if a string is a valid fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. * * @example * ```typescript * console.log(isFediverseHandle("@username@example.com")); // true * console.log(isFediverseHandle("username@example.com")); // true * console.log(isFediverseHandle("@username@")); // false * ``` */ export function isFediverseHandle( handle: string, ): handle is `${string}@${string}` { return handleRegexp.test(handle); } /** * Converts a fediverse handle in the format `@user@server` or `user@server` * to an `acct:` URI, which is a URL-like identifier for ActivityPub actors. * * @example * ```typescript * const identifier = convertFediverseHandle("@username@example.com"); * console.log(identifier?.href); // "acct:username@example.com" * ``` */ export function convertFediverseHandle(handle: string): URL | undefined { const parsed = parseFediverseHandle(handle); if (!parsed) return undefined; const identifier = new URL(`acct:${parsed.username}@${parsed.host}`); return identifier; } /** * Looks up an ActivityStreams object by its URI (including `acct:` URIs) * or a fediverse handle (e.g., `@user@server` or `user@server`). Loading Loading @@ -213,9 +128,7 @@ async function lookupObjectInternal( const documentLoader = options.documentLoader ?? getDocumentLoader({ userAgent: options.userAgent }); if (typeof identifier === "string") { const match = handleRegexp.exec(identifier); if (match) identifier = `acct:${match[1]}@${match[2]}`; identifier = new URL(identifier); identifier = convertFediverseHandle(identifier) ?? new URL(identifier); } let document: unknown | null = null; if (identifier.protocol === "http:" || identifier.protocol === "https:") { Loading fedify/vocab/mod.ts +1 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ */ export * from "./actor.ts"; export * from "./constants.ts"; export * from "./handle.ts"; export * from "./lookup.ts"; export * from "./type.ts"; export * from "./vocab.ts"; Loading
CHANGES.md +19 −6 Original line number Diff line number Diff line Loading @@ -41,6 +41,19 @@ To be released. - The `--allow-private-address` or `-p` option allows looking up WebFinger information for private addresses (e.g., `localhost`). - Added useful functions for Fediverse handles at `@fedify/fedify/vocab`. This functions simplify working with Fediverse handles and URLs. - `FediverseHandle`: An interface representing a Fediverse handle. - `username`: The username part of the handle. - `host`: The host part of the handle. - `parseFediverseHandle`: A function to parse a Fediverse handle into its components. - If the input is a valid Fediverse handle, it returns a `FediverseHandle` object. - Else, it returns `null`. - `isFediverseHandle`: A function to check if a string is a valid Fediverse handle. - `convertFediverseHandle`: A function to convert a Fediverse handle to a URL. - If the input is a valid Fediverse handle, it returns a `URL` object. - Else, it returns `null`. Version 1.7.2 ------------- Loading
fedify/vocab/handle.ts 0 → 100644 +94 −0 Original line number Diff line number Diff line /** * Regular expression to match a fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. */ const handleRegexp = /^@?((?:[-A-Za-z0-9._~!$&'()*+,;=]|%[A-Fa-f0-9]{2})+)@([^@]+)$/; /** * Represents a fediverse handle, which consists of a username and a host. * The username can be alphanumeric and may include special characters, * while the host is typically a domain name. */ export interface FediverseHandle { /** * The username part of the fediverse handle. * It can include alphanumeric characters and some special characters. */ readonly username: string; /** * The host part of the fediverse handle, typically a domain name. * It is the part after the `@` symbol in the handle. */ readonly host: string; } /** * Parses a fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. * * @param handle - The fediverse handle string to parse. * @returns A {@link FediverseHandle} object with `username` and `host` if the input is valid; otherwise `null`. * @since 1.8.0 * @example * ```typescript * const handle = parseFediverseHandle("@username@example.com"); * console.log(handle?.username); // "username" * console.log(handle?.host); // "example.com" * ``` */ export function parseFediverseHandle( handle: string, ): FediverseHandle | null { const match = handleRegexp.exec(handle); if (match) { return { username: match[1], host: match[2], }; } return null; } /** * Checks if a string is a valid fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. * * @param handle - The string to test as a fediverse handle. * @returns `true` if the string matches the fediverse handle pattern; otherwise `false`. * @since 1.8.0 * @example * ```typescript * console.log(isFediverseHandle("@username@example.com")); // true * console.log(isFediverseHandle("username@example.com")); // true * console.log(isFediverseHandle("@username@")); // false * ``` */ export function isFediverseHandle( handle: string, ): handle is `${string}@${string}` { return handleRegexp.test(handle); } /** * Converts a fediverse handle in the format `@user@server` or `user@server` * to an `acct:` URI, which is a URL-like identifier for ActivityPub actors. * * @param handle - The fediverse handle string to convert. * @returns A `URL` object representing the `acct:` URI if conversion succeeds; otherwise `null`. * @since 1.8.0 * @example * ```typescript * const identifier = convertFediverseHandle("@username@example.com"); * console.log(identifier?.href); // "acct:username@example.com" * ``` */ export function convertFediverseHandle(handle: string): URL | null { const parsed = parseFediverseHandle(handle); if (!parsed) return null; const identifier = new URL(`acct:${parsed.username}@${parsed.host}`); return identifier; }
fedify/vocab/lookup.ts +2 −89 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import { type GetUserAgentOptions, } from "../runtime/docloader.ts"; import { lookupWebFinger } from "../webfinger/lookup.ts"; import { convertFediverseHandle } from "./handle.ts"; import { getTypeId } from "./type.ts"; import { type Collection, type Link, Object } from "./vocab.ts"; Loading Loading @@ -47,92 +48,6 @@ export interface LookupObjectOptions { tracerProvider?: TracerProvider; } /** * Regular expression to match a fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. */ const handleRegexp = /^@?((?:[-A-Za-z0-9._~!$&'()*+,;=]|%[A-Fa-f0-9]{2})+)@([^@]+)$/; /** * Represents a fediverse handle, which consists of a username and a host. * The username can be alphanumeric and may include special characters, * while the host is typically a domain name. */ export interface FediverseHandle { /** * The username part of the fediverse handle. * It can include alphanumeric characters and some special characters. */ readonly username: string; /** * The host part of the fediverse handle, typically a domain name. * It is the part after the `@` symbol in the handle. */ readonly host: string; } /** * Parses a fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. * * @example * ```typescript * const handle = parseFediverseHandle("@username@example.com"); * console.log(handle?.username); // "username" * console.log(handle?.host); // "example.com" * ``` */ export function parseFediverseHandle( handle: string, ): FediverseHandle | undefined { const match = handleRegexp.exec(handle); if (match) { return { username: match[1], host: match[2], }; } return undefined; } /** * Checks if a string is a valid fediverse handle in the format `@user@server` or `user@server`. * The `user` part can contain alphanumeric characters and some special characters except `@`. * The `server` part is all characters after the `@` symbol in the middle. * * @example * ```typescript * console.log(isFediverseHandle("@username@example.com")); // true * console.log(isFediverseHandle("username@example.com")); // true * console.log(isFediverseHandle("@username@")); // false * ``` */ export function isFediverseHandle( handle: string, ): handle is `${string}@${string}` { return handleRegexp.test(handle); } /** * Converts a fediverse handle in the format `@user@server` or `user@server` * to an `acct:` URI, which is a URL-like identifier for ActivityPub actors. * * @example * ```typescript * const identifier = convertFediverseHandle("@username@example.com"); * console.log(identifier?.href); // "acct:username@example.com" * ``` */ export function convertFediverseHandle(handle: string): URL | undefined { const parsed = parseFediverseHandle(handle); if (!parsed) return undefined; const identifier = new URL(`acct:${parsed.username}@${parsed.host}`); return identifier; } /** * Looks up an ActivityStreams object by its URI (including `acct:` URIs) * or a fediverse handle (e.g., `@user@server` or `user@server`). Loading Loading @@ -213,9 +128,7 @@ async function lookupObjectInternal( const documentLoader = options.documentLoader ?? getDocumentLoader({ userAgent: options.userAgent }); if (typeof identifier === "string") { const match = handleRegexp.exec(identifier); if (match) identifier = `acct:${match[1]}@${match[2]}`; identifier = new URL(identifier); identifier = convertFediverseHandle(identifier) ?? new URL(identifier); } let document: unknown | null = null; if (identifier.protocol === "http:" || identifier.protocol === "https:") { Loading
fedify/vocab/mod.ts +1 −0 Original line number Diff line number Diff line Loading @@ -51,6 +51,7 @@ */ export * from "./actor.ts"; export * from "./constants.ts"; export * from "./handle.ts"; export * from "./lookup.ts"; export * from "./type.ts"; export * from "./vocab.ts";