mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
d76e0f94e9
* 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
45 lines
1.8 KiB
TypeScript
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);
|
|
}
|