tftsr-devops_investigation/node_modules/stringify-entities/lib/util/format-smart.js
Shaun Arman 8839075805 feat: initial implementation of TFTSR IT Triage & RCA application
Implements Phases 1-8 of the TFTSR implementation plan.

Rust backend (Tauri 2.x, src-tauri/):
- Multi-provider AI: OpenAI-compatible, Anthropic, Gemini, Mistral, Ollama
- PII detection engine: 11 regex patterns with overlap resolution
- SQLCipher AES-256 encrypted database with 10 versioned migrations
- 28 Tauri IPC commands for triage, analysis, document, and system ops
- Ollama: hardware probe, model recommendations, pull/delete with events
- RCA and blameless post-mortem Markdown document generators
- PDF export via printpdf
- Audit log: SHA-256 hash of every external data send
- Integration stubs for Confluence, ServiceNow, Azure DevOps (v0.2)

Frontend (React 18 + TypeScript + Vite, src/):
- 9 pages: full triage workflow NewIssue→LogUpload→Triage→Resolution→RCA→Postmortem→History+Settings
- 7 components: ChatWindow, TriageProgress, PiiDiffViewer, DocEditor, HardwareReport, ModelSelector, UI primitives
- 3 Zustand stores: session, settings (persisted), history
- Type-safe tauriCommands.ts matching Rust backend types exactly
- 8 IT domain system prompts (Linux, Windows, Network, K8s, DB, Virt, HW, Obs)

DevOps:
- .woodpecker/test.yml: rustfmt, clippy, cargo test, tsc, vitest on every push
- .woodpecker/release.yml: linux/amd64 + linux/arm64 builds, Gogs release upload

Verified:
- cargo check: zero errors
- tsc --noEmit: zero errors
- vitest run: 13/13 unit tests passing

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 22:36:25 -05:00

70 lines
2.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @typedef FormatSmartOptions
* @property {boolean} [useNamedReferences=false]
* Prefer named character references (`&amp;`) where possible.
* @property {boolean} [useShortestReferences=false]
* Prefer the shortest possible reference, if that results in less bytes.
* **Note**: `useNamedReferences` can be omitted when using `useShortestReferences`.
* @property {boolean} [omitOptionalSemicolons=false]
* Whether to omit semicolons when possible.
* **Note**: This creates what HTML calls “parse errors” but is otherwise still valid HTML — dont use this except when building a minifier.
* Omitting semicolons is possible for certain named and numeric references in some cases.
* @property {boolean} [attribute=false]
* Create character references which dont fail in attributes.
* **Note**: `attribute` only applies when operating dangerously with
* `omitOptionalSemicolons: true`.
*/
import {toHexadecimal} from './to-hexadecimal.js'
import {toDecimal} from './to-decimal.js'
import {toNamed} from './to-named.js'
/**
* Configurable ways to encode a character yielding pretty or small results.
*
* @param {number} code
* @param {number} next
* @param {FormatSmartOptions} options
* @returns {string}
*/
export function formatSmart(code, next, options) {
let numeric = toHexadecimal(code, next, options.omitOptionalSemicolons)
/** @type {string|undefined} */
let named
if (options.useNamedReferences || options.useShortestReferences) {
named = toNamed(
code,
next,
options.omitOptionalSemicolons,
options.attribute
)
}
// Use the shortest numeric reference when requested.
// A simple algorithm would use decimal for all code points under 100, as
// those are shorter than hexadecimal:
//
// * `&#99;` vs `&#x63;` (decimal shorter)
// * `&#100;` vs `&#x64;` (equal)
//
// However, because we take `next` into consideration when `omit` is used,
// And it would be possible that decimals are shorter on bigger values as
// well if `next` is hexadecimal but not decimal, we instead compare both.
if (
(options.useShortestReferences || !named) &&
options.useShortestReferences
) {
const decimal = toDecimal(code, next, options.omitOptionalSemicolons)
if (decimal.length < numeric.length) {
numeric = decimal
}
}
return named &&
(!options.useShortestReferences || named.length < numeric.length)
? named
: numeric
}