{"version":3,"file":"index.mjs","names":["optimizeSvg","minifyCss","minifyJs"],"sources":["../src/index.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { minify as minifyCss } from \"csso\";\nimport * as esbuild from \"esbuild\";\nimport * as sass from \"sass\";\nimport { optimize as optimizeSvg } from \"svgo\";\nimport { minify as minifyJs } from \"terser\";\nimport {\n\ttype ConfigEnv,\n\ttype IndexHtmlTransformContext,\n\tloadEnv,\n\ttype Plugin,\n\ttype ResolvedConfig,\n} from \"vite\";\nimport { z } from \"zod\";\n\nconst { compileString: compileSass } = sass;\n\nconst escapeRegExp = (value: string): string =>\n\tvalue.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\nconst InlineSourceOptionsSchema = z.object({\n\tcustomAttribute: z\n\t\t.string()\n\t\t.default(\"inline-source\")\n\t\t.describe(\"Custom attribute to trigger inlining\"),\n\treplaceTags: z\n\t\t.array(z.string())\n\t\t.optional()\n\t\t.default([\"svg\", \"math\"])\n\t\t.describe(\n\t\t\t\"Tags that should be replaced entirely when inlining elements. The default behavior is to preserve the tags and place the content from the source file inside them.\",\n\t\t),\n\toptimizeSvgs: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.default(true)\n\t\t.describe(\"Whether or not to optimize SVGs using svgo\"),\n\tcompileSass: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.default(false)\n\t\t.describe(\"Whether or not to compile SASS using sass\"),\n\toptimizeCss: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.default(false)\n\t\t.default(false)\n\t\t.describe(\"Whether or not to optimize CSS using csso\"),\n\tcompileTs: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.default(false)\n\t\t.default(true)\n\t\t.describe(\n\t\t\t\"Whether or not to transform TypeScript to JavaScript using esbuild\",\n\t\t),\n\toptimizeJs: z\n\t\t.boolean()\n\t\t.optional()\n\t\t.default(false)\n\t\t.default(false)\n\t\t.describe(\"Whether or not to optimize JS using terser\"),\n\tsvgoOptions: z.looseObject({}).optional().default({}),\n\tsassOptions: z.looseObject({}).optional().default({}),\n\tcssoOptions: z.looseObject({}).optional().default({}),\n\tterserOptions: z.looseObject({}).optional().default({}),\n});\n\ntype InlineSourceOptions = z.input<typeof InlineSourceOptionsSchema>;\ntype LoadContext = {\n\tload: (options: {\n\t\tid: string;\n\t}) => Promise<{ code?: string } | null | undefined>;\n};\n\nconst PATTERN =\n\t/<([A-z0-9-]+)\\s+([^>]*?)src\\s*=\\s*\"([^>]*?)\"([^>]*?)\\s*((\\/>)|(>\\s*<\\/\\s*\\1\\s*>))/gi;\n\nexport default function VitePluginInlineSource(\n\topts?: InlineSourceOptions,\n): Plugin {\n\tconst options = InlineSourceOptionsSchema.parse(opts ?? {});\n\tconst escapedAttribute = escapeRegExp(options.customAttribute);\n\tconst customAttributePattern = new RegExp(`\\\\b${escapedAttribute}\\\\b`);\n\tconst customAttributeGlobalPattern = new RegExp(escapedAttribute, \"g\");\n\tconst stripCustomAttribute = (segment: string) =>\n\t\tsegment.replace(customAttributeGlobalPattern, \"\");\n\tlet root = \"\";\n\n\tasync function transformHtml(\n\t\tsource: string,\n\t\tctx: LoadContext | IndexHtmlTransformContext,\n\t) {\n\t\tconst result = [];\n\t\tconst tokens = source.matchAll(PATTERN);\n\t\tlet prevPos = 0;\n\t\tfor (const token of tokens) {\n\t\t\tconst [matched, tagName, preAttributes, fileName, postAttributes] = token;\n\t\t\tconst { index } = token;\n\t\t\tconst isSvgFile = path.extname(fileName).toLowerCase() === \".svg\";\n\t\t\tconst isSassFile = path.extname(fileName).toLowerCase() === \".scss\";\n\t\t\tconst isCssFile = path.extname(fileName).toLowerCase() === \".css\";\n\t\t\tconst isJsFile = path.extname(fileName).toLowerCase() === \".js\";\n\t\t\tconst isTsFile = path.extname(fileName).toLowerCase() === \".ts\";\n\t\t\tconst isImg = tagName.toLowerCase() === \"img\";\n\t\t\tconst shouldInline = customAttributePattern.test(\n\t\t\t\t`${preAttributes} ${postAttributes}`,\n\t\t\t);\n\n\t\t\tif ((isImg && !isSvgFile) || !shouldInline) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst filePath = root ? path.join(root, fileName) : fileName;\n\n\t\t\tlet fileContent: string;\n\t\t\tif ((ctx as IndexHtmlTransformContext).server) {\n\t\t\t\tfileContent = (await readFile(`${filePath}`)).toString();\n\t\t\t} else if (\"load\" in ctx) {\n\t\t\t\tconst loaded = await ctx.load({ id: `${filePath}?raw` });\n\t\t\t\tconst rawCode = loaded?.code?.trim();\n\t\t\t\tconst rawValue = rawCode?.match(/^export default (.*);?$/s)?.[1];\n\t\t\t\tif (!rawValue) {\n\t\t\t\t\tthrow new Error(`Failed to load inline source: ${fileName}`);\n\t\t\t\t}\n\t\t\t\tfileContent = JSON.parse(rawValue.replace(/;$/, \"\"));\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Failed to load inline source: ${fileName}`);\n\t\t\t}\n\t\t\tif (isSvgFile && options.optimizeSvgs) {\n\t\t\t\tfileContent = optimizeSvg(fileContent, options.svgoOptions).data;\n\t\t\t} else if (isCssFile && options.optimizeCss) {\n\t\t\t\tconst minifiedCode = minifyCss(fileContent, options.cssoOptions).css;\n\t\t\t\tif (minifiedCode.length === 0 && fileContent.length !== 0) {\n\t\t\t\t\tthrow new Error(\"Failed to minify CSS\");\n\t\t\t\t}\n\t\t\t\tfileContent = minifiedCode;\n\t\t\t} else if (isSassFile && options.compileSass) {\n\t\t\t\tconst { css } = compileSass(fileContent, options.sassOptions);\n\t\t\t\tfileContent = options.optimizeCss\n\t\t\t\t\t? minifyCss(css, options.cssoOptions).css\n\t\t\t\t\t: css;\n\t\t\t} else if (isJsFile && options.optimizeJs) {\n\t\t\t\tconst minifiedCode = (\n\t\t\t\t\tawait minifyJs(fileContent, options.terserOptions)\n\t\t\t\t).code;\n\t\t\t\tif (minifiedCode) {\n\t\t\t\t\tfileContent = minifiedCode;\n\t\t\t\t}\n\t\t\t} else if (isTsFile && options.compileTs) {\n\t\t\t\ttry {\n\t\t\t\t\tconst envVars = loadEnv(env.mode, process.cwd());\n\t\t\t\t\tconst envVarDefines = Object.entries(envVars).reduce<\n\t\t\t\t\t\tRecord<string, string>\n\t\t\t\t\t>((prev, [key, value]) => {\n\t\t\t\t\t\tif (key.startsWith(\"VITE\")) {\n\t\t\t\t\t\t\tprev[`import.meta.env.${key}`] = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn prev;\n\t\t\t\t\t}, {});\n\n\t\t\t\t\tconst transformResult = await esbuild.transform(fileContent, {\n\t\t\t\t\t\tloader: \"ts\",\n\t\t\t\t\t\tdefine: {\n\t\t\t\t\t\t\t\"import.meta.env.MODE\": `\"${env.mode}\"`,\n\t\t\t\t\t\t\t\"import.meta.env.BASE_URL\": `\"${config.base ?? \"/\"}\"`,\n\t\t\t\t\t\t\t\"import.meta.env.PROD\": `${process.env.NODE_ENV == \"production\"}`,\n\t\t\t\t\t\t\t\"import.meta.env.DEV\": `${process.env.NODE_ENV != \"production\"}`,\n\t\t\t\t\t\t\t\"import.meta.env.SSR\": `${env.isSsrBuild}`,\n\t\t\t\t\t\t\t...envVarDefines,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tfileContent = transformResult.code;\n\n\t\t\t\t\tif (options.optimizeJs) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst minifiedResult = await minifyJs(\n\t\t\t\t\t\t\t\tfileContent,\n\t\t\t\t\t\t\t\toptions.terserOptions,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (minifiedResult.code) {\n\t\t\t\t\t\t\t\tfileContent = minifiedResult.code;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// If minification returns empty/undefined, keep the original compiled code\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tconsole.warn(\"Failed to minify compiled TypeScript:\", error);\n\t\t\t\t\t\t\t// Keep the original compiled code if minification fails\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"Failed to compile TypeScript:\", error);\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfileContent = fileContent.replace(/^<!DOCTYPE(.*?[^?])?>/, \"\");\n\n\t\t\tif (index !== prevPos) {\n\t\t\t\tresult.push(source.slice(prevPos, index));\n\t\t\t}\n\t\t\tconst cleanedPreAttributes = stripCustomAttribute(preAttributes);\n\t\t\tconst cleanedPostAttributes = stripCustomAttribute(postAttributes);\n\t\t\tif (options.replaceTags.includes(tagName)) {\n\t\t\t\tresult.push(\n\t\t\t\t\tfileContent.replace(\n\t\t\t\t\t\tnew RegExp(`^<\\\\s*${tagName}`),\n\t\t\t\t\t\t`<${tagName} ${cleanedPreAttributes} ${cleanedPostAttributes}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tresult.push(\n\t\t\t\t\t`<${tagName}\n            ${cleanedPreAttributes} ${cleanedPostAttributes}\n          >${fileContent}</${tagName}>`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tprevPos = index! + matched.length;\n\t\t}\n\t\tresult.push(source.slice(prevPos));\n\t\treturn result.join(\"\");\n\t}\n\n\tlet env: ConfigEnv;\n\tlet config: ResolvedConfig;\n\n\treturn {\n\t\tname: \"vite-plugin-inline-source\",\n\t\tconfigResolved(_config) {\n\t\t\troot = _config.root ?? \"\";\n\t\t\tconfig = _config;\n\t\t},\n\t\tconfig(_, e) {\n\t\t\tenv = e;\n\t\t},\n\t\ttransform(source, id) {\n\t\t\tif (id && !id.endsWith(\".html\")) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\treturn transformHtml(source, this as LoadContext);\n\t\t},\n\t\ttransformIndexHtml(source, ctx) {\n\t\t\treturn transformHtml(source, ctx);\n\t\t},\n\t};\n}\n"],"mappings":"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"}