tftsr-devops_investigation/node_modules/import-meta-resolve/lib/package-json-reader.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

178 lines
4.3 KiB
JavaScript

// Manually “tree shaken” from:
// <https://github.com/nodejs/node/blob/7c3dce0/lib/internal/modules/package_json_reader.js>
// Last checked on: Apr 29, 2024.
// Removed the native dependency.
// Also: no need to cache, we do that in resolve already.
/**
* @import {ErrnoException} from './errors.js'
*
* @typedef {'commonjs' | 'module' | 'none'} PackageType
*
* @typedef PackageConfig
* @property {string} pjsonPath
* @property {boolean} exists
* @property {string | undefined} [main]
* @property {string | undefined} [name]
* @property {PackageType} type
* @property {Record<string, unknown> | undefined} [exports]
* @property {Record<string, unknown> | undefined} [imports]
*/
import fs from 'node:fs'
import path from 'node:path'
import {fileURLToPath} from 'node:url'
import {codes} from './errors.js'
const hasOwnProperty = {}.hasOwnProperty
const {ERR_INVALID_PACKAGE_CONFIG} = codes
/** @type {Map<string, PackageConfig>} */
const cache = new Map()
/**
* @param {string} jsonPath
* @param {{specifier: URL | string, base?: URL}} options
* @returns {PackageConfig}
*/
export function read(jsonPath, {base, specifier}) {
const existing = cache.get(jsonPath)
if (existing) {
return existing
}
/** @type {string | undefined} */
let string
try {
string = fs.readFileSync(path.toNamespacedPath(jsonPath), 'utf8')
} catch (error) {
const exception = /** @type {ErrnoException} */ (error)
if (exception.code !== 'ENOENT') {
throw exception
}
}
/** @type {PackageConfig} */
const result = {
exists: false,
pjsonPath: jsonPath,
main: undefined,
name: undefined,
type: 'none', // Ignore unknown types for forwards compatibility
exports: undefined,
imports: undefined
}
if (string !== undefined) {
/** @type {Record<string, unknown>} */
let parsed
try {
parsed = JSON.parse(string)
} catch (error_) {
const cause = /** @type {ErrnoException} */ (error_)
const error = new ERR_INVALID_PACKAGE_CONFIG(
jsonPath,
(base ? `"${specifier}" from ` : '') + fileURLToPath(base || specifier),
cause.message
)
error.cause = cause
throw error
}
result.exists = true
if (
hasOwnProperty.call(parsed, 'name') &&
typeof parsed.name === 'string'
) {
result.name = parsed.name
}
if (
hasOwnProperty.call(parsed, 'main') &&
typeof parsed.main === 'string'
) {
result.main = parsed.main
}
if (hasOwnProperty.call(parsed, 'exports')) {
// @ts-expect-error: assume valid.
result.exports = parsed.exports
}
if (hasOwnProperty.call(parsed, 'imports')) {
// @ts-expect-error: assume valid.
result.imports = parsed.imports
}
// Ignore unknown types for forwards compatibility
if (
hasOwnProperty.call(parsed, 'type') &&
(parsed.type === 'commonjs' || parsed.type === 'module')
) {
result.type = parsed.type
}
}
cache.set(jsonPath, result)
return result
}
/**
* @param {URL | string} resolved
* @returns {PackageConfig}
*/
export function getPackageScopeConfig(resolved) {
// Note: in Node, this is now a native module.
let packageJSONUrl = new URL('package.json', resolved)
while (true) {
const packageJSONPath = packageJSONUrl.pathname
if (packageJSONPath.endsWith('node_modules/package.json')) {
break
}
const packageConfig = read(fileURLToPath(packageJSONUrl), {
specifier: resolved
})
if (packageConfig.exists) {
return packageConfig
}
const lastPackageJSONUrl = packageJSONUrl
packageJSONUrl = new URL('../package.json', packageJSONUrl)
// Terminates at root where ../package.json equals ../../package.json
// (can't just check "/package.json" for Windows support).
if (packageJSONUrl.pathname === lastPackageJSONUrl.pathname) {
break
}
}
const packageJSONPath = fileURLToPath(packageJSONUrl)
// ^^ Note: in Node, this is now a native module.
return {
pjsonPath: packageJSONPath,
exists: false,
type: 'none'
}
}
/**
* Returns the package type for a given URL.
* @param {URL} url - The URL to get the package type for.
* @returns {PackageType}
*/
export function getPackageType(url) {
// To do @anonrig: Write a C++ function that returns only "type".
return getPackageScopeConfig(url).type
}