mirror of
https://github.com/affaan-m/ECC.git
synced 2026-10-15 04:35:29 +02:00
112 lines
3.0 KiB
JavaScript
112 lines
3.0 KiB
JavaScript
'use strict';
|
|
|
|
const REGISTERED_HOOK_MAX_STDIN_BYTES = 1024 * 1024;
|
|
const MAX_CONTEXT_TOKEN_CHARS = 256;
|
|
|
|
function decodeJsonString(raw) {
|
|
try {
|
|
return JSON.parse(`"${raw}"`);
|
|
} catch {
|
|
return '';
|
|
}
|
|
}
|
|
|
|
function createHookContextScanner() {
|
|
const context = { hookEventName: '', toolName: '', stopHookActive: null };
|
|
let depth = 0;
|
|
let inString = false;
|
|
let escaped = false;
|
|
let stringRole = '';
|
|
let stringBuffer = '';
|
|
let currentKey = '';
|
|
let state = 'root';
|
|
let primitive = '';
|
|
|
|
const commitPrimitive = () => {
|
|
if (currentKey === 'stop_hook_active') {
|
|
if (primitive === 'true') context.stopHookActive = true;
|
|
else if (primitive === 'false') context.stopHookActive = false;
|
|
}
|
|
primitive = '';
|
|
};
|
|
|
|
const push = chunk => {
|
|
for (const char of String(chunk || '')) {
|
|
if (inString) {
|
|
if (escaped) {
|
|
if (stringRole && stringBuffer.length < MAX_CONTEXT_TOKEN_CHARS) {
|
|
stringBuffer += `\\${char}`;
|
|
}
|
|
escaped = false;
|
|
continue;
|
|
}
|
|
if (char === '\\') {
|
|
escaped = true;
|
|
continue;
|
|
}
|
|
if (char === '"') {
|
|
const value = decodeJsonString(stringBuffer);
|
|
if (stringRole === 'key') {
|
|
currentKey = value;
|
|
state = 'colon';
|
|
} else if (stringRole === 'value') {
|
|
if (currentKey === 'hook_event_name') context.hookEventName = value;
|
|
else if (currentKey === 'tool_name') context.toolName = value;
|
|
state = 'afterValue';
|
|
}
|
|
inString = false;
|
|
stringRole = '';
|
|
stringBuffer = '';
|
|
continue;
|
|
}
|
|
if (stringRole && stringBuffer.length < MAX_CONTEXT_TOKEN_CHARS) stringBuffer += char;
|
|
continue;
|
|
}
|
|
|
|
if (char === '"') {
|
|
inString = true;
|
|
stringRole = depth === 1 && state === 'key'
|
|
? 'key'
|
|
: depth === 1 && state === 'value'
|
|
&& (currentKey === 'hook_event_name' || currentKey === 'tool_name')
|
|
? 'value'
|
|
: '';
|
|
stringBuffer = '';
|
|
continue;
|
|
}
|
|
if (char === '{' || char === '[') {
|
|
depth += 1;
|
|
if (depth === 1) state = 'key';
|
|
continue;
|
|
}
|
|
if (char === '}' || char === ']') {
|
|
if (depth === 1 && primitive) commitPrimitive();
|
|
depth = Math.max(0, depth - 1);
|
|
continue;
|
|
}
|
|
if (depth !== 1 || /\s/.test(char)) continue;
|
|
if (state === 'colon' && char === ':') {
|
|
state = 'value';
|
|
primitive = '';
|
|
continue;
|
|
}
|
|
if ((state === 'value' || state === 'afterValue') && char === ',') {
|
|
if (state === 'value') commitPrimitive();
|
|
currentKey = '';
|
|
state = 'key';
|
|
continue;
|
|
}
|
|
if (state === 'value' && currentKey === 'stop_hook_active' && primitive.length < 5) {
|
|
primitive += char;
|
|
}
|
|
}
|
|
};
|
|
|
|
return { context, push };
|
|
}
|
|
|
|
module.exports = {
|
|
REGISTERED_HOOK_MAX_STDIN_BYTES,
|
|
createHookContextScanner,
|
|
};
|