import MagicString , { SourceMapOptions } from 'magic-string' ; import { Template , TemplatePart , ParseLiteralsOptions , parseLiterals } from 'parse-literals' ; import { Strategy , defaultMinifyOptions , defaultStrategy } from './strategy' ; /**
 * Options for <code>minifyHTMLLiterals()</code>.
 */ export type Options = DefaultOptions | CustomOptions < any > ; /**
 * Options for <code>minifyHTMLLiterals()</code>, using default html-minifier
 * strategy.
 */ export interface DefaultOptions extends BaseOptions { /**
     * <code>html-minifier</code> options to use. Defaults to
     * <code>defaultMinifyOptions</code>, for production-ready minification.
     */ minifyOptions ? : Partial < typeof defaultMinifyOptions > ; } /**
 * Options for <code>minifyHTMLLiterals()</code>, using a custom strategy.
 */ export interface CustomOptions < S extends Strategy > extends BaseOptions { /**
     * HTML minification options.
     */ minifyOptions ? : S extends Strategy < infer O > ? Partial < O > : never ; /**
     * Override the default strategy for how to minify HTML. The default is to
     * use <code>html-minifier</code>.
     */ strategy : S ; } /**
 * Options for <code>minifyHTMLLiterals()</code>.
 */ export interface BaseOptions { /**
     * The name of the file. This is used to determine how to parse the source
     * code and for source map filenames. It may be a base name, relative, or
     * absolute path.
     */ fileName ? : string ; param ms param fileName returns generateSourceMap ? : ( ( ms : MagicStringLike , fileName : string ) => SourceMap | undefined ) | false ; /**
     * The MagicString-like constructor to use. MagicString is used to replace
     * strings and generate source maps.
     *
     * Override if you want to set your own version of MagicString or change how
     * strings are overridden. Use <code>generateSourceMap</code> if you want to
     * change how source maps are created.
     */ MagicString ? : { new ( source ) : MagicStringLike ; } ; /**
     * Override how template literals are parsed from a source string.
     */ parseLiterals ? : typeof parseLiterals ; /**
     * Options for <code>parseLiterals()</code>.
     */ parseLiteralsOptions ? : Partial < ParseLiteralsOptions > ; param template returns shouldMinify ? ( template ) : boolean ; param template returns shouldMinifyCSS ? ( template ) : boolean ; /**
     * Override custom validation or set to false to disable validation. This is
     * only useful when implementing your own strategy that may return
     * unexpected results.
     */ validate ? : Validation | false ; } /**
 * A MagicString-like instance. <code>minify-html-literals</code> only uses a
 * subset of the MagicString API to overwrite the source code and generate
 * source maps.
 */ export interface MagicStringLike { generateMap ( options ? ) : SourceMap ; overwrite ( start , end , content ) : any ; toString ( ) : string ; } /**
 * A v3 SourceMap.
 *
 * <code>magic-string> incorrectly declares the SourceMap type with a version
 * string instead of a number, so <code>minify-html-literals</code> declares
 * its own type.
 */ export interface SourceMap { version : number | string ; file : string | null ; sources : Array < string | null > ; sourcesContent : Array < string | null > ; names : string [ ] ; mappings : string ; toString ( ) : string ; toUrl ( ) : string ; } /**
 * Validation that is executed when minifying HTML to ensure there are no
 * unexpected errors. This is to alleviate hard-to-troubleshoot errors such as
 * undefined errors.
 */ export interface Validation { param placeholder ensurePlaceholderValid ( placeholder ) : void ; param parts param htmlParts ensureHTMLPartsValid ( parts , htmlParts ) : void ; } /**
 * The result of a call to <code>minifyHTMLLiterals()</code>.
 */ export interface Result { /**
     * The minified code.
     */ code : string ; /**
     * Optional v3 SourceMap for the code.
     */ map : SourceMap | undefined ; } param ms param fileName returns export function defaultGenerateSourceMap ( ms , fileName ) { return ms . generateMap ( { file : `${ fileName }.map` , source : fileName , hires : true } ) ; } param template returns export function defaultShouldMinify ( template ) { const tag = template . tag && template . tag . toLowerCase ( ) ; return ! ! tag && ( tag . includes ( 'html' ) || tag . includes ( 'svg' ) ) ; } param template returns export function defaultShouldMinifyCSS ( template ) { return ! ! template . tag && template . tag . toLowerCase ( ) . includes ( 'css' ) ; } /**
 * The default validation.
 */ export const defaultValidation = { ensurePlaceholderValid ( placeholder ) { if ( typeof placeholder !== 'string' || ! placeholder . length ) { throw new Error ( 'getPlaceholder() must return a non-empty string' ) ; } } , ensureHTMLPartsValid ( parts , htmlParts ) { if ( parts . length !== htmlParts . length ) { throw new Error ( 'splitHTMLByPlaceholder() must return same number of strings as template parts' ) ; } } } ; param source param options returns export function minifyHTMLLiterals ( source , options ? ) ; param source param options returns export function minifyHTMLLiterals < S extends Strategy > ( source , options ? ) ; export function minifyHTMLLiterals ( source , options = { } ) { options . minifyOptions = { ... defaultMinifyOptions , ... ( options . minifyOptions || { } ) } ; if ( ! options . MagicString ) { options . MagicString = MagicString ; } if ( ! options . parseLiterals ) { options . parseLiterals = parseLiterals ; } if ( ! options . shouldMinify ) { options . shouldMinify = defaultShouldMinify ; } if ( ! options . shouldMinifyCSS ) { options . shouldMinifyCSS = defaultShouldMinifyCSS ; } options . parseLiteralsOptions = { ... { fileName : options . fileName } , ... ( options . parseLiteralsOptions || { } ) } ; const templates = options . parseLiterals ( source , options . parseLiteralsOptions ) ; const strategy = < Strategy > ( < CustomOptions < any > > options ) . strategy || defaultStrategy ; const { shouldMinify , shouldMinifyCSS } = options ; let validate ; if ( options . validate !== false ) { validate = options . validate || defaultValidation ; } const ms = new options . MagicString ( source ) ; templates . forEach ( template => { const minifyHTML = shouldMinify ( template ) ; const minifyCSS = ! ! strategy . minifyCSS && shouldMinifyCSS ( template ) ; if ( minifyHTML || minifyCSS ) { const placeholder = strategy . getPlaceholder ( template . parts ) ; if ( validate ) { validate . ensurePlaceholderValid ( placeholder ) ; } const combined = strategy . combineHTMLStrings ( template . parts , placeholder ) ; let min ; if ( minifyCSS ) { const minifyCSSOptions = ( ( options as DefaultOptions ) . minifyOptions || { } ) . minifyCSS ; if ( typeof minifyCSSOptions === 'function' ) { min = minifyCSSOptions ( combined ) ; } else if ( minifyCSSOptions === false ) { min = combined ; } else { const cssOptions = typeof minifyCSSOptions === 'object' ? minifyCSSOptions : undefined ; min = strategy . minifyCSS ! ( combined , cssOptions ) ; } } else { min = strategy . minifyHTML ( combined , options . minifyOptions ) ; } const minParts = strategy . splitHTMLByPlaceholder ( min , placeholder ) ; if ( validate ) { validate . ensureHTMLPartsValid ( template . parts , minParts ) ; } template . parts . forEach ( ( part , index ) => { if ( part . start < part . end ) { ms . overwrite ( part . start , part . end , minParts [ index ] ) ; } } ) ; } } ) ; const sourceMin = ms . toString ( ) ; if ( source === sourceMin ) { return null ; } else { let map ; if ( options . generateSourceMap !== false ) { const generateSourceMap = options . generateSourceMap || defaultGenerateSourceMap ; map = generateSourceMap ( ms , options . fileName || '' ) ; } return { map , code : sourceMin } ; } }