@stacksjs/sanitizer 0.2.10 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -3,10 +3,10 @@
3
3
  "sources": ["../src/presets.ts", "../src/sanitizer.ts", "../src/index.ts"],
4
4
  "sourcesContent": [
5
5
  "import type { SanitizerOptions } from './types'\n\n/**\n * Strict preset - Only safe, basic formatting\n */\nexport const strict: SanitizerOptions = {\n allowedTags: [\n 'p',\n 'br',\n 'strong',\n 'em',\n 'u',\n 'span',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'code',\n 'pre',\n ],\n allowedAttributes: {\n '*': ['class', 'id'],\n },\n allowedSchemes: ['http', 'https', 'mailto'],\n allowDataAttributes: false,\n allowAriaAttributes: true,\n stripTags: true,\n allowComments: false,\n}\n\n/**\n * Basic preset - Common safe HTML elements\n */\nexport const basic: SanitizerOptions = {\n allowedTags: [\n 'p',\n 'br',\n 'strong',\n 'em',\n 'u',\n 'span',\n 'div',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'a',\n 'img',\n 'code',\n 'pre',\n 'blockquote',\n 'table',\n 'thead',\n 'tbody',\n 'tr',\n 'th',\n 'td',\n ],\n allowedAttributes: {\n '*': ['class', 'id'],\n 'a': ['class', 'id', 'href', 'title', 'target', 'rel'],\n 'img': ['class', 'id', 'src', 'alt', 'title', 'width', 'height'],\n 'td': ['class', 'id', 'colspan', 'rowspan', 'align'],\n 'th': ['class', 'id', 'colspan', 'rowspan', 'align', 'scope'],\n },\n allowedSchemes: ['http', 'https', 'mailto', 'tel'],\n allowDataAttributes: false,\n allowAriaAttributes: true,\n stripTags: true,\n allowComments: false,\n}\n\n/**\n * Relaxed preset - More permissive, includes media and interactive elements\n */\nexport const relaxed: SanitizerOptions = {\n allowedTags: [\n 'p',\n 'br',\n 'strong',\n 'em',\n 'u',\n 'span',\n 'div',\n 'section',\n 'article',\n 'aside',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'dl',\n 'dt',\n 'dd',\n 'a',\n 'img',\n 'figure',\n 'figcaption',\n 'code',\n 'pre',\n 'kbd',\n 'samp',\n 'var',\n 'blockquote',\n 'q',\n 'cite',\n 'table',\n 'thead',\n 'tbody',\n 'tfoot',\n 'tr',\n 'th',\n 'td',\n 'caption',\n 'del',\n 'ins',\n 'sub',\n 'sup',\n 'abbr',\n 'address',\n 'time',\n 'hr',\n 'video',\n 'audio',\n 'source',\n 'track',\n ],\n allowedAttributes: {\n '*': ['class', 'id', 'title'],\n 'a': ['class', 'id', 'href', 'title', 'target', 'rel'],\n 'img': ['class', 'id', 'src', 'srcset', 'alt', 'title', 'width', 'height', 'loading'],\n 'video': ['class', 'id', 'src', 'width', 'height', 'controls', 'preload', 'poster'],\n 'audio': ['class', 'id', 'src', 'controls', 'preload'],\n 'source': ['src', 'type'],\n 'track': ['src', 'kind', 'srclang', 'label'],\n 'td': ['class', 'id', 'colspan', 'rowspan', 'align'],\n 'th': ['class', 'id', 'colspan', 'rowspan', 'align', 'scope'],\n 'time': ['class', 'id', 'datetime'],\n 'abbr': ['class', 'id', 'title'],\n },\n allowedSchemes: ['http', 'https', 'mailto', 'tel', 'data'],\n allowDataAttributes: true,\n allowAriaAttributes: true,\n stripTags: true,\n allowComments: false,\n}\n\n/**\n * Markdown preset - Optimized for markdown-generated HTML\n */\nexport const markdown: SanitizerOptions = {\n allowedTags: [\n 'p',\n 'br',\n 'strong',\n 'em',\n 'span',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'a',\n 'img',\n 'code',\n 'pre',\n 'blockquote',\n 'table',\n 'thead',\n 'tbody',\n 'tr',\n 'th',\n 'td',\n 'del',\n 'ins',\n 'hr',\n 'input', // For task lists\n ],\n allowedAttributes: {\n '*': ['class', 'id'],\n 'a': ['class', 'id', 'href', 'title'],\n 'img': ['class', 'id', 'src', 'alt', 'title'],\n 'code': ['class'], // For syntax highlighting\n 'td': ['align'],\n 'th': ['align', 'scope'],\n 'input': ['type', 'checked', 'disabled'], // For task lists\n },\n allowedSchemes: ['http', 'https', 'mailto'],\n allowDataAttributes: false,\n allowAriaAttributes: false,\n stripTags: true,\n allowComments: false,\n}\n\n/**\n * Get preset by name\n */\nexport function getPreset(name: string): SanitizerOptions {\n switch (name) {\n case 'strict':\n return strict\n case 'basic':\n return basic\n case 'relaxed':\n return relaxed\n case 'markdown':\n return markdown\n default:\n return basic\n }\n}\n",
6
- "import type { SanitizeResult, SanitizerOptions, SanitizerPreset } from './types'\nimport { getPreset } from './presets'\n\n/**\n * Fast, native HTML sanitizer optimized for Bun\n * Provides DOMPurify-like features with performance focus\n */\n\nconst DEFAULT_OPTIONS: SanitizerOptions = {\n allowedTags: [],\n allowedAttributes: {},\n allowedSchemes: ['http', 'https', 'mailto'],\n allowDataAttributes: false,\n allowAriaAttributes: true,\n stripTags: true,\n allowComments: false,\n}\n\n// Dangerous tags that should never be allowed\nconst DANGEROUS_TAGS = [\n 'script',\n 'iframe',\n 'object',\n 'embed',\n 'applet',\n 'base',\n 'link',\n 'meta',\n 'style',\n]\n\n// URL attributes that need validation\nconst URL_ATTRIBUTES = [\n 'href',\n 'src',\n 'action',\n 'formaction',\n 'data',\n 'poster',\n 'cite',\n 'background',\n 'longdesc',\n]\n\n// Event handler attributes (always removed)\nconst EVENT_ATTRIBUTES_REGEX = /^on\\w+/i\n\n/**\n * Sanitize HTML content\n */\nexport function sanitize(\n html: string,\n options?: SanitizerOptions | SanitizerPreset,\n): string {\n const result = sanitizeWithInfo(html, options)\n return result.html\n}\n\n/**\n * Sanitize HTML content with detailed information\n */\nexport function sanitizeWithInfo(\n html: string,\n options?: SanitizerOptions | SanitizerPreset,\n): SanitizeResult {\n // Load preset if string provided\n const opts: SanitizerOptions = typeof options === 'string'\n ? getPreset(options)\n : { ...DEFAULT_OPTIONS, ...options }\n\n const removedTags: string[] = []\n const removedAttributes: string[] = []\n\n // Use a simple regex-based parser for performance\n let result = html\n let modified = false\n\n // Remove comments if not allowed\n if (!opts.allowComments) {\n const commentRegex = /<!--[\\s\\S]*?-->/g\n if (commentRegex.test(result)) {\n result = result.replace(commentRegex, '')\n modified = true\n }\n }\n\n // Parse and sanitize tags\n // eslint-disable-next-line regexp/use-ignore-case\n const tagRegex = /<(\\/?)([a-zA-Z][\\w-]*)([^>]*)>/g\n result = result.replace(tagRegex, (match, closing, tagName, attributesStr) => {\n const lowerTag = tagName.toLowerCase()\n\n // Always remove dangerous tags\n if (DANGEROUS_TAGS.includes(lowerTag)) {\n if (!removedTags.includes(lowerTag)) {\n removedTags.push(lowerTag)\n }\n modified = true\n return opts.stripTags ? '' : escapeHtml(match)\n }\n\n // Check if tag is allowed\n const allowedTags = opts.allowedTags || []\n if (allowedTags.length > 0 && !allowedTags.includes(lowerTag)) {\n if (!removedTags.includes(lowerTag)) {\n removedTags.push(lowerTag)\n }\n modified = true\n return opts.stripTags ? '' : escapeHtml(match)\n }\n\n // For closing tags, just return as-is (already validated by opening tag)\n if (closing) {\n return match\n }\n\n // Sanitize attributes\n const sanitizedAttrs = sanitizeAttributes(\n attributesStr,\n lowerTag,\n opts,\n removedAttributes,\n )\n\n if (sanitizedAttrs !== attributesStr) {\n modified = true\n }\n\n // Transform tag if transformer provided\n if (opts.transformTag) {\n const attributes = parseAttributes(sanitizedAttrs)\n const transformed = opts.transformTag(lowerTag, attributes)\n\n if (transformed === null) {\n if (!removedTags.includes(lowerTag)) {\n removedTags.push(lowerTag)\n }\n modified = true\n return ''\n }\n\n if (transformed.tagName !== lowerTag || JSON.stringify(transformed.attributes) !== JSON.stringify(attributes)) {\n modified = true\n return buildTag(transformed.tagName, transformed.attributes)\n }\n }\n\n return `<${tagName}${sanitizedAttrs}>`\n })\n\n return {\n html: result,\n modified,\n removedTags: removedTags.length > 0 ? removedTags : undefined,\n removedAttributes: removedAttributes.length > 0 ? removedAttributes : undefined,\n }\n}\n\n/**\n * Sanitize attributes\n */\nfunction sanitizeAttributes(\n attributesStr: string,\n tagName: string,\n options: SanitizerOptions,\n removedAttributes: string[],\n): string {\n if (!attributesStr.trim()) {\n return attributesStr\n }\n\n const attributes = parseAttributes(attributesStr)\n const sanitized: Record<string, string> = {}\n\n for (const [name, value] of Object.entries(attributes)) {\n const lowerName = name.toLowerCase()\n\n // Remove event handlers\n if (EVENT_ATTRIBUTES_REGEX.test(lowerName)) {\n if (!removedAttributes.includes(lowerName)) {\n removedAttributes.push(lowerName)\n }\n continue\n }\n\n // Check if attribute is allowed\n if (!isAttributeAllowed(lowerName, tagName, options)) {\n if (!removedAttributes.includes(lowerName)) {\n removedAttributes.push(lowerName)\n }\n continue\n }\n\n // Validate URL attributes\n if (URL_ATTRIBUTES.includes(lowerName)) {\n if (!isUrlSafe(value, options)) {\n if (!removedAttributes.includes(lowerName)) {\n removedAttributes.push(lowerName)\n }\n continue\n }\n }\n\n // Sanitize style attribute\n if (lowerName === 'style' && options.allowedStyles) {\n sanitized[name] = sanitizeStyle(value, options.allowedStyles)\n }\n else {\n sanitized[name] = value\n }\n }\n\n return buildAttributes(sanitized)\n}\n\n/**\n * Check if attribute is allowed\n */\nfunction isAttributeAllowed(\n attrName: string,\n tagName: string,\n options: SanitizerOptions,\n): boolean {\n const allowedAttrs = options.allowedAttributes\n\n if (!allowedAttrs) {\n return false\n }\n\n // Check data attributes\n if (attrName.startsWith('data-')) {\n return options.allowDataAttributes || false\n }\n\n // Check aria attributes\n if (attrName.startsWith('aria-')) {\n return options.allowAriaAttributes || false\n }\n\n // Array format (global allowed attributes)\n if (Array.isArray(allowedAttrs)) {\n return allowedAttrs.includes(attrName)\n }\n\n // Object format (per-tag or global)\n if (allowedAttrs[tagName]?.includes(attrName)) {\n return true\n }\n\n // Check global attributes (*)\n if (allowedAttrs['*']?.includes(attrName)) {\n return true\n }\n\n return false\n}\n\n/**\n * Validate URL safety\n */\nfunction isUrlSafe(url: string, options: SanitizerOptions): boolean {\n // Use custom validator if provided\n if (options.urlValidator) {\n return options.urlValidator(url)\n }\n\n // Check for javascript: protocol and other dangerous schemes\n const trimmed = url.trim().toLowerCase()\n\n // Remove common whitespace/encoding tricks\n // eslint-disable-next-line no-control-regex\n const cleaned = trimmed.replace(/[\\s\\x00-\\x1F]/g, '')\n\n // Dangerous protocols\n const dangerousProtocols = ['javascript:', 'data:text/html', 'vbscript:', 'file:']\n for (const protocol of dangerousProtocols) {\n if (cleaned.startsWith(protocol)) {\n return false\n }\n }\n\n // Check allowed schemes\n if (options.allowedSchemes && options.allowedSchemes.length > 0) {\n // Relative URLs are allowed\n if (!cleaned.includes(':')) {\n return true\n }\n\n const hasAllowedScheme = options.allowedSchemes.some((scheme) => {\n return cleaned.startsWith(`${scheme}:`)\n })\n\n if (!hasAllowedScheme) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Sanitize inline styles\n */\nfunction sanitizeStyle(style: string, allowedStyles: string[]): string {\n const properties = style.split(';').filter(p => p.trim())\n const sanitized: string[] = []\n\n for (const prop of properties) {\n const colonIndex = prop.indexOf(':')\n if (colonIndex === -1)\n continue\n\n const name = prop.substring(0, colonIndex).trim().toLowerCase()\n const value = prop.substring(colonIndex + 1).trim()\n\n // Check if property is allowed\n if (allowedStyles.includes(name)) {\n // Additional validation for dangerous values\n if (!value.toLowerCase().includes('javascript:') && !value.toLowerCase().includes('expression(')) {\n sanitized.push(`${name}: ${value}`)\n }\n }\n }\n\n return sanitized.join('; ')\n}\n\n/**\n * Parse HTML attributes from string\n */\nfunction parseAttributes(attributesStr: string): Record<string, string> {\n const attributes: Record<string, string> = {}\n const attrRegex = /([\\w-]+)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+)))?/g\n\n let match\n // biome-ignore lint/suspicious/noAssignInExpressions: needed for regex matching\n // eslint-disable-next-line no-cond-assign\n while ((match = attrRegex.exec(attributesStr))) {\n const name = match[1]\n const value = match[2] || match[3] || match[4] || ''\n attributes[name] = value\n }\n\n return attributes\n}\n\n/**\n * Build attributes string from object\n */\nfunction buildAttributes(attributes: Record<string, string>): string {\n const parts: string[] = []\n\n for (const [name, value] of Object.entries(attributes)) {\n if (value === '') {\n parts.push(name)\n }\n else {\n // Escape quotes in value\n const escaped = value.replace(/\"/g, '&quot;')\n parts.push(`${name}=\"${escaped}\"`)\n }\n }\n\n return parts.length > 0 ? ` ${parts.join(' ')}` : ''\n}\n\n/**\n * Build tag string from name and attributes\n */\nfunction buildTag(tagName: string, attributes: Record<string, string>): string {\n return `<${tagName}${buildAttributes(attributes)}>`\n}\n\n/**\n * Escape HTML special characters\n */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\n/**\n * Check if HTML content is safe (quick check)\n */\nexport function isSafe(html: string, options?: SanitizerOptions | SanitizerPreset): boolean {\n const result = sanitizeWithInfo(html, options)\n return !result.modified\n}\n\n/**\n * Strip all HTML tags\n */\nexport function stripTags(html: string): string {\n return html.replace(/<[^>]*>/g, '')\n}\n\n/**\n * Escape HTML for safe display\n */\nexport function escape(text: string): string {\n return escapeHtml(text)\n}\n",
6
+ "/* eslint-disable style/max-statements-per-line */\nimport type { SanitizeResult, SanitizerOptions, SanitizerPreset } from './types'\nimport { getPreset } from './presets'\n\n/**\n * Fast, native HTML sanitizer optimized for Bun\n * Provides DOMPurify-like features with performance focus\n */\n\nconst DEFAULT_OPTIONS: SanitizerOptions = {\n allowedTags: [],\n allowedAttributes: {},\n allowedSchemes: ['http', 'https', 'mailto'],\n allowDataAttributes: false,\n allowAriaAttributes: true,\n stripTags: true,\n allowComments: false,\n}\n\n// Dangerous tags that should never be allowed\nconst DANGEROUS_TAGS = [\n 'script',\n 'iframe',\n 'object',\n 'embed',\n 'applet',\n 'base',\n 'link',\n 'meta',\n 'style',\n]\n\n// URL attributes that need validation\nconst URL_ATTRIBUTES = [\n 'href',\n 'src',\n 'action',\n 'formaction',\n 'data',\n 'poster',\n 'cite',\n 'background',\n 'longdesc',\n]\n\n// Event handler attributes (always removed)\nconst EVENT_ATTRIBUTES_REGEX = /^on\\w+/i\n\n/**\n * Sanitize HTML content\n */\nexport function sanitize(\n html: string,\n options?: SanitizerOptions | SanitizerPreset,\n): string {\n const result = sanitizeWithInfo(html, options)\n return result.html\n}\n\n/**\n * Sanitize HTML content with detailed information\n */\nexport function sanitizeWithInfo(\n html: string,\n options?: SanitizerOptions | SanitizerPreset,\n): SanitizeResult {\n // Load preset if string provided\n const opts: SanitizerOptions = typeof options === 'string'\n ? getPreset(options)\n : { ...DEFAULT_OPTIONS, ...options }\n\n const removedTags: string[] = []\n const removedAttributes: string[] = []\n\n // Use a simple regex-based parser for performance\n let result = html\n let modified = false\n\n // Remove comments if not allowed\n if (!opts.allowComments) {\n const commentRegex = /<!--[\\s\\S]*?-->/g\n if (commentRegex.test(result)) {\n result = result.replace(commentRegex, '')\n modified = true\n }\n }\n\n // Parse and sanitize tags\n // eslint-disable-next-line regexp/use-ignore-case\n const tagRegex = /<(\\/?)([a-zA-Z][\\w-]*)([^>]*)>/g\n result = result.replace(tagRegex, (match, closing, tagName, attributesStr) => {\n const lowerTag = tagName.toLowerCase()\n\n // Always remove dangerous tags\n if (DANGEROUS_TAGS.includes(lowerTag)) {\n if (!removedTags.includes(lowerTag)) {\n removedTags.push(lowerTag)\n }\n modified = true\n return opts.stripTags ? '' : escapeHtml(match)\n }\n\n // Check if tag is allowed\n const allowedTags = opts.allowedTags || []\n if (allowedTags.length > 0 && !allowedTags.includes(lowerTag)) {\n if (!removedTags.includes(lowerTag)) {\n removedTags.push(lowerTag)\n }\n modified = true\n return opts.stripTags ? '' : escapeHtml(match)\n }\n\n // For closing tags, just return as-is (already validated by opening tag)\n if (closing) {\n return match\n }\n\n // Sanitize attributes\n const sanitizedAttrs = sanitizeAttributes(\n attributesStr,\n lowerTag,\n opts,\n removedAttributes,\n )\n\n if (sanitizedAttrs !== attributesStr) {\n modified = true\n }\n\n // Transform tag if transformer provided\n if (opts.transformTag) {\n const attributes = parseAttributes(sanitizedAttrs)\n const transformed = opts.transformTag(lowerTag, attributes)\n\n if (transformed === null) {\n if (!removedTags.includes(lowerTag)) {\n removedTags.push(lowerTag)\n }\n modified = true\n return ''\n }\n\n if (transformed.tagName !== lowerTag || JSON.stringify(transformed.attributes) !== JSON.stringify(attributes)) {\n modified = true\n return buildTag(transformed.tagName, transformed.attributes)\n }\n }\n\n return `<${tagName}${sanitizedAttrs}>`\n })\n\n return {\n html: result,\n modified,\n removedTags: removedTags.length > 0 ? removedTags : undefined,\n removedAttributes: removedAttributes.length > 0 ? removedAttributes : undefined,\n }\n}\n\n/**\n * Sanitize attributes\n */\nfunction sanitizeAttributes(\n attributesStr: string,\n tagName: string,\n options: SanitizerOptions,\n removedAttributes: string[],\n): string {\n if (!attributesStr.trim()) {\n return attributesStr\n }\n\n const attributes = parseAttributes(attributesStr)\n const sanitized: Record<string, string> = {}\n\n for (const [name, value] of Object.entries(attributes)) {\n const lowerName = name.toLowerCase()\n\n // Remove event handlers\n if (EVENT_ATTRIBUTES_REGEX.test(lowerName)) {\n if (!removedAttributes.includes(lowerName)) {\n removedAttributes.push(lowerName)\n }\n continue\n }\n\n // Check if attribute is allowed\n if (!isAttributeAllowed(lowerName, tagName, options)) {\n if (!removedAttributes.includes(lowerName)) {\n removedAttributes.push(lowerName)\n }\n continue\n }\n\n // Validate URL attributes\n if (URL_ATTRIBUTES.includes(lowerName)) {\n if (!isUrlSafe(value, options)) {\n if (!removedAttributes.includes(lowerName)) {\n removedAttributes.push(lowerName)\n }\n continue\n }\n }\n\n // Sanitize style attribute\n if (lowerName === 'style' && options.allowedStyles) {\n sanitized[name] = sanitizeStyle(value, options.allowedStyles)\n }\n else {\n sanitized[name] = value\n }\n }\n\n return buildAttributes(sanitized)\n}\n\n/**\n * Check if attribute is allowed\n */\nfunction isAttributeAllowed(\n attrName: string,\n tagName: string,\n options: SanitizerOptions,\n): boolean {\n const allowedAttrs = options.allowedAttributes\n\n if (!allowedAttrs) {\n return false\n }\n\n // Check data attributes\n if (attrName.startsWith('data-')) {\n return options.allowDataAttributes || false\n }\n\n // Check aria attributes\n if (attrName.startsWith('aria-')) {\n return options.allowAriaAttributes || false\n }\n\n // Array format (global allowed attributes)\n if (Array.isArray(allowedAttrs)) {\n return allowedAttrs.includes(attrName)\n }\n\n // Object format (per-tag or global)\n if (allowedAttrs[tagName]?.includes(attrName)) {\n return true\n }\n\n // Check global attributes (*)\n if (allowedAttrs['*']?.includes(attrName)) {\n return true\n }\n\n return false\n}\n\n/**\n * Validate URL safety\n */\nfunction isUrlSafe(url: string, options: SanitizerOptions): boolean {\n // Use custom validator if provided\n if (options.urlValidator) {\n return options.urlValidator(url)\n }\n\n // Check for javascript: protocol and other dangerous schemes\n const trimmed = url.trim().toLowerCase()\n\n // Remove common whitespace/encoding tricks\n // eslint-disable-next-line no-control-regex\n const cleaned = trimmed.replace(/[\\s\\x00-\\x1F]/g, '')\n\n // Dangerous protocols\n const dangerousProtocols = ['javascript:', 'data:text/html', 'vbscript:', 'file:']\n for (const protocol of dangerousProtocols) {\n if (cleaned.startsWith(protocol)) {\n return false\n }\n }\n\n // Check allowed schemes\n if (options.allowedSchemes && options.allowedSchemes.length > 0) {\n // Relative URLs are allowed\n if (!cleaned.includes(':')) {\n return true\n }\n\n const hasAllowedScheme = options.allowedSchemes.some((scheme) => {\n return cleaned.startsWith(`${scheme}:`)\n })\n\n if (!hasAllowedScheme) {\n return false\n }\n }\n\n return true\n}\n\n/**\n * Sanitize inline styles\n */\nfunction sanitizeStyle(style: string, allowedStyles: string[]): string {\n const properties = style.split(';').filter(p => p.trim())\n const sanitized: string[] = []\n\n for (const prop of properties) {\n const colonIndex = prop.indexOf(':')\n if (colonIndex === -1)\n continue\n\n const name = prop.substring(0, colonIndex).trim().toLowerCase()\n const value = prop.substring(colonIndex + 1).trim()\n\n // Check if property is allowed\n if (allowedStyles.includes(name)) {\n // Additional validation for dangerous values\n if (!value.toLowerCase().includes('javascript:') && !value.toLowerCase().includes('expression(')) {\n sanitized.push(`${name}: ${value}`)\n }\n }\n }\n\n return sanitized.join('; ')\n}\n\n/**\n * Parse HTML attributes from string\n */\nfunction parseAttributes(attributesStr: string): Record<string, string> {\n const attributes: Record<string, string> = {}\n const attrRegex = /([\\w-]+)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\\s>]+)))?/g\n\n let match\n // biome-ignore lint/suspicious/noAssignInExpressions: needed for regex matching\n // eslint-disable-next-line no-cond-assign\n while ((match = attrRegex.exec(attributesStr))) {\n const name = match[1]\n const value = match[2] || match[3] || match[4] || ''\n attributes[name] = value\n }\n\n return attributes\n}\n\n/**\n * Build attributes string from object\n */\nfunction buildAttributes(attributes: Record<string, string>): string {\n const parts: string[] = []\n\n for (const [name, value] of Object.entries(attributes)) {\n if (value === '') {\n parts.push(name)\n }\n else {\n // Escape quotes in value\n const escaped = value.replace(/\"/g, '&quot;')\n parts.push(`${name}=\"${escaped}\"`)\n }\n }\n\n return parts.length > 0 ? ` ${parts.join(' ')}` : ''\n}\n\n/**\n * Build tag string from name and attributes\n */\nfunction buildTag(tagName: string, attributes: Record<string, string>): string {\n return `<${tagName}${buildAttributes(attributes)}>`\n}\n\n/**\n * Escape HTML special characters\n */\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n\n/**\n * Check if HTML content is safe (quick check)\n */\nexport function isSafe(html: string, options?: SanitizerOptions | SanitizerPreset): boolean {\n const result = sanitizeWithInfo(html, options)\n return !result.modified\n}\n\n/**\n * Strip all HTML tags\n */\nexport function stripTags(html: string): string {\n return html.replace(/<[^>]*>/g, '')\n}\n\n/**\n * Escape HTML for safe display\n */\nexport function escape(text: string): string {\n return escapeHtml(text)\n}\n",
7
7
  "/**\n * @stacksjs/sanitizer\n *\n * A fast, native Bun-powered HTML sanitizer with DOMPurify-like features.\n * Protection against XSS and malicious content.\n */\n\n// Default export\nimport { sanitize } from './sanitizer'\n\nexport * from './presets'\nexport { basic, getPreset, markdown, relaxed, strict } from './presets'\nexport * from './sanitizer'\n\n// Re-export for convenience\nexport { escape, isSafe, sanitize, sanitizeWithInfo, stripTags } from './sanitizer'\nexport * from './types'\n\nexport default sanitize\n"
8
8
  ],
9
- "mappings": "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",
9
+ "mappings": "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",
10
10
  "debugId": "11C850CF49E4930C64756E2164756E21",
11
11
  "names": []
12
12
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/sanitizer",
3
3
  "type": "module",
4
- "version": "0.2.10",
4
+ "version": "0.2.11",
5
5
  "description": "A fast, native Bun-powered HTML sanitizer with DOMPurify-like features. Protection against XSS and malicious content.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",