mirror of
https://github.com/yaklang/yaklang-chrome-extension.git
synced 2026-09-22 19:21:53 +08:00
74 lines
2.9 KiB
TypeScript
74 lines
2.9 KiB
TypeScript
import type {
|
|
ActiveTabInfo,
|
|
BrowserPageCallable,
|
|
BrowserProfileInferenceCandidate,
|
|
BrowserRecordingEvent,
|
|
BrowserTransformDirection,
|
|
BrowserTransformProfileInput,
|
|
} from '@/types/models';
|
|
import { compileGuidedTransform, defaultGuidedTransform, type GuidedTransformOutputKind } from './guided';
|
|
|
|
interface RequestRouteSource {
|
|
url?: string;
|
|
method?: string;
|
|
}
|
|
|
|
function originOf(url?: string): string {
|
|
try { return url ? new URL(url).origin : ''; } catch { return ''; }
|
|
}
|
|
|
|
function routeOf(event?: RequestRouteSource, tab?: ActiveTabInfo): string {
|
|
const value = event?.url || tab?.url;
|
|
try { return value ? `*${new URL(value, tab?.url).pathname}` : '*'; } catch { return '*'; }
|
|
}
|
|
|
|
function emptyDirection(enabled = false): BrowserTransformDirection {
|
|
return { enabled, nodes: [] };
|
|
}
|
|
|
|
function candidateGuidance(candidate?: BrowserProfileInferenceCandidate): {
|
|
inputPaths?: string[];
|
|
outputKind?: GuidedTransformOutputKind;
|
|
outputField?: string;
|
|
} {
|
|
const destination = candidate?.request.destination;
|
|
const serialization = candidate?.request.serialization;
|
|
if (!destination) return {};
|
|
if (candidate?.direction === 'response') {
|
|
return { inputPaths: [destination], outputKind: 'body' };
|
|
}
|
|
if (serialization === 'form-field') return { outputKind: 'form-field', outputField: destination.slice(5) };
|
|
if (serialization === 'json-field') return { outputKind: 'json-field', outputField: destination.slice(5) };
|
|
if (serialization === 'header') return { outputKind: 'header', outputField: destination.slice(7) };
|
|
if (serialization === 'query') return { outputKind: 'query', outputField: destination.slice(6) };
|
|
return { outputKind: 'body' };
|
|
}
|
|
|
|
export function createBrowserTransformProfileInput(
|
|
tab: ActiveTabInfo,
|
|
event?: BrowserRecordingEvent,
|
|
callable?: BrowserPageCallable,
|
|
candidate?: BrowserProfileInferenceCandidate,
|
|
): BrowserTransformProfileInput {
|
|
const guide = defaultGuidedTransform(callable, candidateGuidance(candidate));
|
|
const compiled = callable ? compileGuidedTransform(guide, callable) : emptyDirection(true);
|
|
const responseDirection = candidate?.direction === 'response';
|
|
const routeEvent = candidate ? {
|
|
url: candidate.request.url,
|
|
method: candidate.request.method,
|
|
} : event;
|
|
return {
|
|
name: routeEvent?.url
|
|
? `${routeEvent.method || 'HTTP'} ${routeOf(routeEvent, tab)} ${responseDirection ? '响应' : '请求'}明文网关`
|
|
: `${tab.title || '当前页面'} 明文网关`,
|
|
enabled: true,
|
|
target: { tabId: tab.id, frameId: 0 },
|
|
origin: originOf(tab.url),
|
|
match: { methods: routeEvent?.method ? [routeEvent.method.toUpperCase()] : ['POST'], urlPattern: routeOf(routeEvent, tab) },
|
|
request: responseDirection ? emptyDirection(false) : compiled,
|
|
response: responseDirection ? compiled : emptyDirection(false),
|
|
failMode: 'closed',
|
|
maxConcurrency: callable?.kind === 'request-transaction' ? 1 : 2,
|
|
};
|
|
}
|