docs(banners): 📚️ add JSDocs documentation and infos

This commit is contained in:
Guz013
2023-06-26 10:45:09 -03:00
parent 3ebc02115f
commit 00b4440751
7 changed files with 349 additions and 55 deletions

View File

@@ -227,6 +227,10 @@ module.exports = {
'tsconfig',
'workspace',
'woff',
'marknow',
'lored',
'guz013',
'xml',
],
minLength: 4,
}],

View File

@@ -2,9 +2,14 @@ import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
/**
* @param {import('./types').Reader | undefined} reader
* @param {import('./types').Reader | undefined} [reader=import('node:fs').readFile]
* The function to be used as reader of the local files.
*
* @typedef {import('satori').SatoriOptions['fonts'][0]} Font
* @returns {Promise<{subtitle: Font, title: Font}>}
*
* @module \@marknow/banners
* @access protected
*/
export async function getMonaSansFonts(reader) {
reader ||= (await import('node:fs/promises')).readFile;

View File

@@ -1,11 +1,10 @@
/* eslint-disable complexity */
/* eslint-disable @typescript-eslint/indent */
/**
* Returns the html string of the banner to be used by satori.
* Use the params to customize and complete it.
* Constructor of the HTML banner converted to VNodes to be used in satori.
* Use the properties to customize and complete it.
*
* @typedef {import('satori').SatoriOptions['fonts'][0]} Font
*
* @typedef {{
* dimensions: { width: number, height: number },
* fonts: { title: Font, subtitle: Font },
@@ -14,8 +13,12 @@
* rtl: boolean,
* }} Props
* @param {Props} properties
* Properties to be applied on the html.
*
* @return {string}
* @returns {string}
*
* @module \@marknow/banners
* @access protected
*/
export default function html({
dimensions,

View File

@@ -1,8 +1,20 @@
/**
* @param {string} icon
* @param {import('./types').Fetcher | undefined} fetcher
/**
* Utility function used to get a SVG icon from Iconify OR from an url passed as the icon.
*
* @return {Promise<string>}
* If the `icon` parameter is not a valid icon name or url,
* it returns the `icon` itself.
*
* @param {string} icon
* The icon's name or url endpoint.
*
* @param {import('./types').Fetcher | undefined} [fetcher=globalThis.fetch]
* Fetch function to be used.
*
* @returns {Promise<string>}
*
* @module \@marknow/banners
* @access protected
*/
export async function getIcon(icon, fetcher = fetch) {
if (!isIconName(icon) && !isValidUrl(icon)) {
@@ -19,6 +31,20 @@ export async function getIcon(icon, fetcher = fetch) {
return svg;
}
/**
* Utility function used to set the icons SVG width and height to the specified dimensions.
*
* @param {string} svg
* The svg string.
*
* @param {{width?: string | number, height?: string | number}} dimensions
* The dimensions values, if type number it is converted to pixels.
*
* @returns {string}
*
* @module \@marknow/banners
* @access protected
*/
export function setIconDimensions(svg, { width, height }) {
width = typeof width === 'number'
? `width="${width}px"`
@@ -38,10 +64,14 @@ export function setIconDimensions(svg, { width, height }) {
}
/**
* Checks if a given string is a valid [Iconify](https://iconify.design/)/[Icônes](https://icones.js.org/)-like icon name.
* Checks if a given string is a valid
* [Iconify](https://iconify.design/)/[Icônes](https://icones.js.org/)-like icon name.
*
* @param {string} iconName
* @return {boolean}
* @param {string} string The string to be checked.
* @returns {boolean}
*
* @module \@marknow/banners
* @access package
*/
function isIconName(string) {
try {
@@ -54,8 +84,13 @@ function isIconName(string) {
}
/**
* @param {string} string
* @return {boolean}
* Checks if string is a valid URL.
*
* @param {string} string The string to be checked.
* @returns {boolean}
*
* @module \@marknow/banners
* @access package
*/
function isValidUrl(string) {
try {

View File

@@ -1,7 +1,50 @@
/**
* @param {import('./types').BannerOptions} options
* @returns {Promise<import('./types').Banner>}
*/
export default function banner({ title, subtitle, icon, layout, config, }: import('./types').BannerOptions): Promise<import('./types').Banner>;
/**
/**
* The banner constructor function. Use the options to customize the
* appearance of the resulting banner.
*
* @param {import('./types').BannerOptions} options
* Options object for customizing the banner appearance.
*
* @returns {Promise<import('./types').Banner>}
*
* @example
* import newBanner from '@marknow/banners';
*
* export async function GET({ fetch }) {
* const banner = await newBanner({
* title: 'Hello world',
* subtitle: 'This is a example api endpoint.'
* icon: 'material-symbols:api'
* fonts: {
* title: {
* data: await (await fetch('/Mona-Sans-SemiBold.woff')).arrayBuffer(),
* name: 'Mona Sans',
* weight: 600,
* },
* subtitle: {
* data: await (await fetch('/Mona-Sans-Regular.woff')).arrayBuffer(),
* name: 'Mona Sans',
* weight: 400,
* },
* },
* libConfig: {
* fetcher: fetch,
* },
* });
*
* return new Response(banner.toString(), {
* status: 200,
* headers: {
* 'Content-type': 'image/svg+xml',
* },
* });
* }
*
* @module \@marknow/banners
* @access public
*/
export default function banner({ title, subtitle, icon, layout, config, }: import('./types').BannerOptions): Promise<import('./types').Banner>;
export type { BannerOptions, Banner } from './types'

View File

@@ -5,8 +5,49 @@ import { getMonaSansFonts } from './fonts';
import { getIcon, setIconDimensions } from './icons';
/**
* The banner constructor function. Use the options to customize the
* appearance of the resulting banner.
*
* @param {import('./types').BannerOptions} options
* Options object for customizing the banner appearance.
*
* @returns {Promise<import('./types').Banner>}
*
* @example
* import newBanner from '@marknow/banners';
*
* export async function GET({ fetch }) {
* const banner = await newBanner({
* title: 'Hello world',
* subtitle: 'This is a example api endpoint.'
* icon: 'material-symbols:api'
* fonts: {
* title: {
* data: await (await fetch('/Mona-Sans-SemiBold.woff')).arrayBuffer(),
* name: 'Mona Sans',
* weight: 600,
* },
* subtitle: {
* data: await (await fetch('/Mona-Sans-Regular.woff')).arrayBuffer(),
* name: 'Mona Sans',
* weight: 400,
* },
* },
* libConfig: {
* fetcher: fetch,
* },
* });
*
* return new Response(banner.toString(), {
* status: 200,
* headers: {
* 'Content-type': 'image/svg+xml',
* },
* });
* }
*
* @module \@marknow/banners
* @access public
*/
export default async function banner({
title,
@@ -60,7 +101,17 @@ export default async function banner({
};
}
/** @type {(string: string, maxChar: number) => string} */
/**
* Small utility function used to truncate long texts on the banner
*
* @param {string} string - Text string to be truncated.
* @param {number} maxChar - Maximum number of characters.
*
* @returns {string}
*
* @module \@marknow/banners
* @access package
*/
function truncateText(string, maxChar) {
return string.length > maxChar ? `${string.slice(0, maxChar)}...` : string;
}

View File

@@ -3,6 +3,170 @@ import type { OpenMode, PathLike } from "node:fs";
import type { FileHandle } from "node:fs/promises";
import type { SatoriOptions } from "satori/wasm";
/**
* Options object for customizing the banner appearance.
*
* @module \@marknow/banners
* @access public
*/
export interface BannerOptions {
/**
* **(REQUIRED)** Title to be displayed in the banner.
*/
title: string,
/**
* (Optional) Set the text direction right-to-left.
*/
rtl?: boolean = false,
/**
* (Optional) {@link https://iconify.design/ Iconify}/{@link https://icones.js.org/ Icônes}-like
* icon name OR url for svg file of the icon to be used in the banner.
*/
icon?: string = '',
/**
* (Optional) Subtitle/legend to be displayed in the banner
* bellow the title.
*/
subtitle?: string = '',
/**
* (Optional) Customize the colors of the banner.
*
* Customize the background color and foreground (title, subtitle
* and icon) colors.
*/
colors?: Colors = { background: '#ffffff', foreground: '#000000' },
/**
* (Optional) Customize the layout of the banner and position of elements.
*/
layout?: 'horizontal' | 'vertical' = 'horizontal',
/**
* (Optional) Customize the fonts used on the banner.
*
* Changes the default font file used for the title and subtitle.
* Defaults is {@link https://github.com/github/mona-sans Github's Mona Sans}
* semi-bold and regular respectively.
*
* @see {@link https://github.com/vercel/satori#fonts}
*/
fonts?: {
title: Font,
subtitle: Font,
}
/**
* (Optional) Customize the behavior of the package.
*
* Provide functions or polyfills to be used by the package
* for better compatibility or customization of the banner
* creation.
*/
libConfig?: {
/**
* (Optional) Fetch function used by the package to retrieve
* icons from {@link https://iconify.design/ Iconify} and custom
* icons provided as url.
*
* Default function used is the
* {@link https://developer.mozilla.org/en-US/docs/Web/API/fetch globalThis.fetch}
* function. Compatible with modern browsers, Node.js (version 18 and greater),
* Deno and Bun.
*
* @see {@link BannerOptions.icon}
*
* @param {RequestInfo} input - The request url/info.
* @param {RequestInit} - Request options.
* @returns {Promise<Response>}
*/
fetcher?: Fetcher = globalThis.fetch,
/**
* (Optional) The function used to read the font files and return a Buffer or
* ArrayBuffer from them.
*
* Default function used is the {@link https://nodejs.org/api/fs.html#fsreadfilepath-options-callback fs.readFile}
* from the Node file system promises api ({@link https://nodejs.org/api/fs.html#file-system node:fs/promises}).
* Compatible with Node.js (version 10 and greater), Deno and Bun.
*
* @param {PathLike | FileHandle} path - The path to the font files.
* @returns {Promise<Buffer | ArrayBuffer>}
*/
reader?: Reader = import ('node:fs/promises').readFile,
/**
* (Optional) The function used to get the icon svg file from {@link https://iconify.design/ Iconify}
* or URL endpoint passed.
*
* @see {@link BannerOptions.icon}
*
* @param {string} icon - Icon name or URL.
* @returns {string | Promise<string>}
*/
iconHandler?: (icon: string) => string | Promise<string>
}
}
/**
* The resulting banner object.
*
* Has a `toString()` function to be used in string literals
* that returns the svg string of the banner.
*
* @module \@marknow/banners
* @access public
*/
export interface Banner {
/**
* The resulting svg of the banner.
* @readonly
*/
svg: string,
/**
* The raw html used to create the banner.
* @readonly
*/
html: string,
/**
* The used icon's svg.
* @readonly
*/
icon: string,
/**
* React-element-like objects / VDOM used to create the banner.
* @readonly
*/
vNodes: VNode,
/**
* Returns the {@link Banner.svg svg string} of the banner.
* Useful when using the banner object directly on a string.
*
* @example
* import newBanner from '@marknow/banners';
*
* const banner = await newBanner({ ... });
*
* // Prints the resulting svg instead of the banner object itself.
* console.log(`Banner svg:\n${banner}`)
*
* @readonly
*/
toString(): string,
};
/**
* Font object for the banner passed to the `satori` package.
*
* @see {@link BannerOptions.fonts}
* @see {@link https://github.com/vercel/satori#fonts}
*
* @module \@marknow/banners > satori
* @access protected
*/
export type Font = SatoriOptions['fonts'][0];
export type Colors = {
@@ -10,54 +174,43 @@ export type Colors = {
background: string;
}
/**
* "Global Fetch"-like function used by the package to retrieve
* icons from [Iconify](https://iconify.design/) and custom
* icons provided as url.
*
* @param {RequestInfo} input - The request url/info.
* @param {RequestInit} - Request options.
* @returns {Promise<Response>}
*
* @module \@marknow/banners
* @access protected
*/
export type Fetcher = (
input: RequestInfo | URL,
init?: RequestInit
) => Promise<Response>;
/**
* "Node.js' `fs.readFile`"-like function used to read the font files
* and return a Buffer or ArrayBuffer from them.
*
* @param {RequestInfo} input - The request url/info.
* @param {RequestInit} - Request options.
* @returns {Promise<Response>}
*
* @module \@marknow/banners
* @access protected
*/
export type Reader = (
path: PathLike | FileHandle,
) => Promise<Buffer | ArrayBuffer>
/**
* Options object for creating a banner.
*
* @package `@marknow/banners`
*/
export interface BannerOptions {
icon?: string,
title: string,
subtitle?: string,
layout?: 'horizontal' | 'vertical',
fonts?: {
title: Font,
subtitle: Font,
}
colors?: Colors,
rtl?: boolean,
libConfig?: {
fetcher?: Fetcher = fetch,
reader?: Reader,
iconHandler?: (icon: string) => string | Promise<string>
}
}
/**
*
*/
export interface Banner {
toString(): string,
html: string,
svg: string,
icon: string,
vNodes: VNode,
};
/**
* **Copied from the satori-html package,**
* React-element-like objects / VDOM object used in satori.
*
* @package `satori-html`
* @module \@marknow/banners > satori-html
* @access protected
*/
export interface VNode {
type: string;