import React from 'react' import type { Explain } from '../../core/explain' import type { IamPrimitives } from '../../core/types' import { Spinner } from '../components/icons' import { JsonTree } from '../components/json-tree' import { DetailEmpty, Section, SplitView } from '../components/layout' import { Alert, Badge, Button, Field, Input, TextArea } from '../components/ui' import { safeParseJson } from '../lib/format' import type { IamIDecisionInput, IamIDevtoolsEngine } from '../lib/types' import { IamTraceTree } from './trace-tree' const INITIAL: IamIDecisionInput = { subjectId: '', action: '', resourceType: '', resourceId: '', attributesJson: '{}', environmentJson: '{}', scope: '', } export function IamDecisionInspector({ engine, defaults, }: { engine: IamIDevtoolsEngine defaults?: Partial }) { const [input, setInput] = React.useState({ ...INITIAL, ...defaults }) const [result, setResult] = React.useState(null) const [error, setError] = React.useState(null) const [pending, setPending] = React.useState(false) const update = (patch: Partial) => setInput((s) => ({ ...s, ...patch })) async function run() { setError(null) setPending(true) try { const attrs = safeParseJson>(input.attributesJson, {}) const env = safeParseJson>(input.environmentJson, {}) if (attrs.error) throw new Error(`attributes JSON: ${attrs.error}`) if (env.error) throw new Error(`environment JSON: ${env.error}`) const resource = { type: input.resourceType, id: input.resourceId || undefined, attributes: attrs.value } const environment = { ...env.value, ...(input.scope ? { scope: input.scope } : {}) } const trace = await engine.explain(input.subjectId, input.action, resource, environment) setResult(trace) } catch (err) { setError(err instanceof Error ? err.message : String(err)) } finally { setPending(false) } } return (

Request

update({ subjectId: e.target.value })} placeholder="user-1" value={input.subjectId} />
update({ action: e.target.value })} placeholder="read" value={input.action} /> update({ scope: e.target.value })} placeholder="org-acme" value={input.scope} />
update({ resourceType: e.target.value })} placeholder="post" value={input.resourceType} /> update({ resourceId: e.target.value })} placeholder="p-1" value={input.resourceId} />