convert-svg-core
Version:
Supports converting SVG into another format using headless Chromium
346 lines • 18.1 kB
TypeScript
import { type Browser, type LaunchOptions, type WaitForOptions } from "puppeteer-core";
import type { IProvider } from "./provider.js";
/**
* Converts SVG to another format using a headless Chromium instance.
*
* When an {@link IConverter} is created it must either be passed an existing {@link Browser} instance via
* {@link IConverterOptions#browser} or {@link IConverterLaunchOptions} via {@link IConverterOptions#launch} so that a
* browser instance can be created or connected; otherwise it will fail to be created.
*
* If an existing {@link Browser} instance is being used you may want to also consider what happens if/when the
* {@link IConverter} is closed (e.g. via {@link #close}) as the default behavior is to close the browser and all open
* pages, even those not opened by the {@link IConverter}. It can instead be instructed to either disconnect from the
* browser process or do nothing at all via {@link IConverterOptions#closeBehavior}.
*
* Due to constraints within Chromium, the SVG input is first written to a temporary HTML file and then navigated to.
* This is because the default page for Chromium is using the `chrome` protocol so cannot load externally referenced
* files (e.g. that use the `file` protocol). Each invocation of {@link #convert} or {@link #convertFile} open their own
* {@link Page} and create their own temporary files to avoid conflicts with other asynchronous invocations, which is
* closed and deleted respectively once finished. This allows a single {@link IConverter} to safely process these calls
* concurrently.
*
* An {@link IConverter} uses its own {@link BrowserContext} to open each new {@link Page}. This ensures that the pages
* are isolated and that they can be closed by the {@link IConverter} accordingly.
*
* It's also the responsibility of the caller to ensure that all {@link IConverter} instances are closed before the
* process exits.
*/
export interface IConverter<ConvertOptions extends IConverterConvertOptions, ConvertOptionsParsed extends IConverterConvertOptionsParsed> {
/**
* Whether this {@link IConverter} has been closed.
*/
readonly closed: boolean;
/**
* The {@link IProvider} for this {@link IConverter}.
*/
readonly provider: IProvider<ConvertOptions, ConvertOptionsParsed>;
/**
* Closes this {@link IConverter}.
*
* What happens when the {@link IConverter} closes depends entirely on which {@link IConverterCloseBehavior} is being
* used. The default behaviour is `"close"` but this may have been changed via {@link IConverterOptions#closeBehavior}
* when this {@link IConverter} was created.
*
* Regardless of the behavior above, any temporary files that may have been created by this {@link IConverter} that
* have not yet been deleted will be deleted now.
*
* Once closed, this {@link IConverter} should be discarded and a new one created, as and when needed.
*
* An error will occur if any problem arises while performing the closing behavior, where applicable.
*/
close(): Promise<void>;
/**
* Converts the specified `input` SVG into another format using the `options` provided.
*
* `input` can either be an SVG buffer or string.
*
* If the width and/or height cannot be derived from `input`; then they must be provided via their corresponding
* options. This method attempts to derive the dimensions from `input` via any `width`/`height` attributes or its
* calculated `viewBox` attribute.
*
* Only standard SVG element attributes (excl. event attributes) are allowed, and others are stripped from the SVG
* before being converted. This includes deprecated attributes unless the `allowDeprecatedAttributes` option is
* disabled. This is primarily for security purposes to ensure that malicious code cannot be injected.
*
* This method is resolved with the converted output buffer.
*
* An error will occur if this {@link IConverter} has been closed, both the `baseFile` and `baseUrl` options have been
* provided, `input` does not contain an SVG element, or no `width` and/or `height` options were provided and this
* information could not be derived from `input`.
*
* @param input The SVG input to be converted to another format.
* @param options The options to be used.
* @return The converted output buffer.
*/
convert(input: Buffer | string, options?: ConvertOptions): Promise<Buffer>;
/**
* Converts the SVG file at the specified path into another format using the `options` provided and writes it to the
* output file.
*
* The output file is derived from `inputFilePath` unless the `outputFilePath` option is specified.
*
* If the width and/or height cannot be derived from the input file, then they must be provided via their
* corresponding options. This method attempts to derive the dimensions from the input file via any `width`/`height`
* attributes or its calculated `viewBox` attribute.
*
* Only standard SVG element attributes (excl. event attributes) are allowed, and others are stripped from the SVG
* before being converted. This includes deprecated attributes unless the `allowDeprecatedAttributes` option is
* disabled. This is primarily for security purposes to ensure that malicious code cannot be injected.
*
* This method is resolved with the path of the converted output file for reference.
*
* An error will occur if this {@link IConverter} has been closed, both the `baseFile` and `baseUrl` options have been
* provided, the input file does not contain an SVG element, no `width` and/or `height` options were provided and this
* information could not be derived from an input file, or a problem arises while reading the input file or writing
* the output file.
*
* @param inputFilePath The path of the SVG file to be converted to another file format.
* @param options The options to be used.
* @return The output file path.
*/
convertFile(inputFilePath: string, options?: IConverterConvertFileOptions<ConvertOptions>): Promise<string>;
}
/**
* The options that can be used to construct an implementation of {@link IConverter}.
*/
export interface IConverterOptions<ConvertOptions extends IConverterConvertOptions, ConvertOptionsParsed extends IConverterConvertOptionsParsed> {
/**
* An existing {@link Browser} instance provided by `puppeteer-core` that is used to create a {@link BrowserContext}
* to open each new {@link Page} to capture a screenshot of an SVG to convert it into another format. If specified,
* {@link #launch} will be ignored.
*
* For context; each {@link IConverter} instance uses their own {@link BrowserContext} to open each new {@link Page}.
* This ensures that the pages are isolated and that they can be closed by the {@link IConverter} accordingly. A
* {@linl Page} is opened for each invocation of {@link IConverter#convert} and {@link IConverter#convertFile} and
* closed once finished. If the {@link IConverter} is closed (e.g. via {@link IConverter#close}), any pages currently
* open due to ongoing invocations of those methods will be closed immediately and will likely result in them
* rejecting.
*/
browser?: Browser;
/**
* The behavior when the {@link IConverter} is closed (e.g. via {@link IConverter#close}), which may be one of the
* following:
*
* - `"close"` - Calls {@link Browser#close}, effectively closing the browser and therefore all open pages, even those
* not opened by the {@link IConverter} in the scenario that a shared browser instance or connection is being used.
* This is the default behavior as it typically makes most sense for those wanting to just let the `convert-svg-*`
* package to manage the browser resources.
* - `"disconnect"` - Calls {@link BrowserContext#close} and {@link Browser#disconnect}, effectively closing any pages
* opened by the {@link IConverter} and disconnecting from the browser, keeping the browser process running and any
* other pages created outside the {@link IConverter} open.
* - `"none"` - Calls {@link BrowserContext#close}, effectively closing any pages opened by the {@link IConverter} but
* not doing anything with the browser. This could potentially result in a browser instance running that cannot be
* accessed to close depending on what was responsible for creating or connecting to the browser.
*
* Care should be taken when specifying this option that the consequences are fully understood as well as the shift in
* the responsibilities to the caller to ensure that resources are managed accordingly.
*
* @defaultValue "close"
*/
closeBehavior?: IConverterCloseBehavior;
/**
* The options that are to be passed directly to `puppeteer-core` when launching a new {@link Browser} that is used to
* create a {@link BrowserContext} to open each new {@link Page} to capture a screenshot of an SVG to convert it into
* another format. Ignored if {@link #browser} is also specified.
*
* For context; each {@link IConverter} instance uses their own {@link BrowserContext} to open each new {@link Page}.
* This ensures that the pages are isolated and that they can be closed by the {@link IConverter} accordingly. A
* {@linl Page} is opened for each invocation of {@link IConverter#convert} and {@link IConverter#convertFile} and
* closed once finished. If the {@link IConverter} is closed (e.g. via {@link IConverter#close}), any pages currently
* open due to ongoing invocations of those methods will be closed immediately and will likely result in them
* rejecting.
*/
launch?: IConverterLaunchOptions;
/**
* The options that are to be passed directly to `puppeteer-core` when populating a {@link Page} with the SVG
* contents.
*
* For context; each {@link IConverter} instance uses their own {@link BrowserContext} to open each new {@link Page}.
* This ensures that the pages are isolated and that they can be closed by the {@link IConverter} accordingly. A
* {@linl Page} is opened for each invocation of {@link IConverter#convert} and {@link IConverter#convertFile} and
* closed once finished. If the {@link IConverter} is closed (e.g. via {@link IConverter#close}), any pages currently
* open due to ongoing invocations of those methods will be closed immediately and will likely result in them
* rejecting.
*/
page?: WaitForOptions;
/**
* The {@link IProvider} to be used.
*/
provider: IProvider<ConvertOptions, ConvertOptionsParsed>;
}
/**
* The behavior when a {@link IConverter} is closed (e.g. via {@link IConverter#close}), which may be one of the
* following:
*
* - `"close"` - Calls {@link Browser#close}, effectively closing the browser and therefore all open pages, even those
* not opened by the {@link IConverter} in the scenario that a shared browser instance or connection is being used.
* - `"disconnect"` - Calls {@link BrowserContext#close} and {@link Browser#disconnect}, effectively closing any pages
* opened by the {@link IConverter} and disconnecting from the browser, keeping the browser process running and any
* other pages created outside the {@link IConverter} open.
* - `"none"` - Calls {@link BrowserContext#close}, effectively closing any pages opened by the {@link IConverter} but
* not doing anything with the browser. This could potentially result in a browser instance running that cannot be
* accessed to close depending on what was responsible for creating or connecting to the browser.
*/
export type IConverterCloseBehavior = "close" | "disconnect" | "none";
/**
* The options that can be passed to {@link IConverter#convert}.
*/
export interface IConverterConvertOptions {
/**
* Whether deprecated SVG element attributes should be retained in the SVG during conversion.
*
* @defaultValue true
*/
allowDeprecatedAttributes?: boolean;
/**
* The background color to be used to fill transparent regions within the SVG. If omitted, the {@link IProvider} will
* determine the default background color.
*/
background?: string;
/**
* The path of the file to be converted into a file URL to use for all relative URLs contained within the SVG. Cannot
* be used in conjunction with {@link #baseUrl}.
*/
baseFile?: string;
/**
* The base URL to use for all relative URLs contained within the SVG. Cannot be used in conjunction with
* {@link #baseFile}.
*/
baseUrl?: string;
/**
* The height of the output to be generated. If omitted, an attempt will be made to derive the height from the SVG
* input.
*/
height?: number | string;
/**
* The type of rounding to be applied to the width and height, which may be one of the following:
*
* - `"ceil"` - Values are rounded using `Math.ceil`.
* - `"floor"` - Values are rounded using `Math.floor`.
* - `"round"` - Values are rounded using `Math.round`. The default rounding used, if omitted.
*
* @defaultValue "round"
*/
rounding?: IConverterRounding;
/**
* The scale to be applied to the width and height (either specified as options or derived).
*
* @defaultValue 1
*/
scale?: number;
/**
* The width of the output to be generated. If omitted, an attempt will be made to derive the width from the SVG
* input.
*/
width?: number | string;
}
/**
* The options that can be passed to {@link IConverter#convert} after being parsed.
*/
export interface IConverterConvertOptionsParsed {
/**
* Whether deprecated SVG element attributes should be retained in the SVG during conversion.
*/
allowDeprecatedAttributes: boolean;
/**
* The background color to be used to fill transparent regions within the SVG. If omitted, the {@link IProvider} will
* determine the default background color.
*/
background?: string;
/**
* The base URL to use for all relative URLs contained within the SVG.
*/
baseUrl: string;
/**
* The height of the output to be generated. If omitted, an attempt will be made to derive the height from the SVG
* input.
*/
height?: number;
/**
* The type of rounding to be applied to the width and height, which may be one of the following:
*
* - `"ceil"` - Values are rounded using `Math.ceil`.
* - `"floor"` - Values are rounded using `Math.floor`.
* - `"round"` - Values are rounded using `Math.round`.
*/
rounding: IConverterRounding;
/**
* The scale to be applied to the width and height (either specified as options or derived).
*/
scale: number;
/**
* The width of the output to be generated. If omitted, an attempt will be made to derive the width from the SVG
* input.
*/
width?: number;
}
/**
* The options that can be passed to {@link IConverter#convertFile}.
*/
export type IConverterConvertFileOptions<ConvertOptions extends IConverterConvertOptions> = ConvertOptions & {
/**
* The path of the file to which the output should be written to. By default, this will be derived from the input file
* path.
*/
outputFilePath?: string;
};
/**
* The options that can be passed to {@link IConverter#convertFile} after being parsed.
*/
export type IConverterConvertFileOptionsParsed<ConvertOptionsParsed extends IConverterConvertOptionsParsed> = ConvertOptionsParsed & {
/**
* The path of the file to which the output should be written to.
*/
outputFilePath: string;
};
/**
* TODO: Document
*/
export type IConverterLaunchOptions = Omit<LaunchOptions, "executablePath"> & {
/**
* TODO: Document
*
* @param options
* @return
*/
executablePath?: string | ((options: LaunchOptions) => string);
};
/**
* The type of rounding to be applied to the width and height during a conversion, which may be one of the following:
*
* - `"ceil"` - Values are rounded using `Math.ceil`.
* - `"floor"` - Values are rounded using `Math.floor`.
* - `"round"` - Values are rounded using `Math.round`.
*/
export type IConverterRounding = "ceil" | "floor" | "round";
/**
* An implementation of {@link IConverter}.
*/
export declare class Converter<ConvertOptions extends IConverterConvertOptions, ConvertOptionsParsed extends IConverterConvertOptionsParsed> implements IConverter<ConvertOptions, ConvertOptionsParsed> {
#private;
/**
* Creates an instance of {@link Converter} using the `options` provided.
*
* A {@link BrowserContext} is created from the either {@link IConverterOptions#browser}, if specified, or a new
* {@link Browser} instance launched using {@link IConverterOptions#launch}.
*
* An error will occur if neither of the above options is specified.
*
* @param options The options to be used.
* @return A newly created {@link Converter} instance.
*/
static create<ConvertOptions extends IConverterConvertOptions, ConvertOptionsParsed extends IConverterConvertOptionsParsed>(options: IConverterOptions<ConvertOptions, ConvertOptionsParsed>): Promise<Converter<ConvertOptions, ConvertOptionsParsed>>;
/**
* TODO: Document
*
* @return
*/
static parseEnvLaunchOptions(): IConverterLaunchOptions | undefined;
private constructor();
convert(input: Buffer | string, options?: ConvertOptions): Promise<Buffer>;
convertFile(inputFilePath: string, options?: IConverterConvertFileOptions<ConvertOptions>): Promise<string>;
close(): Promise<void>;
get closed(): boolean;
get provider(): IProvider<ConvertOptions, ConvertOptionsParsed>;
}
//# sourceMappingURL=converter.d.ts.map