favilib
Version:
An enhanced Node.js module for generating favicons and assets required for Progressive Web Apps (PWAs). It supports the latest standards from `w3.org`, `Edge`, `Yandex`, and Windows Tile (Manifest), providing a unified interface for both CommonJS and ES m
636 lines (611 loc) • 24.9 kB
text/typescript
import { Transform, TransformCallback } from 'stream';
type Orientation = "any" | "natural" | "portrait" | "landscape" | "portrait-primary" | "portrait-secondary" | "landscape-primary" | "landscape-secondary";
type DevicePlatformIdentifiers = "android" | "chromeos" | "ipados" | "huawei" | "ios" | "kaios" | "macos" | "windows" | "xbox";
type DistributionPlatformIdentifiers = "chrome_web_store" | "chromeos_play" | "webapp" | "itunes" | "microsoft-inbox" | "microsoft-store" | "play";
interface Image {
/**
* A string that specifies the path to the icon image file.
*/
readonly src: string;
/**
* A string that specifies one or more sizes at which the icon file can be used.
* Each size is specified as `<width in pixels>`x`<height in pixels>`.
* If multiple sizes are specified, they are separated by spaces; for example, `48x48 96x96`.
* Refer to [MDN](https://developer.mozilla.org/en-US/docs/Web/Manifest/icons#sizes)
*/
readonly sizes?: string;
/**
* A string that specifies the [MIME type](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the icon.
*/
readonly type?: string;
}
interface Icon extends Image {
/**
* Specifies the purpose of the icon, allowing one or more keywords separated by spaces.
* Valid values are:
*
* - `monochrome`: Indicates the icon is intended to be used as a monochrome icon with a solid fill.
* - `maskable`: Designed with icon masks and safe zones in mind, allowing parts outside the safe zone to be ignored.
* - `any`: Indicates the icon is suitable for any context.
*
* Examples: `"monochrome"`, `"maskable any"`, `"any maskable"`.
*
* **Note**: Order and duplicates are not enforced.
* @default "any"
*/
readonly purpose?: string;
}
interface Screenshot extends Image {
/**
* String that represents a class of devices.
* This should be used only when the screenshot is only applicable for a particular form factor.
*
* - `narrow` the screenshot is applicable only to narrow screens.
* - `wide` the screenshot is applicable only to wide screens.
*
*/
readonly form_factor: "narrow" | "wide";
/**
* String that represents the accessible name of the screenshot object.
*/
readonly label: string;
/**
* String that represents the platform to which the screenshot applies.
* This should be used when a screenshot is only applicable to a specific device or distribution platform.
*/
readonly platform: DevicePlatformIdentifiers | DistributionPlatformIdentifiers | (string & NonNullable<unknown>);
}
type MimeTypeExtensionsMap = {
"audio/wav": ".wav";
"audio/x-wav": ".wav";
"audio/mpeg": ".mp3";
"audio/mp4": ".mp4";
"audio/aac": ".adts";
"audio/ogg": ".ogg";
"application/ogg": ".ogg";
"audio/webm": ".webm";
"audio/flac": ".flac";
"audio/mid": ".mid" | ".rmi";
"video/mp4": ".mp4";
"video/webm": ".webm";
"video/ogg": ".ogg";
"video/x-msvideo": ".avi";
"video/3gpp": ".3gp";
"video/3gpp2": ".3g2";
"video/mpeg": ".mpeg";
"video/quicktime": ".mov";
"image/jpeg": ".jpg" | ".jpeg";
"image/png": ".png";
"image/gif": ".gif";
"image/webp": ".webp";
"image/svg+xml": ".svg";
"image/bmp": ".bmp";
"image/x-icon": ".ico";
"application/pdf": ".pdf";
"application/msword": ".doc";
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx";
"application/vnd.ms-excel": ".xls";
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx";
"application/vnd.ms-powerpoint": ".ppt";
"application/vnd.openxmlformats-officedocument.presentationml.presentation": ".pptx";
"application/zip": ".zip";
"application/x-rar-compressed": ".rar";
"application/x-tar": ".tar";
"application/x-7z-compressed": ".7z";
"application/gzip": ".gz";
"application/json": ".json";
"application/javascript": ".js";
"application/xml": ".xml";
"text/html": ".html";
"text/css": ".css";
"text/plain": ".txt";
"application/octet-stream": ".bin";
};
type MimeTypes = keyof MimeTypeExtensionsMap;
type Extensions<MimeType extends MimeTypes> = MimeTypeExtensionsMap[MimeType];
type ValidAccept<K extends MimeTypes> = {
[]?: Extensions<key>[];
};
interface FileHandler {
/**
* The URL within the scope of your app that your app will open to when handling the given file type.
*/
action: string;
/**
* An object that contains the MIME-types that the above url can handle as keys and file extensions as values.
*/
accept: Partial<ValidAccept<MimeTypes>>;
/**
* A list of icon objects that will show when given the option to open the given file with your app.
*/
icons?: Array<Image>;
/**
* Dictates if multiple app instances can launch when handling several files at once.
* This member defaults to `single-client` but can also be set to `multiple-clients`
* if you want an app instance to launch for each file being handled.
*/
launch_type?: "single-client" | "multiple-clients";
}
type Category = "beauty" | "books" | "books & reference" | "business" | "cars" | "dating" | "design" | "developer" | "developer tools" | "development" | "education" | "entertainment" | "events" | "fashion" | "finance" | "fitness" | "food" | "fundraising" | "games" | "government" | "graphics" | "graphics & design" | "health" | "health & fitness" | "kids" | "lifestyle" | "magazines" | "medical" | "multimedia" | "multimedia design" | "music" | "navigation" | "network" | "networking" | "news" | "parenting" | "personalization" | "pets" | "photo" | "photo & video" | "politics" | "productivity" | "reference" | "security" | "shopping" | "social" | "social networking" | "sports" | "transportation" | "travel" | "utilities" | "video" | "weather" | (string & NonNullable<unknown>);
type ProtocolName = "web+example" | "web+jngl" | "web+jnglstore" | "web+service" | "web+app" | "web+music" | (string & NonNullable<unknown>);
interface ProtocolHandler {
protocol: ProtocolName;
url: string;
}
type Direction = "auto" | "ltr" | "rtl";
type Locale = "en" | "fr" | "ar" | "en-US" | "zh-CN" | "zh-HK" | "zh-TW" | "es-ES" | "fr-FR" | "de-DE" | "ja-JP" | (string & NonNullable<unknown>);
interface NameLocalized {
value: string;
lang?: Locale;
dir?: Direction;
}
type Localized<T> = T & {
[]?: Partial<Record<Locale, T[K]>>;
};
interface LocalizableMember {
name?: string | NameLocalized;
short_name?: string;
description?: string;
icons?: Array<Icon>;
}
type LocalizedMember = Localized<LocalizableMember>;
interface Shotcut extends LocalizedMember {
/**
* A string that represents the name of the shortcut, which is displayed to users in a context menu.
*/
readonly name: string;
/**
* A string that represents a short version of the shortcut's name.
*/
readonly short_name?: string;
/**
* A string that describes the purpose of the shortcut.
*/
readonly description?: string;
/**
* An app URL that opens when the associated shortcut is activated.
* The URL must be within the `scope` of the web app manifest.
*/
readonly url: string;
/**
* An array of icon objects representing the shortcut in various contexts.
* This has the same format as the `icons` manifest member.
*/
readonly icons?: Array<Icon>;
}
/**
* DOC https://developer.mozilla.org/en-US/docs/Web/Manifest/launch_handler
* API https://wicg.github.io/web-app-launch/#launch_handler-member
*/
type ClientMode = "auto" | "focus-existing" | "navigate-existing" | "navigate-new";
interface LaunchHandler {
readonly client_mode: ClientMode | ClientMode[];
}
type Display = "fullscreen" | "standalone" | "minimal-ui" | "browser";
type DisplayOverride = Display | "tabbed" | "window-controls-overlay";
interface RelatedApplication {
/**
* A string that identifies the platform on which the application can be found.
* Examples include `amazon` (Amazon App Store), `play` (Google Play Store), and `windows` (Windows Store).
* See the complete list of possible [platform values](https://github.com/w3c/manifest/wiki/Platforms).
*/
readonly platform: string;
/**
* A string that represents the URL at which the platform-specific application can be found. If not specified, an `id` must be provided.
*/
readonly url?: string;
/**
* A string with the ID used to represent the application on the specified platform. If not specified, a `url` must be provided.
*/
readonly id?: string;
}
interface ShareParams {
/**
* Name of the query parameter for the title of the document being shared.
*/
title?: string;
/**
* Name of the query parameter for the body of the message being shared.
*/
text?: string;
/**
* Name of the query parameter for the URL being shared.
*/
url?: string;
files?: FileParam[];
}
interface FileParam {
/**
* Name of the form field used to share files.
*/
name: string;
/**
* A string or array of strings of accepted MIME types or extensions.
*/
accept: string;
}
type Enctype = "application/x-www-form-urlencoded" | "multipart/form-data" | "text/plain" | "application/json" | (string & NonNullable<unknown>);
interface ShareTarget {
/**
* The URL within the scope of your app that your app will handle the share action.
*/
action: string;
/**
* `GET` or `POST`.
* Use `POST` if the shared data includes binary data like images.
*/
method: "POST" | "GET";
/**
* The encoding of the data when the method is a `POST` request. Otherwise, ignored.
*/
enctype?: Enctype;
/**
* The object that allows you to configure the share parameters. Should corresponded to the object exposed by `navigator.share()`.
*/
params: ShareParams;
}
interface W3Manifest extends LocalizedMember {
/**
* The name of the app, used by the OS to display next to the app's icon.
*/
readonly name: string;
/**
* This can be used to display the name of the app when there isn't enough space for `name`.
* It is recommended that `short_name` be 12 characters or less in length.
*/
readonly short_name: string;
/**
* Specify a unique identifier for your web application.
*/
readonly id?: string;
/**
* The description of the app.
*/
readonly description?: string;
/**
* The list of categories the app belongs to.
*/
readonly categories?: Array<Category>;
/**
* Array of icon image objects that are used by the OS in different contexts.
*/
readonly icons: Array<Icon>;
/**
* Array of screenshot image objects, also used by the OS in different contexts.
*/
readonly screenshots?: Array<Screenshot>;
/**
* The preferred URL that should be navigated to when the operating system launches your app.
*/
readonly start_url: string;
/**
* Defines the navigation scope for the app. Outside of this scope, the visited page reverts to a normal webpage, not a PWA. This defaults to start_url.
*/
readonly scope?: string;
/**
* @description
* A string with keyword values. If not specified, the default value `browser` is used.
*
* - `browser`: Opens the app in a conventional browser tab or new window, using the platform-specific convention for opening links.
* - `minimal-ui`: Opens the app to look and feel like a standalone app but with a minimal set of UI elements for navigation.
* - `standalone`: Opens the app to look and feel like a standalone native app.
* - `fullscreen`: The application will make use of all available display space.
*
* @example
* ```js
* display: "standalone"
* ```
* @tutorial
* The [display-mode](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/display-mode) media feature can be used
* to configure your application styles and other behavior based on the current display mode.
*
* ```css
* media(display-mode: standalone){
* body {
* color: red;
* }
* }
* ```
*/
readonly display?: Display;
/**
* It's similar to the `display` member, but allows you to select a fallback order for different display modes.
* - `tabbed`
* [Experimental] - The application can contain multiple application contexts inside a single OS-level window.
* - `window-controls-overlay`
* [Experimental] - This display mode only applies when the application is in a separate PWA window and on a desktop OS.
*/
readonly display_override: Array<DisplayOverride>;
/**
* Changes the default color used by certain OS features.
* For example, this would change the color of your title bar when the application is installed on Windows.
*/
readonly theme_color?: string;
/**
* Represents the page color of the window that your application will be opened in. This is the color that your app will default to before any styles are loaded. Once styles are loaded, your application will use the background color defined in your CSS.
*/
readonly background_color?: string;
/**
* On supporting devices, this defines the default orientation for the app.
*/
readonly orientation?: Orientation;
/**
* Specify an array of protocols that the application can handle.
* A protocol handler will contain `protocol` and `url` members to specify how each valid protocol is handled.
*/
readonly protocol_handlers?: Array<ProtocolHandler>;
/**
* The list of common tasks users will be able to do by right-clicking or long-pressing on the app icon.
*/
readonly shortcuts?: Array<Shotcut>;
/**
* Allows your PWA to be registered as a share target.
*/
readonly share_target?: Array<ShareTarget>;
/**
* Specify how your PWA should handle different file types.
*/
readonly file_handlers?: Array<FileHandler>;
/**
* Specify the text direction for your PWA.
*/
readonly dir?: Direction;
/**
* Specify the primary language of your app.
*/
readonly lang?: string;
/**
* Specify a suitable age range for their application.
* A rating ID is obtained by answering a questionnaire about an application, and then providing the associated ID for that application.
* You can read more about IARC [here](https://www.globalratings.com/how-iarc-works.aspx).
* @example
* ```js
* iarc_rating_id: 'e58c174a-81d2-5c3c-32cc-34b8de4a52e9'
* ```
*/
readonly iarc_rating_id?: string;
/**
* Specify applications that have similar or adjacent functionality to your application.
*/
readonly related_applications?: Array<RelatedApplication>;
/**
* Specify whether or not related_applications should be preferred to this one.
* This member defaults to `false`, but if set to `true`, the browser may recommend an alternate application to the user.
*/
readonly prefer_related_applications?: boolean;
/**
* Defines values that control the launch of a web application.
*/
readonly launch_handler?: LaunchHandler;
/**
* Specify the default link handling for the web app.
*
* - `auto`: The user agent should select the appropriate behavior for the platform (Default if not otherwise specified).
* - `preferred`: the user agent should open in-scope links within the installed application.
* - `not-preferred`: The user agent should not open links within the installed application.
*/
readonly handle_links?: "auto" | "preferred" | "not-preferred";
}
interface Widget {
/**
* The title of the widget, presented to users.
*/
readonly name: string;
/**
* An alternative short version of the name.
*/
readonly short_name?: string;
/**
* A description of what the widget does.
*/
readonly description: string;
/**
* An array of icons to be used for the widget.
* If missing, the icons manifest member is used instead.
* Icons larger than `1024x1024` are ignored.
*/
readonly icons?: Array<Icon>;
/**
* An array of screenshots that show what the widget looks like.
* Analogous to the [screenshot manifest](https://developer.mozilla.org/docs/Web/Manifest/screenshots) member.
* The platform field of a screenshot item supports the Windows and any values.
* Images larger than `1024x1024` pixels are ignored.
* For screenshot requirements specific to the Windows 11 Widgets Board,
* see Screenshot image requirements in Integrate with the widget picker.
*/
readonly screenshots: Array<Screenshot>;
/**
* A string used to reference the widget in the PWA service worker.
*/
readonly tag: string;
/**
* The template to use to display the widget in the operating system widgets dashboard.
* Note: this property is currently only informational and not used. See `ms_ac_template` below.
*/
readonly template?: string;
/**
* The URL of the custom Adaptive Cards template to use to display the widget in the operating system widgets dashboard. See Define a widget template below.
*/
readonly ms_ac_template: string;
/**
* The URL where the data to fill the template with can be found. If present, this URL is required to return valid JSON.
*/
readonly data?: string;
/**
* The MIME type for the widget data.
*/
readonly type?: string;
/**
* A boolean indicating if the widget requires authentication.
*/
readonly auth?: boolean;
/**
* The frequency, in seconds, at which the widget will be updated.
* Code in your service worker must perform the updating; the widget is not updated automatically.
* See [Access widget instances at runtime](https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/widgets#access-widget-instances-at-runtime).
*/
readonly update?: number;
/**
* A boolean indicating whether to allow multiple instances of the widget. Defaults to true.
*/
readonly multiple?: boolean;
}
interface EdageSidePanel {
preferred_width: number;
}
interface EdgeManifest extends W3Manifest {
/**
* Enable [sidebar](https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/sidebar) support in your PWA
*/
readonly edge_side_panel?: EdageSidePanel;
/**
* Widgets are [defined](https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/widgets#define-widgets)
* in your PWA manifest file, by using the `widgets` manifest member.
*/
readonly widgets?: Array<Widget>;
}
type PlatformManifests = W3Manifest & EdgeManifest;
interface Manifest extends PlatformManifests {
}
/**
* - `default` The default setting has a white background with black text and symbols.
* - `black` Black background with white text and icons.
* - `black-translucent` Transparent background with white text and icons.
* It is not possible to have a transparent status bar with black text and icons.
*/
type AppleStatusBarStyle = "default" | "black" | "black-translucent";
type PlatformName = "android" | "appleIcon" | "appleStartup" | "favicons" | "windows" | "yandex";
interface IconSize {
readonly width: number;
readonly height: number;
}
interface IconOptions {
readonly sizes: IconSize[];
readonly offset?: number;
readonly background?: string | boolean;
readonly transparent: boolean;
readonly rotate: boolean;
readonly purpose?: string;
readonly pixelArt?: boolean;
}
interface NamedIconOptions extends IconOptions {
readonly name: string;
}
interface FileOptions {
readonly manifestFileName?: string;
}
interface OutputOptions {
images?: boolean | string;
files?: boolean | string;
html?: boolean;
assetsPrefix?: string;
}
interface ShortcutOptions extends Omit<Shotcut, "icons" | "icons_localized"> {
/**
* Shortcut icon source file, used to automatically generate transparent icons of (36, 48, 72, 96, 144, 192) square sizes.
*/
readonly icon?: string | Buffer | (string | Buffer)[];
}
interface ScreenshotOptions extends Omit<Screenshot, "src" | "form_factor"> {
/**
* Source file used to produce screenshots. Currently only supports format conversion, controlled by `type` type
*/
readonly src: string | Buffer | (string | Buffer)[];
readonly form_factor?: Screenshot["form_factor"];
}
interface FaviconOptions extends Pick<Manifest, "name" | "name_localized" | "short_name" | "short_name_localized"> {
/**
* Specify the value of the `theme_color` member in the manifest. Control the user's preferred color scheme (light and dark).
* @example
* ```js
* themes: ["#fff", "#000"]
* ```
* output HTML
* ```html
* <meta name="theme-color" media="(prefers-color-scheme: light)" content="#fff">
* <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#000">
* ```
*/
readonly themes?: string[];
readonly appleStatusBarStyle?: AppleStatusBarStyle;
/**
* Similar to the background_color in the manifest.
* Will be used as the default background color when some icons are generated
*/
readonly background?: string;
/**
* Specify the rules you need in `manifest.webmanifest`.
*
* @tutorial
* Currently supports all rules in [w3.org](https://www.w3.org/TR/appmanifest/#web-application-manifest) and some rules in Edge.
* Please submit an issue if necessary to expand more.
*/
readonly manifest?: Omit<Manifest, "name" | "name_localized" | "short_name" | "short_name_localized" | "theme_color" | "background_color" | "icons" | "shortcuts" | "screenshots">;
/**
* Specify generated rules and automatically add `icons` member to manifest.
*/
readonly icons?: Record<PlatformName, boolean | (NamedIconOptions | string)[]>;
/**
* Specify generated rules and automatically add `shortcuts` member to manifest.
*/
readonly shortcuts?: Array<ShortcutOptions>;
/**
* Specify generated rules and automatically add `screenshots` member to manifest.
*/
readonly screenshots?: Array<ScreenshotOptions>;
readonly loadManifestWithCredentials?: boolean;
readonly manifestRelativePaths?: boolean;
/**
* Specify rules for `maskable` icons and automatically add sub-items to the `icons` member in the manifest.
*/
readonly manifestMaskable?: boolean | string | Buffer | (string | Buffer)[];
/**
* @example "v=1.0.0"
*/
readonly cacheBustingQueryParam?: string | null;
/**
* Keeps pixels "sharp" when scaling up, for pixel art.
*/
readonly pixel_art?: boolean;
readonly output?: OutputOptions;
/**
* Customize the manifest file name for each platform.
*/
readonly files?: Record<PlatformName, FileOptions>;
/**
* Specify the version value in the Yandex browser manifest.
*/
readonly version?: string;
}
interface FaviconImage {
readonly name: string;
readonly contents: Buffer;
}
interface FaviconFile {
readonly name: string;
readonly contents: string;
}
declare const config: {
defaults: FaviconOptions;
};
type FaviconHtmlElement = string;
interface FaviconResponse {
readonly images: FaviconImage[];
readonly files: FaviconFile[];
readonly html: FaviconHtmlElement[];
}
declare function favicons(source: string | Buffer | (string | Buffer)[], options?: FaviconOptions): Promise<FaviconResponse>;
interface FaviconStreamOptions extends FaviconOptions {
readonly html?: string;
readonly pipeHTML?: boolean;
readonly emitBuffers?: boolean;
}
type HandleHTML = (html: FaviconHtmlElement[]) => void;
declare class FaviconStream extends Transform {
constructor(options: FaviconStreamOptions, handleHTML: HandleHTML);
_transform(file: any, // eslint-disable-line @typescript-eslint/no-explicit-any -- superclass uses any
_encoding: BufferEncoding, callback: TransformCallback): void;
}
declare function stream(options: FaviconStreamOptions, handleHTML: HandleHTML): FaviconStream;
export { type FaviconFile, type FaviconHtmlElement, type FaviconImage, type FaviconOptions, type FaviconResponse, type FaviconStreamOptions, type HandleHTML, type NamedIconOptions, type PlatformName, config, favicons as default, favicons, stream };