Files
callstack__agent-device/scripts/layering/cutover-policy-ast.ts
Michał Pierzchała d76e0f94e9 refactor: migrate snapshot to device runtime (#1779)
* refactor: migrate snapshot to device runtime

* refactor: complete snapshot runtime policy cutover

* test: enforce snapshot owner-facts admission

* refactor: consolidate desktop snapshot capture

* fix: scroll to visible iOS smoke targets

* fix: close snapshot cutover alias bypasses

* fix: constrain snapshot admission identity flow

* fix: enforce snapshot admission through owner facts

* fix: adapt replay source tests to snapshot runtime
2026-08-18 15:49:24 +02:00

45 lines
1.8 KiB
TypeScript

/** A production file the cutover policies scan: repo-relative path plus its source. */
export type ProductionSource = Readonly<{ path: string; source: string }>;
export function memberName(node: Record<string, unknown>): string | undefined {
const property = node.property as Record<string, unknown> | undefined;
if (!property) return undefined;
return node.computed === true
? propertyName(property)
: property.type === 'Identifier'
? String(property.name)
: undefined;
}
export function propertyName(node: unknown): string | undefined {
if (node === null || typeof node !== 'object') return undefined;
const value = node as Record<string, unknown>;
return value.type === 'Identifier' || value.type === 'Literal'
? ((value.name as string | undefined) ?? (value.value as string | undefined))
: undefined;
}
export function memberPath(node: unknown): string[] | undefined {
if (node === null || typeof node !== 'object') return undefined;
const record = node as Record<string, unknown>;
if (record.type === 'Identifier') {
return typeof record.name === 'string' ? [record.name] : undefined;
}
if (record.type === 'ChainExpression') return memberPath(record.expression);
if (record.type !== 'MemberExpression' || record.computed === true) return undefined;
const object = memberPath(record.object);
const name = propertyName(record.property);
return object && name ? [...object, name] : undefined;
}
export function visitAst(node: unknown, visitor: (node: Record<string, unknown>) => void): void {
if (node === null || typeof node !== 'object') return;
if (Array.isArray(node)) {
for (const child of node) visitAst(child, visitor);
return;
}
const record = node as Record<string, unknown>;
visitor(record);
for (const child of Object.values(record)) visitAst(child, visitor);
}