{"version":3,"sources":["jsdelivr-header.js","/npm/vite-plugin-virtual-html@1.1.16/src/index.ts","/npm/vite-plugin-virtual-html@1.1.16/src/html/types.ts","/npm/vite-plugin-virtual-html@1.1.16/src/html/Base.ts","/npm/vite-plugin-virtual-html@1.1.16/src/html/utils.ts","/npm/vite-plugin-virtual-html@1.1.16/src/history-api/historyApiFallbackPlugin.ts","/npm/vite-plugin-virtual-html@1.1.16/src/html/Serve.ts","/npm/vite-plugin-virtual-html@1.1.16/src/html/Build.ts","/npm/vite-plugin-virtual-html@1.1.16/src/html/VirtualHtmlPlugin.ts"],"names":[],"mappings":"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","file":"/npm/vite-plugin-virtual-html@1.1.16/dist/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/vite-plugin-virtual-html@1.1.16/dist/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import type {Plugin,} from 'vite'\nimport type {HtmlPluginOptions,} from './html/types'\nimport virtualHtmlPlugin from \"./html/VirtualHtmlPlugin\"\nimport type {HistoryApiOptions} from \"./history-api/types\"\n\nexport default (virtualHtmlOptions: HtmlPluginOptions & HistoryApiOptions): Plugin => {\n  return new virtualHtmlPlugin(virtualHtmlOptions)\n}\n\nexport * from './history-api/historyApiFallbackPlugin'\n\nexport * from './html/types'\n\nexport * from './history-api/types'\n","import { type IncomingMessage } from 'http'\n\nexport type PageObject = {\n  template: string,\n  data?: VirtualHtmlTemplateData,\n  render?: VirtualHtmlTemplateRender,\n}\n/**\n * describe a page\n */\nexport type VirtualHtmlPage = string | PageObject | VirtualPageOptions\n/**\n * html template render\n */\nexport type VirtualHtmlTemplateRender = (template: string, data: Record<string, any>) => string\n\nexport type VirtualHtmlTemplateData = Record<string, any>\n\nexport type Pages = { [key: string]: VirtualHtmlPage }\n\nexport type VirtualPageOptions = {\n  entry: string,\n  title?: string,\n  body?: string,\n}\n\nexport type UrlTransformerFunction = (resolvedUrl: string,req: IncomingMessage) => string\n\n/**\n * plugin config options\n */\nexport type HtmlPluginOptions = {\n  /**\n   * config html-entries' path\n   * if it is true, plugin will use glob to find all the html page in project to generate a json like {a: /src/a/a.html,}\n   */\n  pages?: Pages | true,\n  /**\n   * transform url to another url by user.\n   * This is ONLY apply in dev mode.\n   * @param url\n   */\n  urlTransformer?: UrlTransformerFunction\n  /**\n   * define the index page,to replace default index.html\n   * this page will trigger `transformIndexHtml` hook.\n   */\n  indexPage?: string,\n  /**\n   * use for template. as global inject data\n   */\n  data?: Record<string, unknown>\n  /**\n   * function to render template\n   */\n  render?: VirtualHtmlTemplateRender\n  /**\n   * when pages set to true, customize fast-glob's pattern\n   * default value is ['**\\\\*.html', '!node_modules\\\\**\\\\*.html', '!.**\\\\*.html']\n   */\n  extraGlobPattern?: Array<string>\n  /**\n   * inject code to html\n   * key: html name, can be *\n   */\n  injectCode?: Record<string, InjectCode>\n\n}\n\n/**\n * inject code to tag's before or after\n */\nexport enum POS {\n  before,\n  after\n}\n\n/**\n * inject code config\n */\nexport type InjectCode = {\n  pos: POS,\n  find: string,\n  replacement: string,\n}\n","import type { HtmlPluginOptions, InjectCode, PageObject, VirtualHtmlTemplateData } from './types'\nimport { Pages, POS, VirtualHtmlPage, VirtualHtmlTemplateRender, VirtualPageOptions } from './types'\nimport { type UserConfig, createFilter, } from 'vite'\nimport * as path from 'path'\nimport * as fs from 'fs'\nimport { normalizePath, } from './utils'\nimport glob from 'fast-glob'\nimport debug from 'debug'\n\nconst fsp = fs.promises\nconst DEFAULT_GLOB_PATTERN = [\n  '**/*.html',\n  '!node_modules/**/*.html',\n  '!.**/*.html'\n]\nconst VIRTUAL_HTML_CONTENT = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>#TITLE#</title>\n    <script src=\"#ENTRY#\" type=\"module\"></script>\n</head>\n<body>\n#BODY#\n</body>\n</html>\n`\nexport const DEFAULT_INJECTCODE_ALL = '*'\n\nexport class Base {\n  _config?: UserConfig\n  \n  _pages: Pages\n  \n  _indexPage: string\n  \n  _globalRender: VirtualHtmlTemplateRender\n  \n  _globalData: Record<string, unknown>\n  \n  _injectCode: Record<string, InjectCode>\n  \n  cwd = normalizePath(process.cwd())\n  logger = debug('vite-plugin-virtual-html')\n  _filter: (id: string | unknown) => boolean\n  \n  constructor(virtualHtmlOptions: HtmlPluginOptions) {\n    const {\n      pages: pagesObj,\n      indexPage = 'index',\n      render = this.defaultRender,\n      data = {},\n      extraGlobPattern = [],\n      injectCode = {},\n    } = virtualHtmlOptions\n    if (pagesObj === true || pagesObj === undefined) {\n      this._pages = this.findAllHtmlInProject(extraGlobPattern)\n    } else {\n      this._pages = pagesObj\n    }\n    this._indexPage = indexPage\n    this._globalData = data\n    this._globalRender = render\n    this._injectCode = injectCode\n    this._filter = createFilter(/\\.html|\\/$/,)\n  }\n  \n  /**\n   * load html file\n   * @param id\n   */\n  _load = async (id: string) => {\n    if (this._filter(id)) {\n      let newId = this.getHtmlName(id, this._config?.root)\n      const maybeIndexName1 = (newId+'/').replace('//', '/')\n      const maybeIndexName2 = (newId + '/index').replace('//', '/')\n      const maybeIndexName3 = newId.replace('index', '').replace('//', '/')\n      \n      const pageOption: VirtualHtmlPage | VirtualPageOptions = this._pages[newId] || this._pages[maybeIndexName1] || this._pages[maybeIndexName2] || this._pages[maybeIndexName3]\n      if (pageOption !== undefined) {\n        // string\n        if (typeof pageOption === 'string') {\n          const page = await this.generatePageOptions(pageOption, this._globalData, this._globalRender)\n          // generate html template\n          return await this.readHtml(page)\n        }\n        // PageObject\n        if ('template' in pageOption) {\n          const page = await this.generatePageOptions(pageOption, this._globalData, this._globalRender)\n          // generate html template\n          return await this.readHtml(page)\n        }\n        // VirtualPageOptions\n        if ('entry' in pageOption) {\n          return await this.generateVirtualPage(pageOption)\n        }\n      }\n    }\n    return null\n  }\n  \n  /**\n   * transform code to inject some code into original code\n   * @param code\n   * @param id\n   */\n  _transform = async (code: string, id: string): Promise<string | null> => {\n    if (this._filter(id)) {\n      const ids = id.split('/')\n      const key = ids[ids.length - 1]\n      let _code = code\n      if (DEFAULT_INJECTCODE_ALL in this._injectCode) {\n        _code = this.generateInjectCode(this._injectCode[DEFAULT_INJECTCODE_ALL], _code)\n      }\n      if (key in this._injectCode) {\n        _code = this.generateInjectCode(this._injectCode[key], _code)\n      }\n      return _code\n    }\n    return null\n  }\n  \n  /**\n   * get html file's name\n   * @param id\n   * @param root\n   */\n  getHtmlName = (id: string, root?: string) => {\n    const _root = (root ?? '').replace(this.cwd, '')\n    const _id = id.replace(this.cwd, '')\n    const result = _id.replace('.html','').replace(_root !== '' ? this.addTrailingSlash(_root) : '', '')\n    return result.startsWith('/') ? result.substring(1,result.length) : result\n  }\n  \n  /**\n   * add trailing slash on path\n   * @param {string} path\n   * @returns {string}\n   */\n  addTrailingSlash = (path: string): string => {\n    const _path = normalizePath(path.replace(this.cwd, ''))\n    return _path.endsWith('/') ? _path : `${_path}/`\n  }\n  \n  /**\n   * generate URL\n   * @param url\n   */\n  generateUrl = (url?: string): string => {\n    if (!url) {\n      return '/'\n    }\n    // url with parameters\n    if (url.indexOf('?') > 0) {\n      return url.split('?')[0]\n    }\n    return url\n  }\n  \n  /**\n   * read HTML file from disk and generate code from template system(with render function)\n   * @param template\n   * @param data\n   * @param render\n   */\n  readHtml = async ({\n                      template = '',\n                      data = {},\n                      render = this.defaultRender\n                    }: PageObject) => {\n    const templatePath = path.resolve(this.cwd, `.${template}`)\n    if (!fs.existsSync(templatePath)) {\n      this.logger('[vite-plugin-virtual-html]: template file must exist!')\n      return ''\n    }\n    return await this.renderTemplate(templatePath, render, data)\n  }\n  \n  /**\n   * render template\n   * @param templatePath\n   * @param render\n   * @param data\n   */\n  renderTemplate = async (templatePath: string, render: VirtualHtmlTemplateRender, data: VirtualHtmlTemplateData) => {\n    return await this.readTemplate(templatePath).then(code => {\n      return render(code, data)\n    })\n  }\n  \n  /**\n   * read html file's content to render with render function\n   * @param templatePath\n   */\n  readTemplate = async (templatePath: string): Promise<string> => {\n    const result = await fsp.readFile(templatePath)\n    return result.toString()\n  }\n  \n  /**\n   * generate page option from string/object to object\n   * @param page\n   * @param globalData\n   * @param globalRender\n   */\n  generatePageOptions = async (page: PageObject | string, globalData: Record<string, unknown>, globalRender: VirtualHtmlTemplateRender): Promise<PageObject> => {\n    if (typeof page === 'string') {\n      return {\n        template: page,\n        data: {\n          ...globalData,\n        },\n        render: globalRender,\n      }\n    }\n    const {\n      data = {},\n      render,\n      template\n    } = page\n    return {\n      template: template,\n      data: {\n        ...globalData,\n        ...data,\n      },\n      render: render ?? globalRender ?? this.defaultRender,\n    }\n  }\n  \n  /**\n   * directly use find\\replacement / replacement\\find to replace find\n   * @param {pos, find, replacement}\n   * @param code\n   */\n  generateInjectCode = ({\n                          pos,\n                          find,\n                          replacement\n                        }: InjectCode, code: string): string => {\n    if (pos === POS.after) {\n      return code.replace(find, `${find}\\n${replacement}`)\n    }\n    if (pos === POS.before) {\n      return code.replace(find, `\\n${replacement}\\n${find}`)\n    }\n    return code\n  }\n  \n  /**\n   * generate page from virtual page\n   * @param vPages\n   */\n  generateVirtualPage = async (vPages: VirtualPageOptions): Promise<string> => {\n    const {\n      entry,\n      title = '',\n      body = '<div id=\"app\"></div>'\n    } = vPages\n    return VIRTUAL_HTML_CONTENT.replace('#ENTRY#', entry).replace('#TITLE#', title).replace('#BODY#', body)\n  }\n  \n  /**\n   * find all html file in project and return it as Pages\n   */\n  findAllHtmlInProject = (extraGlobPattern: Array<string> = []): Pages => {\n    const pages: Pages = {}\n    let realPattern: Array<string> = []\n    if (extraGlobPattern.length === 0) {\n      realPattern = DEFAULT_GLOB_PATTERN\n    } else {\n      const set: Set<string> = new Set()\n      DEFAULT_GLOB_PATTERN.forEach(dg=>set.add(dg))\n      extraGlobPattern.forEach(dg=>set.add(dg))\n      for (let key of set.keys()) {\n        realPattern.push(key)\n      }\n    }\n    const files = glob.sync(realPattern)\n    files.forEach(file => {\n      const filePathArr = file.split('/')\n      pages[filePathArr[filePathArr.length - 1].replace('.html', '')] = `/${file}`\n    })\n    return pages\n  }\n  \n  defaultRender = (template: string, data: Record<string, any>) => {\n    try {\n      const resolved = require.resolve('ejs')\n      return require(resolved).render(template, data, {\n        delimiter: '%',\n        root: process.cwd()\n      })\n    } catch (e) {\n      //\n    }\n    return template\n  }\n}\n","import path from \"node:path\"\nimport os from \"node:os\"\n\n// sourcecode from vite\n// export const isWindows = os.platform() === 'win32'\nexport function slash(p: string): string {\n  return p.replace(/\\\\/g, '/')\n}\n\nexport function normalizePath(id: string): string {\n  return path.posix.normalize(os.platform() === 'win32' ? slash(id) : id)\n}\n\n// end\n","import type { Connect, Plugin, ViteDevServer } from 'vite'\nimport history from 'connect-history-api-fallback'\nimport type { HistoryApiOptions, HistoryRewrites } from './types'\n\n// noinspection JSUnusedGlobalSymbols\nexport const historyApiFallbackPlugin = (historyApiOptions: HistoryApiOptions): Plugin => {\n  const {\n    rewrites,\n    usePreview\n  } = historyApiOptions\n  const configureServerHookName = usePreview ? 'configurePreviewServer' : 'configureServer'\n  return {\n    name: 'vite-plugin-virtual-html:history',\n    [configureServerHookName](server: ViteDevServer) {\n      if (rewrites) {\n        buildHistoryApiFallback(server, rewrites)\n      }\n    },\n  }\n}\n\n/**\n * build a server\n * @param server\n * @param rewrites\n */\nexport function buildHistoryApiFallback(server: ViteDevServer, rewrites: Array<HistoryRewrites>) {\n  server.middlewares.use(history({\n    disableDotRule: undefined,\n    htmlAcceptHeaders: [\n      'text/html',\n      'application/xhtml+xml'\n    ],\n    rewrites: rewrites,\n  }) as Connect.NextHandleFunction)\n}\n","import type { HtmlPluginOptions, UrlTransformerFunction } from './types'\nimport { Base } from './Base'\nimport { buildHistoryApiFallback } from '../history-api/historyApiFallbackPlugin'\nimport type { ViteDevServer } from 'vite'\nimport type { HistoryApiOptions, HistoryRewrites } from '../history-api/types'\nimport { normalizePath } from './utils'\n\nexport class Serve extends Base {\n  _rewrites?: Array<HistoryRewrites>\n  \n  _urlTransformer?: UrlTransformerFunction\n  \n  constructor(virtualHtmlOptions: HtmlPluginOptions & HistoryApiOptions) {\n    super(virtualHtmlOptions)\n    this._rewrites = virtualHtmlOptions.rewrites\n    this._urlTransformer = virtualHtmlOptions.urlTransformer\n  }\n  \n  _configureServer = (server: ViteDevServer) => {\n    if (this._rewrites) {\n      buildHistoryApiFallback(server, this._rewrites)\n    }\n    // other html handled after vite's inner middlewares.\n    return () => {\n      server.middlewares.use('/', async (req, res, next) => {\n        const originalUrl = req.originalUrl\n        const reqUrl = req.url\n        let url = decodeURI(this.generateUrl(originalUrl?.endsWith('/') ? originalUrl : reqUrl))\n        if (this._urlTransformer) {\n          url = this._urlTransformer(url, req)\n        }\n        // if request is not html , directly return next()\n        if ((!url.endsWith('.html') && !url.endsWith('/')) && url !== '/') {\n          return next()\n        }\n        // request / means client requests an index page\n        // load it with indexPage config\n        let htmlCode: string\n        if (url === '/' || url === '/index.html') {\n          url = `/${this._indexPage}.html`\n        }\n        // load specify html file code\n        htmlCode = await this._load(normalizePath(url)) ?? ''\n        const transformResult = await this._transform(htmlCode, url)\n        if (transformResult === null) {\n          return next()\n        }\n        res.end(await server.transformIndexHtml(url, transformResult))\n        next()\n      })\n    }\n  }\n}\n","import type {HtmlPluginOptions} from \"./types\"\nimport {VirtualHtmlPage, VirtualPageOptions} from \"./types\"\nimport type {UserConfig} from 'vite'\nimport {Base} from \"./Base\"\nimport fs, {promises as fsp} from \"fs\"\nimport path from \"path\"\nimport {normalizePath} from \"./utils\"\n\nexport class Build extends Base {\n\n  _needRemove: Array<string> = []\n  _distDir!: string\n\n  constructor(virtualHtmlOptions: HtmlPluginOptions) {\n    super(virtualHtmlOptions)\n  }\n\n  /**\n   * check html file's parent directory\n   * @param html\n   * @param needRemove\n   */\n  async checkVirtualPath(html: string, needRemove: Array<string>, root: string) {\n    const cwd = normalizePath(path.resolve(this.cwd, root))\n    const pathArr = html.split('/')\n    const fileName = pathArr[pathArr.length - 1]\n    const middlePath = html.replace(fileName, '').replace(cwd, '')\n    const firstPath = middlePath.split('/')[1]\n    if (!fs.existsSync(middlePath)) {\n      needRemove.push(normalizePath(path.resolve(cwd, `./${firstPath}`)))\n      await fsp.mkdir(path.resolve(cwd, `./${middlePath}`), {\n        recursive: true\n      })\n    }\n  }\n\n  async _buildConfig(config: UserConfig,) {\n    this._config = config\n    const pagesKey = Object.keys(this._pages)\n    for (let i = 0; i < pagesKey.length; i++) {\n      const key = pagesKey[i]\n      const pageOption = this._pages[key]\n      const vHtml = normalizePath(path.resolve(this.cwd, `./${config.root ? this.addTrailingSlash(config.root) : ''}${this.htmlNameAddIndex(key)}.html`))\n      if (!fs.existsSync(vHtml)) {\n        this._needRemove.push(vHtml)\n        await this.checkVirtualPath(vHtml, this._needRemove, config.root??'')\n        if (typeof pageOption === 'string' || 'template' in pageOption) {\n          const genPageOption = await this.generatePageOptions(pageOption, this._globalData, this._globalRender)\n          await fsp.copyFile(path.resolve(this.cwd, `.${genPageOption.template}`), vHtml)\n        }\n        if (typeof pageOption !== 'string' && 'entry' in pageOption) {\n          await fsp.writeFile(path.resolve(this.cwd, vHtml), await this.generateVirtualPage(pageOption))\n        }\n      }\n    }\n    this.logger('[vite-plugin-virtual-html]: This plugin cannot use in library mode!')\n    // get custom distDir config,if it is undefined use default config 'dist'\n    this._distDir = config.build?.outDir ?? 'dist'\n    // inject build.rollupOptions.input from pages directly.\n    config.build = {\n      ...config.build,\n      rollupOptions: {\n        ...config.build?.rollupOptions,\n        input: {\n          ...(config.build?.rollupOptions?.input as object),\n          ...this.extractHtmlPath(this._pages),\n        },\n      },\n    }\n  }\n\n  _closeBundle() {\n    // remove files should not be under project root\n    for (let vHtml of this._needRemove) {\n      if (fs.existsSync(vHtml)) {\n        fsp.rm(vHtml, {\n          recursive: true,\n        }).catch(() => {\n          // ignore this warning\n        })\n      }\n    }\n  }\n\n  /**\n   * use pages' key as html name\n   * @param pages\n   */\n  extractHtmlPath(pages: { [p: string]: VirtualHtmlPage | VirtualPageOptions }) {\n    const newPages: { [key: string]: string } = {}\n    Object.keys(pages).forEach(key => {\n      newPages[key] = `/${this.htmlNameAddIndex(key)}.html`\n    })\n    return newPages\n  }\n\n  htmlNameAddIndex(htmlName: string): string{\n    return htmlName.endsWith('/') ? htmlName + 'index' : htmlName\n  }\n\n}\n","import {HtmlPluginOptions} from \"./types\"\nimport { ConfigEnv, Plugin, ResolvedConfig, UserConfig, ViteDevServer } from 'vite'\nimport {HistoryApiOptions} from \"../history-api/types\"\nimport { Serve } from './Serve'\nimport { Build } from './Build'\n\nexport default class VirtualHtmlPlugin implements Plugin {\n  name = 'vite-plugin-virtual-html'\n\n  _htmlOptions: HtmlPluginOptions\n\n  _config!: UserConfig\n\n  load?: OmitThisParameter<(id: string) => Promise<string | null>>\n\n  configureServer?: OmitThisParameter<(server: ViteDevServer) => () => void>\n\n  transform?: OmitThisParameter<(code: string, id: string) => Promise<string | null>>\n\n  closeBundle?: OmitThisParameter<() => void>\n\n  constructor(virtualHtmlOptions: HtmlPluginOptions & HistoryApiOptions) {\n    this._htmlOptions = virtualHtmlOptions\n    this.config = this.config.bind(this)\n  }\n\n  async config(config: UserConfig, {command}: ConfigEnv) {\n    config.appType = 'custom'\n    this._config = config\n    if (command === 'serve') {\n      const serve = new Serve(this._htmlOptions)\n      this.configureServer = serve._configureServer.bind(serve)\n      this.load = serve._load.bind(serve)\n      this.transform = serve._transform.bind(serve)\n    } else if (command === 'build') {\n      const build = new Build(this._htmlOptions)\n      await build._buildConfig.call(build, config)\n      this.load = build._load.bind(build)\n      this.transform = build._transform.bind(build)\n      this.closeBundle = build._closeBundle.bind(build)\n    }\n  }\n}\n"]}