@scriptdb/client 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +27 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +27 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -167,7 +167,7 @@ declare class ScriptDBClient {
|
|
|
167
167
|
/**
|
|
168
168
|
* Execute code in a database
|
|
169
169
|
*/
|
|
170
|
-
run(code: string, databaseName: string): Promise<any>;
|
|
170
|
+
run(code: string | Function, databaseName: string): Promise<any>;
|
|
171
171
|
/**
|
|
172
172
|
* Save a database to disk
|
|
173
173
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -167,7 +167,7 @@ declare class ScriptDBClient {
|
|
|
167
167
|
/**
|
|
168
168
|
* Execute code in a database
|
|
169
169
|
*/
|
|
170
|
-
run(code: string, databaseName: string): Promise<any>;
|
|
170
|
+
run(code: string | Function, databaseName: string): Promise<any>;
|
|
171
171
|
/**
|
|
172
172
|
* Save a database to disk
|
|
173
173
|
*/
|
package/dist/index.js
CHANGED
|
@@ -837,7 +837,33 @@ var ScriptDBClient = class {
|
|
|
837
837
|
* Execute code in a database
|
|
838
838
|
*/
|
|
839
839
|
async run(code, databaseName) {
|
|
840
|
-
|
|
840
|
+
let stringCode;
|
|
841
|
+
if (typeof code === "function") {
|
|
842
|
+
const funcStr = code.toString();
|
|
843
|
+
const arrowMatch = funcStr.match(/^[\s]*\(?\s*\)?\s*=>\s*{?/);
|
|
844
|
+
const functionMatch = funcStr.match(/^[\s]*function\s*\(?[\w\s]*\)?\s*{/);
|
|
845
|
+
const match = arrowMatch || functionMatch;
|
|
846
|
+
const start = match ? match[0].length : 0;
|
|
847
|
+
const end = funcStr.lastIndexOf("}");
|
|
848
|
+
stringCode = funcStr.substring(start, end);
|
|
849
|
+
stringCode = stringCode.replace(/^[\s\r\n]+/, "").replace(/[\s\r\n]+$/, "");
|
|
850
|
+
stringCode = stringCode.replace(
|
|
851
|
+
/import\s*\(\s*([^)]+?)\s*\)\s*\.from\s*\(\s*(['"])([^'"]+)\2\s*\)/g,
|
|
852
|
+
(_, importArg, quote, modulePath) => {
|
|
853
|
+
const trimmed = importArg.trim();
|
|
854
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
855
|
+
const inner = trimmed.slice(1, -1).trim();
|
|
856
|
+
return `import { ${inner} } from ${quote}${modulePath}${quote}`;
|
|
857
|
+
} else {
|
|
858
|
+
return `import ${trimmed} from ${quote}${modulePath}${quote}`;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
);
|
|
862
|
+
stringCode = stringCode.split("\n").map((line) => line.trim()).join("\n").trim();
|
|
863
|
+
} else {
|
|
864
|
+
stringCode = code;
|
|
865
|
+
}
|
|
866
|
+
return this.sendRequest("script-code", { code: stringCode, databaseName });
|
|
841
867
|
}
|
|
842
868
|
/**
|
|
843
869
|
* Save a database to disk
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import * as net from \"net\";\nimport * as tls from \"tls\";\nimport { URL } from \"url\";\nimport * as crypto from \"crypto\";\n\ntype Action = 'script-code' | 'save-db' | 'remove-db' | 'rename-db' | 'login' | 'logout' | 'get-info' | 'list-dbs' | 'create-db' | 'update-db' | 'get-db' | 'shell-command' | 'string';\n\ninterface DataOptions {\n code?: string | any;\n databaseName?: string | any;\n token?: string | any;\n username?: string | any;\n password?: string | any;\n newName?: string | any;\n}\n\ninterface PayloadOptions {\n id?: number;\n action?: Action;\n data?: DataOptions;\n}\n// Type definitions\ninterface Logger {\n debug?: (...args: any[]) => void;\n info?: (...args: any[]) => void;\n warn?: (...args: any[]) => void;\n error?: (...args: any[]) => void;\n}\n\ninterface ClientOptions {\n secure?: boolean;\n logger?: Logger;\n requestTimeout?: number;\n socketTimeout?: number;\n retries?: number;\n retryDelay?: number;\n tlsOptions?: tls.TlsOptions;\n frame?: 'ndjson' | 'length-prefix';\n preferLengthPrefix?: boolean;\n maxPending?: number;\n maxQueue?: number;\n maxMessageSize?: number;\n signing?: {\n secret: string;\n algorithm?: string;\n };\n stringify?: (obj: any) => string;\n username?: string;\n password?: string;\n tokenRefresh?: () => Promise<{ token: string; expiresAt?: number }>;\n}\n\ninterface PendingRequest {\n resolve: (value: any) => void;\n reject: (error: Error) => void;\n timer: NodeJS.Timeout | null;\n}\n\ninterface QueuedRequest extends PendingRequest {\n payloadBase: PayloadOptions;\n id: number;\n}\n\ninterface Message {\n id?: number;\n action?: Action;\n command?: string;\n message?: string;\n data?: DataOptions;\n token?: string;\n signature?: string;\n payload?: any;\n}\n\n// Minimal no-op logger\nconst noopLogger = {\n debug: () => { },\n info: () => { },\n warn: () => { },\n error: () => { },\n};\n\nexport class ScriptDBClient {\n // Properties\n private options: ClientOptions;\n private socketTimeout: number = 0;\n private maxMessageSize: number = 0;\n private _mask: (obj: any) => any = () => { };\n private _maskArgs: (args: any[]) => any[] = () => [];\n private logger?: Logger = {};\n private secure: boolean = true;\n private requestTimeout: number = 0;\n private retries: number = 0;\n private retryDelay: number = 0;\n private frame: 'ndjson' | 'length-prefix' = 'ndjson';\n private uri: string = '';\n private protocolName: string = '';\n private username: string | null = null;\n private password: string | null = null;\n private host: string = '';\n private port: number = 0;\n private database: string | null = null;\n private client: net.Socket | tls.TLSSocket | null = null;\n private buffer: Buffer = Buffer.alloc(0);\n private _nextId: number = 1;\n private _pending: Map<number, PendingRequest> = new Map();\n private _maxPending: number = 0;\n private _maxQueue: number = 0;\n private _pendingQueue: QueuedRequest[] = [];\n private _connected: boolean = false;\n private _authenticating: boolean = false;\n private token: string | null = null;\n private _currentRetries: number = 0;\n private tokenExpiry: number | null = null;\n private _destroyed: boolean = false;\n private _reconnectTimer: NodeJS.Timeout | null = null;\n private signing: { secret: string; algorithm?: string } | null = null;\n private _stringify: (obj: any) => string = JSON.stringify;\n private ready: Promise<any> = Promise.resolve();\n private _resolveReadyFn: ((value: any) => void) | null = null;\n private _rejectReadyFn: ((err: Error) => void) | null = null;\n private _connecting: Promise<any> | null = null;\n private _authPendingId: number | null = null;\n\n /**\n * Create a new client. Do NOT auto-connect in constructor — call connect()\n * @param uri - Connection URI\n * @param options - Client options\n * @param options.secure - use TLS\n * @param options.logger - { debug, info, warn, error }\n * @param options.requestTimeout - Request timeout in ms\n * @param options.retries - Reconnection retries\n * @param options.retryDelay - Initial retry delay in ms\n * @param options.tlsOptions - Passed to tls.connect when secure\n */\n constructor(uri: string, options: ClientOptions = {}) {\n if (!uri || typeof uri !== \"string\") throw new Error(\"uri required\");\n this.options = Object.assign({}, options);\n // sensible default socket timeout (ms). 0 = disabled (no socket timeout)\n this.socketTimeout = Number.isFinite(this.options.socketTimeout)\n ? this.options.socketTimeout!\n : 0;\n // sensible default max message size (bytes)\n this.maxMessageSize = Number.isFinite(this.options.maxMessageSize)\n ? this.options.maxMessageSize!\n : 5 * 1024 * 1024; // 5MB\n\n // masking helper (used to hide tokens/passwords from logs)\n this._mask = (obj) => {\n try {\n if (!obj || typeof obj !== \"object\") return obj;\n const copy = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj);\n if (copy.token) copy.token = \"****\";\n if (copy.password) copy.password = \"****\";\n if (copy.data && copy.data.password) copy.data.password = \"****\";\n return copy;\n } catch (e) {\n return obj;\n }\n };\n\n // helper to mask any arguments passed to logger methods\n const rawLogger =\n this.options.logger && typeof this.options.logger === \"object\"\n ? this.options.logger\n : noopLogger;\n this._maskArgs = (args) => {\n return args.map((a) => {\n if (!a) return a;\n if (typeof a === \"string\") return a;\n return this._mask(a);\n });\n };\n\n // wrapper logger that masks sensitive fields in objects before delegating\n this.logger = {\n debug: (...args) =>\n rawLogger.debug && rawLogger.debug(...this._maskArgs(args)),\n info: (...args) =>\n rawLogger.info && rawLogger.info(...this._maskArgs(args)),\n warn: (...args) =>\n rawLogger.warn && rawLogger.warn(...this._maskArgs(args)),\n error: (...args) =>\n rawLogger.error && rawLogger.error(...this._maskArgs(args)),\n };\n // secure by default; warn if user explicitly disables secure\n this.secure =\n typeof this.options.secure === \"boolean\" ? !!this.options.secure : true;\n if (!this.secure)\n this.logger.warn?.(\n \"Warning: connecting in insecure mode (secure=false). This is not recommended.\"\n );\n // By default do not set a per-request timeout (0 = disabled).\n this.requestTimeout = Number.isFinite(this.options.requestTimeout)\n ? this.options.requestTimeout!\n : 0;\n this.retries = Number.isFinite(this.options.retries)\n ? this.options.retries!\n : 3;\n this.retryDelay = Number.isFinite(this.options.retryDelay)\n ? this.options.retryDelay!\n : 1000;\n // framing: 'ndjson' (default) or 'length-prefix'. If the caller prefers higher throughput\n // they can set options.preferLengthPrefix = true or options.frame = 'length-prefix'.\n this.frame =\n this.options.frame === \"length-prefix\" || this.options.preferLengthPrefix\n ? \"length-prefix\"\n : \"ndjson\";\n\n // Validate and parse URI - only accept scriptdb:// protocol\n let parsed;\n try {\n parsed = new URL(uri);\n } catch (e) {\n throw new Error(\"Invalid uri\");\n }\n\n // Validate protocol\n if (parsed.protocol !== \"scriptdb:\") {\n throw new Error(\"URI must use scriptdb:// protocol\");\n }\n\n this.uri = uri;\n this.protocolName = parsed.protocol\n ? parsed.protocol.replace(\":\", \"\")\n : \"scriptdb\";\n // prefer explicit credentials passed in options over credentials embedded in the URI\n this.username =\n (typeof this.options.username === \"string\"\n ? this.options.username\n : parsed.username) || null;\n this.password =\n (typeof this.options.password === \"string\"\n ? this.options.password\n : parsed.password) || null;\n if (parsed.username && !(typeof this.options.username === \"string\")) {\n this.logger.warn?.(\n \"Credentials found in URI — consider passing credentials via options instead of embedding in URI\"\n );\n }\n // do not keep credentials in the stored URI representation\n try {\n parsed.username = \"\";\n parsed.password = \"\";\n this.uri = parsed.toString();\n } catch (e) {\n // fallback to original uri\n this.uri = uri;\n }\n this.host = parsed.hostname || \"localhost\";\n this.port = parsed.port ? parseInt(parsed.port, 10) : 1234;\n this.database =\n parsed.pathname && parsed.pathname.length > 1\n ? parsed.pathname.slice(1)\n : null;\n\n // internal state\n this.client = null;\n this.buffer = Buffer.alloc(0);\n this._nextId = 1; // request id generator\n this._pending = new Map(); // id -> {resolve,reject,timer}\n this._maxPending = Number.isFinite(this.options.maxPending)\n ? this.options.maxPending!\n : 100;\n this._maxQueue = Number.isFinite(this.options.maxQueue)\n ? this.options.maxQueue!\n : 1000;\n this._pendingQueue = []; // queued requests when pending >= max\n this._connected = false;\n this._authenticating = false;\n this.token = null;\n this._currentRetries = 0;\n this.tokenExpiry = null; // ms timestamp when token expires\n this._destroyed = false;\n this._reconnectTimer = null;\n\n // signing options: { secret: '...', algorithm: 'sha256' }\n this.signing =\n this.options.signing && this.options.signing.secret\n ? this.options.signing\n : null;\n\n // fast stringify support: allow user to pass a custom stringify function (e.g. fast-json-stringify)\n this._stringify =\n typeof this.options.stringify === \"function\"\n ? this.options.stringify\n : JSON.stringify;\n\n // ready promise lifecycle managed by helpers to avoid race conditions\n this._createReady();\n }\n\n _createReady() {\n this.ready = new Promise((resolve, reject) => {\n this._resolveReadyFn = resolve;\n this._rejectReadyFn = reject;\n });\n }\n\n _resolveReady(value: any) {\n if (this._resolveReadyFn) {\n try {\n this._resolveReadyFn(value);\n } catch (e) { }\n this._resolveReadyFn = null;\n this._rejectReadyFn = null;\n }\n }\n\n _rejectReady(err: Error) {\n if (this._rejectReadyFn) {\n // Use process.nextTick to defer the rejection, preventing unhandled errors\n // when called from event handlers\n const rejectFn = this._rejectReadyFn;\n this._resolveReadyFn = null;\n this._rejectReadyFn = null;\n \n process.nextTick(() => {\n try {\n rejectFn(err);\n } catch (e) {\n // Silently ignore - promise already rejected\n }\n });\n }\n }\n\n /**\n * Check if connected\n */\n get connected(): boolean {\n return this._connected;\n }\n\n /**\n * Connect to server and authenticate. Returns a Promise that resolves when authenticated.\n */\n connect() {\n // avoid double connect\n if (this._connecting) return this._connecting;\n\n this._connecting = new Promise((resolve, reject) => {\n const opts = { host: this.host, port: this.port };\n const onConnect = () => {\n console.log(\"ScriptDBClient: Connected to server at\", opts.host, opts.port);\n this.logger?.info?.(\"Connected to server\");\n this._connected = true;\n this._currentRetries = 0;\n console.log(\"ScriptDBClient: Setting up listeners...\");\n this._setupListeners();\n console.log(\"ScriptDBClient: Authenticating...\");\n this.authenticate()\n .then(() => {\n // reset pending queue processing after auth\n this._processQueue();\n resolve(this);\n })\n .catch((err) => {\n reject(err);\n });\n };\n\n try {\n if (this.secure) {\n // Create a separate object for host and port to avoid type conflicts\n const connectionOpts = { host: opts.host, port: opts.port };\n const tlsOptions: any = Object.assign(\n {},\n this.options.tlsOptions || {},\n connectionOpts\n );\n // safe default\n if (typeof tlsOptions.rejectUnauthorized === \"undefined\")\n tlsOptions.rejectUnauthorized = true;\n this.client = tls.connect(tlsOptions as tls.ConnectionOptions, onConnect);\n } else {\n this.client = net.createConnection(opts, onConnect);\n }\n } catch (e) {\n const error = e as Error;\n this.logger?.error?.(\"Connection failed\", error.message);\n // reject ready if present and clear handlers\n this._rejectReady(error);\n // make sure ready is recreated on next attempt\n this._createReady();\n // allow future connect attempts\n this._connecting = null;\n return reject(error);\n }\n\n // Guard against client not being set (shouldn't happen, but TypeScript needs it)\n if (!this.client) {\n const error = new Error(\"Failed to create client socket\");\n this.logger?.error?.(\"Connection failed\", error.message);\n this._connecting = null;\n return reject(error);\n }\n\n // attach top-level handlers for errors/close to trigger reconnect logic\n const onError = (err: Error) => {\n this.logger?.error?.(\n \"Client socket error:\",\n err && err.message ? err.message : err\n );\n this._handleDisconnect(err);\n };\n const onClose = (hadError: boolean) => {\n this.logger?.info?.(\"Server closed connection\");\n // Don't pass error to avoid double error throwing\n this._handleDisconnect(null);\n };\n this.client.on(\"error\", onError);\n this.client.on(\"close\", onClose);\n // socket timeouts\n if (this.socketTimeout > 0 && this.client) {\n this.client.setTimeout(this.socketTimeout);\n this.client.on(\"timeout\", () => {\n this.logger?.warn?.(\"Socket timeout, destroying connection\");\n try {\n this.client?.destroy();\n } catch (e) { }\n });\n }\n }).catch((err) => {\n // Ensure errors are properly propagated without additional throwing\n this._connecting = null;\n throw err;\n });\n\n return this._connecting;\n }\n\n _setupListeners() {\n if (!this.client) return;\n console.log(\"ScriptDBClient _setupListeners: called, client exists:\", !!this.client);\n // clear any previous data listeners and reset buffer\n this.client.removeAllListeners(\"data\");\n this.buffer = Buffer.alloc(0);\n\n console.log(\"ScriptDBClient _setupListeners: frame mode:\", this.frame);\n \n // Parser depends on framing\n if (this.frame === \"length-prefix\") {\n // length-prefixed framing: [uint32BE length][payload]\n this.client.on(\"data\", (chunk) => {\n if (!Buffer.isBuffer(chunk)) {\n try {\n chunk = Buffer.from(chunk);\n } catch (e) {\n return;\n }\n }\n // fast path: append and scan (we keep concat here for simplicity)\n this.buffer = Buffer.concat([this.buffer, chunk]);\n while (this.buffer.length >= 4) {\n const len = this.buffer.readUInt32BE(0);\n // enforce max message/frame size\n if (len > this.maxMessageSize) {\n this.logger?.error?.(\n \"Incoming length-prefixed frame exceeds maxMessageSize — closing connection\"\n );\n try {\n this.client?.destroy();\n } catch (e) { }\n return;\n }\n if (this.buffer.length < 4 + len) break;\n const payload = this.buffer.slice(4, 4 + len);\n this.buffer = this.buffer.slice(4 + len);\n let msg;\n try {\n msg = JSON.parse(payload.toString(\"utf8\"));\n } catch (e) {\n this.logger?.error?.(\n \"Invalid JSON frame\",\n e && (e as Error).message ? (e as Error).message : e\n );\n continue;\n }\n // validate schema\n if (!msg || typeof msg !== \"object\") continue;\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\") &&\n (typeof msg.data === \"object\" ||\n typeof msg.data === \"undefined\" ||\n msg.data === null);\n if (!validSchema) {\n this.logger?.warn?.(\"Message failed schema validation — ignoring\");\n continue;\n }\n this._handleMessage(msg);\n }\n });\n } else {\n // Buffer-aware NDJSON parser: avoid repeated string concatenation\n console.log(\"ScriptDBClient _setupListeners: Setting up NDJSON data listener\");\n this.client.on(\"data\", (chunk) => {\n console.log(\"ScriptDBClient: Received data chunk, length:\", chunk.length);\n if (!Buffer.isBuffer(chunk)) {\n try {\n chunk = Buffer.from(chunk);\n } catch (e) {\n return;\n }\n }\n\n // If buffer is empty and chunk contains no trailing partial line, avoid concat\n const idxLastNewline = chunk.indexOf(0x0a);\n if (this.buffer.length === 0 && idxLastNewline === chunk.length - 1) {\n // chunk ends with newline and no previous partial: process in-place\n let start = 0;\n let idx;\n while ((idx = chunk.indexOf(0x0a, start)) !== -1) {\n const lineBuf = chunk.slice(start, idx);\n start = idx + 1;\n if (lineBuf.length === 0) continue;\n let msg;\n try {\n msg = JSON.parse(lineBuf.toString(\"utf8\"));\n } catch (e: any) {\n this.logger?.error?.(\n \"Invalid JSON from server\",\n e && e.message ? e.message : e\n );\n continue;\n }\n // schema check\n if (!msg || typeof msg !== \"object\") continue;\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\");\n if (!validSchema) continue;\n this._handleMessage(msg);\n }\n return;\n }\n\n // fallback: append chunk to buffer (infrequent), then scan\n this.buffer = Buffer.concat([this.buffer, chunk]);\n\n // enforce max message size\n // enforce max message size using configured value\n if (this.buffer.length > this.maxMessageSize) {\n this.logger?.error?.(\n \"Incoming message exceeds maxMessageSize — closing connection\"\n );\n try {\n this.client?.destroy();\n } catch (e) { }\n return;\n }\n\n let idx;\n while ((idx = this.buffer.indexOf(0x0a)) !== -1) {\n const lineBuf = this.buffer.slice(0, idx);\n this.buffer = this.buffer.slice(idx + 1);\n if (lineBuf.length === 0) continue;\n let msg;\n try {\n msg = JSON.parse(lineBuf.toString(\"utf8\"));\n } catch (e: any) {\n this.logger?.error?.(\n \"Invalid JSON from server\",\n e && (e as Error).message ? (e as Error).message : e\n );\n continue;\n }\n\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\");\n if (!validSchema) {\n this.logger?.warn?.(\"Message failed schema validation — ignoring\");\n continue;\n }\n\n this._handleMessage(msg);\n }\n });\n }\n }\n\n // build the final buffer for sending using current token and signing settings\n _buildFinalBuffer(payloadBase: Message, id: number) {\n // payloadBase is { action, data }\n const payloadObj: Message = Object.assign(\n { id, action: payloadBase.action },\n payloadBase.data !== undefined ? { data: payloadBase.data } : {}\n );\n // attach current token at send time\n if (this.token) payloadObj.token = this.token;\n\n const payloadStr = this._stringify(payloadObj);\n\n if (this.signing && this.signing.secret) {\n const hmac = crypto.createHmac(\n this.signing.algorithm || \"sha256\",\n this.signing.secret\n );\n hmac.update(payloadStr);\n const sig = hmac.digest(\"hex\");\n const envelope = { id, signature: sig, payload: payloadObj };\n const envelopeStr = this._stringify(envelope);\n if (this.frame === \"length-prefix\") {\n const body = Buffer.from(envelopeStr, \"utf8\");\n const buf = Buffer.allocUnsafe(4 + body.length);\n buf.writeUInt32BE(body.length, 0);\n body.copy(buf, 4);\n return buf;\n }\n return Buffer.from(envelopeStr + \"\\n\", \"utf8\");\n }\n\n // no signing\n if (this.frame === \"length-prefix\") {\n const body = Buffer.from(payloadStr, \"utf8\");\n const buf = Buffer.allocUnsafe(4 + body.length);\n buf.writeUInt32BE(body.length, 0);\n body.copy(buf, 4);\n return buf;\n }\n return Buffer.from(payloadStr + \"\\n\", \"utf8\");\n }\n\n _handleMessage(msg: Message) {\n console.log('ScriptDBClient _handleMessage:', JSON.stringify(msg));\n console.log('ScriptDBClient _handleMessage msg.id:', msg.id, 'msg.action:', msg.action, 'msg.command:', (msg as any).command, 'msg.message:', msg.message);\n \n // message with id for request/response mapping (check this FIRST)\n if (msg && typeof msg.id !== \"undefined\") {\n console.log('Handling message with id:', msg.id, 'action:', msg.action, 'message:', msg.message);\n const pending = this._pending.get(msg.id);\n if (!pending) {\n console.log('No pending request for id', msg.id, 'pending map size:', this._pending.size);\n this.logger?.debug?.(\"No pending request for id\", msg.id);\n return;\n }\n const { resolve, reject, timer } = pending;\n if (timer) clearTimeout(timer);\n this._pending.delete(msg.id);\n // process next queued request if any\n this._processQueue();\n\n // Handle login responses with id\n if (msg.action === \"login\" || msg.command === \"login\") {\n console.log('Processing login response with id');\n if (msg.message === \"AUTH OK\") {\n console.log('AUTH OK - setting token and resolving');\n this.token = msg.data && msg.data.token ? msg.data.token : null;\n this._resolveReady(null);\n return resolve(msg.data);\n } else {\n console.log('AUTH FAILED:', msg.data);\n this._rejectReady(new Error(\"Authentication failed\"));\n const errorMsg = msg.data || \"Authentication failed\";\n // Close the connection after receiving AUTH FAIL\n try {\n this.client?.end();\n } catch (e) {}\n return reject(new Error(typeof errorMsg === 'string' ? errorMsg : \"Authentication failed\"));\n }\n }\n\n if ((msg.action === \"script-code\" || msg.command === \"script-code\") && msg.message === \"OK\")\n return resolve(msg.data);\n if ((msg.action === \"script-code\" || msg.command === \"script-code\") && msg.message === \"ERROR\")\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Server returned ERROR\"));\n \n // Handle create-db responses\n if (msg.action === \"create-db\" && msg.message === \"SUCCESS\")\n return resolve(msg.data);\n if (msg.action === \"create-db\" && msg.message === \"ERROR\")\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Failed to create database\"));\n \n // Default: resolve for OK/SUCCESS, reject for ERROR\n if (msg.message === \"OK\" || msg.message === \"SUCCESS\") {\n return resolve(msg.data);\n } else if (msg.message === \"ERROR\") {\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Request failed\"));\n }\n \n return reject(new Error(\"Invalid response from server\"));\n }\n\n // otherwise, unhandled message\n console.log('Unhandled message:', msg);\n this.logger?.debug?.(\"Unhandled message from server\", this._mask(msg));\n }\n\n authenticate() {\n if (this._authenticating)\n return Promise.reject(new Error(\"Already authenticating\"));\n this._authenticating = true;\n\n return new Promise((resolve, reject) => {\n const id = this._nextId++;\n const payload:Message = {\n id,\n action: \"login\",\n data: { username: this.username, password: this.password },\n };\n\n // create a timer only when requestTimeout is enabled (>0)\n let timer: any = null;\n if (this.requestTimeout > 0) {\n timer = setTimeout(() => {\n this._pending.delete(id);\n this._authenticating = false;\n reject(new Error(\"Auth timeout\"));\n this.close();\n }, this.requestTimeout);\n }\n\n this._pending.set(id, {\n resolve: (data: any) => {\n if (timer) clearTimeout(timer);\n this._authenticating = false;\n // server may still send a login message; set token if present\n if (data && (data as any).token) this.token = (data as any).token;\n resolve(data);\n },\n reject: (err: any) => {\n if (timer) clearTimeout(timer);\n this._authenticating = false;\n reject(err);\n },\n timer,\n });\n\n try {\n // use _write to respect backpressure\n const buf = Buffer.from(JSON.stringify(payload) + \"\\n\", \"utf8\");\n this._write(buf).catch((err: any) => {\n if (timer) clearTimeout(timer);\n this._pending.delete(id);\n this._authenticating = false;\n reject(err);\n });\n } catch (e: any) {\n clearTimeout(timer);\n this._pending.delete(id);\n this._authenticating = false;\n reject(e);\n }\n })\n .then((data: any) => {\n // mark ready if token present\n if (data && (data as any).token) {\n this.token = (data as any).token;\n this._resolveReady(null);\n }\n return data;\n })\n .catch((err: any) => {\n this._rejectReady(err);\n throw err;\n });\n }\n\n // internal write helper that respects backpressure\n _write(buf: any) {\n return new Promise((resolve, reject) => {\n if (!this.client || !this._connected)\n return reject(new Error(\"Not connected\"));\n try {\n const ok = this.client.write(buf, (err) => {\n if (err) return reject(err);\n resolve(undefined);\n });\n if (!ok) {\n // wait for drain\n this.client.once(\"drain\", () => resolve(undefined));\n }\n // if ok was true, the callback above resolves\n } catch (e) {\n reject(e);\n }\n });\n }\n\n async _processQueue() {\n while (\n this._pending.size < this._maxPending &&\n this._pendingQueue.length > 0\n ) {\n const item: any = this._pendingQueue.shift();\n const { payloadBase, id, resolve, reject, timer } = item;\n // ensure token valid or attempt refresh\n if (this.tokenExpiry && Date.now() >= this.tokenExpiry) {\n const refreshed = await this._maybeRefreshToken();\n if (!refreshed) {\n clearTimeout(timer);\n try {\n reject(new Error(\"Token expired and refresh failed\"));\n } catch (e) { }\n continue;\n }\n }\n\n // build final buffer at send time so token is fresh and we don't store tokens in queue\n let buf;\n try {\n buf = this._buildFinalBuffer(payloadBase, id);\n } catch (e) {\n clearTimeout(timer);\n try {\n reject(e);\n } catch (er) { }\n continue;\n }\n\n // register pending before writing so that responses arriving quickly are handled\n this._pending.set(id, { resolve, reject, timer });\n // write with backpressure\n try {\n await this._write(buf);\n } catch (e) {\n clearTimeout(timer);\n this._pending.delete(id);\n try {\n reject(e);\n } catch (er) { }\n }\n }\n }\n\n /**\n * Execute a command. Supports concurrent requests via request id mapping.\n * Returns a Promise resolved with response.data or rejected on ERROR/timeout.\n */\n async execute(payload:Message) {\n // wait until authenticated\n try {\n await this.ready;\n } catch (err: any) {\n throw new Error(\n \"Not authenticated: \" + (err && err.message ? err.message : err)\n );\n }\n\n if (!this.token) throw new Error(\"Not authenticated\");\n\n const id = this._nextId++;\n\n // payloadBase stored in queue; final buffer will be built at send time\n const payloadBase: PayloadOptions = { action: payload.action, data: payload.data };\n\n // if token expired, try refresh before proceeding\n if (this.tokenExpiry && Date.now() >= this.tokenExpiry) {\n const refreshed = await this._maybeRefreshToken();\n if (!refreshed) throw new Error(\"Token expired\");\n }\n\n return new Promise((resolve, reject) => {\n // create request timer only if requestTimeout > 0\n let timer: any = null;\n if (this.requestTimeout > 0) {\n timer = setTimeout(() => {\n if (this._pending.has(id)) {\n this._pending.delete(id);\n reject(new Error(\"Request timeout\"));\n }\n }, this.requestTimeout);\n }\n\n // if too many pending, queue this request\n if (this._pending.size >= this._maxPending) {\n if (this._pendingQueue.length >= this._maxQueue) {\n if (timer) clearTimeout(timer);\n return reject(new Error(\"Pending queue full\"));\n }\n // enqueue payload base so we don't store tokens in the queue\n this._pendingQueue.push({ payloadBase, id, resolve, reject, timer });\n // try to process queue (async)\n this._processQueue().catch(() => { });\n return;\n }\n\n // build final buffer now using current token\n let finalBuf;\n try {\n finalBuf = this._buildFinalBuffer(payloadBase, id);\n } catch (e) {\n clearTimeout(timer);\n return reject(e);\n }\n\n this._pending.set(id, { resolve, reject, timer });\n // write with backpressure handling\n this._write(finalBuf).catch((e) => {\n if (timer) clearTimeout(timer);\n this._pending.delete(id);\n reject(e);\n });\n });\n }\n /**\n * Attempt to refresh token using provided tokenRefresh option if token expired.\n * options.tokenRefresh should be async function that returns { token, expiresAt }\n */\n async _maybeRefreshToken() {\n if (\n !this.options.tokenRefresh ||\n typeof this.options.tokenRefresh !== \"function\"\n )\n return false;\n try {\n const res = await this.options.tokenRefresh();\n if (res && res.token) {\n this.token = res.token;\n if (res.expiresAt) this.tokenExpiry = res.expiresAt;\n return true;\n }\n } catch (e) {\n this.logger?.error?.(\n \"Token refresh failed\",\n e && (e as Error).message ? (e as Error).message : String(e)\n );\n }\n return false;\n }\n\n destroy() {\n this._destroyed = true;\n if (this._reconnectTimer) {\n clearTimeout(this._reconnectTimer);\n this._reconnectTimer = null;\n }\n // reject ready and clear queues/pending\n this._rejectReady(new Error(\"Client destroyed\"));\n this._pending.forEach((pending, id) => {\n if (pending.timer) clearTimeout(pending.timer);\n try {\n pending.reject(new Error(\"Client destroyed\"));\n } catch (e: any) { }\n this._pending.delete(id);\n });\n this._pendingQueue = [];\n try {\n if (this.client) this.client.destroy();\n } catch (e: any) { }\n this.client = null;\n }\n\n _handleDisconnect(err: any) {\n // Prevent handling disconnect multiple times\n if (!this._connected && !this._authenticating) {\n return;\n }\n \n // Check if we're disconnecting during authentication - likely an AUTH FAIL\n const wasAuthenticating = this._authenticating;\n \n // cleanup pending requests\n this._pending.forEach((pending, id) => {\n if (pending.timer) clearTimeout(pending.timer);\n \n // Defer rejection to next tick to allow outer promise chain to catch it\n const errorMsg = wasAuthenticating \n ? \"Authentication failed - credentials may be required\"\n : (err && err.message ? err.message : \"Disconnected\");\n \n process.nextTick(() => {\n try {\n // Create Error here to avoid Bun logging it immediately\n pending.reject(new Error(errorMsg));\n } catch (e: any) { \n // Ignore - rejection already handled\n }\n });\n \n this._pending.delete(id);\n });\n\n this._connected = false;\n // allow new connect() calls to create a fresh connection\n this._connecting = null;\n // reset authenticating state so future connect/auth attempts are clean\n this._authenticating = false;\n\n // DON'T reconnect on auth failure when retries is 0\n if (wasAuthenticating && this.retries === 0) {\n const rejectErr = err || new Error(\"Authentication failed and no retries configured\");\n try {\n this._rejectReady(rejectErr);\n } catch (e: any) { }\n return;\n }\n\n // try reconnect\n if (this._currentRetries < this.retries) {\n // create a fresh ready promise for the reconnect attempt\n this._createReady();\n // add jitter to avoid thundering herd\n const base = Math.min(\n this.retryDelay * Math.pow(2, this._currentRetries),\n 30000\n );\n const jitter = Math.floor(Math.random() * Math.min(1000, base));\n const delay = base + jitter;\n this._currentRetries += 1;\n this.logger?.info?.(\n \"Attempting reconnect in \" +\n delay +\n \"ms (attempt \" +\n this._currentRetries +\n \")\"\n );\n // clear token/state before reconnect attempt\n this.token = null;\n setTimeout(() => {\n // clear any lingering pending queue when reconnecting to fresh state\n // we keep queued requests but they will be reprocessed after connect\n this.connect().catch((e: any) => {\n this.logger?.error?.(\"Reconnect failed\", e && e.message ? e.message : e);\n });\n }, delay);\n } else {\n // give up\n try {\n this._rejectReady(err || new Error(\"Disconnected and no retries left\"));\n } catch (e: any) { }\n }\n }\n\n close() {\n if (!this.client) return;\n try {\n this.client.removeAllListeners(\"data\");\n this.client.removeAllListeners(\"error\");\n this.client.removeAllListeners(\"close\");\n this.client.end();\n } catch (e: any) { }\n this.client = null;\n }\n\n /**\n * Disconnect (alias for close)\n */\n disconnect() {\n this.close();\n }\n\n /**\n * Send request helper (for public API methods)\n */\n async sendRequest(action: Action, data: any = {}): Promise<any> {\n return this.execute({ action, data });\n }\n\n // ========== Public API Methods ==========\n\n /**\n * Login with username and password\n */\n async login(username: string, password: string): Promise<any> {\n return this.sendRequest('login', { username, password });\n }\n\n /**\n * Logout from server\n */\n async logout(): Promise<any> {\n return this.sendRequest('logout', {});\n }\n\n /**\n * List all databases\n */\n async listDatabases(): Promise<any> {\n return this.sendRequest('list-dbs', {});\n }\n\n /**\n * Create a new database\n */\n async createDatabase(name: string): Promise<any> {\n return this.sendRequest('create-db', { databaseName: name });\n }\n\n /**\n * Remove a database\n */\n async removeDatabase(name: string): Promise<any> {\n return this.sendRequest('remove-db', { databaseName: name });\n }\n\n /**\n * Rename a database\n */\n async renameDatabase(oldName: string, newName: string): Promise<any> {\n return this.sendRequest('rename-db', { databaseName: oldName, newName });\n }\n\n /**\n * Execute code in a database\n */\n async run(code: string, databaseName: string): Promise<any> {\n return this.sendRequest('script-code', { code, databaseName });\n }\n\n /**\n * Save a database to disk\n */\n async saveDatabase(databaseName: string): Promise<any> {\n return this.sendRequest('save-db', { databaseName });\n }\n\n /**\n * Update database metadata\n */\n async updateDatabase(databaseName: string, data: any): Promise<any> {\n return this.sendRequest('update-db', { databaseName, ...data });\n }\n\n /**\n * Get server information\n */\n async getInfo(): Promise<any> {\n return this.sendRequest('get-info', {});\n }\n\n /**\n * Execute shell command on server\n */\n async executeShell(command: string): Promise<{ stdout: string; stderr: string }> {\n return this.sendRequest('shell-command', { command });\n }\n}\n\nexport default ScriptDBClient;\n"],"mappings":"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","names":["idx"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import * as net from \"net\";\nimport * as tls from \"tls\";\nimport { URL } from \"url\";\nimport * as crypto from \"crypto\";\n\ntype Action = 'script-code' | 'save-db' | 'remove-db' | 'rename-db' | 'login' | 'logout' | 'get-info' | 'list-dbs' | 'create-db' | 'update-db' | 'get-db' | 'shell-command' | 'string';\n\ninterface DataOptions {\n code?: string | any;\n databaseName?: string | any;\n token?: string | any;\n username?: string | any;\n password?: string | any;\n newName?: string | any;\n}\n\ninterface PayloadOptions {\n id?: number;\n action?: Action;\n data?: DataOptions;\n}\n// Type definitions\ninterface Logger {\n debug?: (...args: any[]) => void;\n info?: (...args: any[]) => void;\n warn?: (...args: any[]) => void;\n error?: (...args: any[]) => void;\n}\n\ninterface ClientOptions {\n secure?: boolean;\n logger?: Logger;\n requestTimeout?: number;\n socketTimeout?: number;\n retries?: number;\n retryDelay?: number;\n tlsOptions?: tls.TlsOptions;\n frame?: 'ndjson' | 'length-prefix';\n preferLengthPrefix?: boolean;\n maxPending?: number;\n maxQueue?: number;\n maxMessageSize?: number;\n signing?: {\n secret: string;\n algorithm?: string;\n };\n stringify?: (obj: any) => string;\n username?: string;\n password?: string;\n tokenRefresh?: () => Promise<{ token: string; expiresAt?: number }>;\n}\n\ninterface PendingRequest {\n resolve: (value: any) => void;\n reject: (error: Error) => void;\n timer: NodeJS.Timeout | null;\n}\n\ninterface QueuedRequest extends PendingRequest {\n payloadBase: PayloadOptions;\n id: number;\n}\n\ninterface Message {\n id?: number;\n action?: Action;\n command?: string;\n message?: string;\n data?: DataOptions;\n token?: string;\n signature?: string;\n payload?: any;\n}\n\n// Minimal no-op logger\nconst noopLogger = {\n debug: () => { },\n info: () => { },\n warn: () => { },\n error: () => { },\n};\n\nexport class ScriptDBClient {\n // Properties\n private options: ClientOptions;\n private socketTimeout: number = 0;\n private maxMessageSize: number = 0;\n private _mask: (obj: any) => any = () => { };\n private _maskArgs: (args: any[]) => any[] = () => [];\n private logger?: Logger = {};\n private secure: boolean = true;\n private requestTimeout: number = 0;\n private retries: number = 0;\n private retryDelay: number = 0;\n private frame: 'ndjson' | 'length-prefix' = 'ndjson';\n private uri: string = '';\n private protocolName: string = '';\n private username: string | null = null;\n private password: string | null = null;\n private host: string = '';\n private port: number = 0;\n private database: string | null = null;\n private client: net.Socket | tls.TLSSocket | null = null;\n private buffer: Buffer = Buffer.alloc(0);\n private _nextId: number = 1;\n private _pending: Map<number, PendingRequest> = new Map();\n private _maxPending: number = 0;\n private _maxQueue: number = 0;\n private _pendingQueue: QueuedRequest[] = [];\n private _connected: boolean = false;\n private _authenticating: boolean = false;\n private token: string | null = null;\n private _currentRetries: number = 0;\n private tokenExpiry: number | null = null;\n private _destroyed: boolean = false;\n private _reconnectTimer: NodeJS.Timeout | null = null;\n private signing: { secret: string; algorithm?: string } | null = null;\n private _stringify: (obj: any) => string = JSON.stringify;\n private ready: Promise<any> = Promise.resolve();\n private _resolveReadyFn: ((value: any) => void) | null = null;\n private _rejectReadyFn: ((err: Error) => void) | null = null;\n private _connecting: Promise<any> | null = null;\n private _authPendingId: number | null = null;\n\n /**\n * Create a new client. Do NOT auto-connect in constructor — call connect()\n * @param uri - Connection URI\n * @param options - Client options\n * @param options.secure - use TLS\n * @param options.logger - { debug, info, warn, error }\n * @param options.requestTimeout - Request timeout in ms\n * @param options.retries - Reconnection retries\n * @param options.retryDelay - Initial retry delay in ms\n * @param options.tlsOptions - Passed to tls.connect when secure\n */\n constructor(uri: string, options: ClientOptions = {}) {\n if (!uri || typeof uri !== \"string\") throw new Error(\"uri required\");\n this.options = Object.assign({}, options);\n // sensible default socket timeout (ms). 0 = disabled (no socket timeout)\n this.socketTimeout = Number.isFinite(this.options.socketTimeout)\n ? this.options.socketTimeout!\n : 0;\n // sensible default max message size (bytes)\n this.maxMessageSize = Number.isFinite(this.options.maxMessageSize)\n ? this.options.maxMessageSize!\n : 5 * 1024 * 1024; // 5MB\n\n // masking helper (used to hide tokens/passwords from logs)\n this._mask = (obj) => {\n try {\n if (!obj || typeof obj !== \"object\") return obj;\n const copy = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj);\n if (copy.token) copy.token = \"****\";\n if (copy.password) copy.password = \"****\";\n if (copy.data && copy.data.password) copy.data.password = \"****\";\n return copy;\n } catch (e) {\n return obj;\n }\n };\n\n // helper to mask any arguments passed to logger methods\n const rawLogger =\n this.options.logger && typeof this.options.logger === \"object\"\n ? this.options.logger\n : noopLogger;\n this._maskArgs = (args) => {\n return args.map((a) => {\n if (!a) return a;\n if (typeof a === \"string\") return a;\n return this._mask(a);\n });\n };\n\n // wrapper logger that masks sensitive fields in objects before delegating\n this.logger = {\n debug: (...args) =>\n rawLogger.debug && rawLogger.debug(...this._maskArgs(args)),\n info: (...args) =>\n rawLogger.info && rawLogger.info(...this._maskArgs(args)),\n warn: (...args) =>\n rawLogger.warn && rawLogger.warn(...this._maskArgs(args)),\n error: (...args) =>\n rawLogger.error && rawLogger.error(...this._maskArgs(args)),\n };\n // secure by default; warn if user explicitly disables secure\n this.secure =\n typeof this.options.secure === \"boolean\" ? !!this.options.secure : true;\n if (!this.secure)\n this.logger.warn?.(\n \"Warning: connecting in insecure mode (secure=false). This is not recommended.\"\n );\n // By default do not set a per-request timeout (0 = disabled).\n this.requestTimeout = Number.isFinite(this.options.requestTimeout)\n ? this.options.requestTimeout!\n : 0;\n this.retries = Number.isFinite(this.options.retries)\n ? this.options.retries!\n : 3;\n this.retryDelay = Number.isFinite(this.options.retryDelay)\n ? this.options.retryDelay!\n : 1000;\n // framing: 'ndjson' (default) or 'length-prefix'. If the caller prefers higher throughput\n // they can set options.preferLengthPrefix = true or options.frame = 'length-prefix'.\n this.frame =\n this.options.frame === \"length-prefix\" || this.options.preferLengthPrefix\n ? \"length-prefix\"\n : \"ndjson\";\n\n // Validate and parse URI - only accept scriptdb:// protocol\n let parsed;\n try {\n parsed = new URL(uri);\n } catch (e) {\n throw new Error(\"Invalid uri\");\n }\n\n // Validate protocol\n if (parsed.protocol !== \"scriptdb:\") {\n throw new Error(\"URI must use scriptdb:// protocol\");\n }\n\n this.uri = uri;\n this.protocolName = parsed.protocol\n ? parsed.protocol.replace(\":\", \"\")\n : \"scriptdb\";\n // prefer explicit credentials passed in options over credentials embedded in the URI\n this.username =\n (typeof this.options.username === \"string\"\n ? this.options.username\n : parsed.username) || null;\n this.password =\n (typeof this.options.password === \"string\"\n ? this.options.password\n : parsed.password) || null;\n if (parsed.username && !(typeof this.options.username === \"string\")) {\n this.logger.warn?.(\n \"Credentials found in URI — consider passing credentials via options instead of embedding in URI\"\n );\n }\n // do not keep credentials in the stored URI representation\n try {\n parsed.username = \"\";\n parsed.password = \"\";\n this.uri = parsed.toString();\n } catch (e) {\n // fallback to original uri\n this.uri = uri;\n }\n this.host = parsed.hostname || \"localhost\";\n this.port = parsed.port ? parseInt(parsed.port, 10) : 1234;\n this.database =\n parsed.pathname && parsed.pathname.length > 1\n ? parsed.pathname.slice(1)\n : null;\n\n // internal state\n this.client = null;\n this.buffer = Buffer.alloc(0);\n this._nextId = 1; // request id generator\n this._pending = new Map(); // id -> {resolve,reject,timer}\n this._maxPending = Number.isFinite(this.options.maxPending)\n ? this.options.maxPending!\n : 100;\n this._maxQueue = Number.isFinite(this.options.maxQueue)\n ? this.options.maxQueue!\n : 1000;\n this._pendingQueue = []; // queued requests when pending >= max\n this._connected = false;\n this._authenticating = false;\n this.token = null;\n this._currentRetries = 0;\n this.tokenExpiry = null; // ms timestamp when token expires\n this._destroyed = false;\n this._reconnectTimer = null;\n\n // signing options: { secret: '...', algorithm: 'sha256' }\n this.signing =\n this.options.signing && this.options.signing.secret\n ? this.options.signing\n : null;\n\n // fast stringify support: allow user to pass a custom stringify function (e.g. fast-json-stringify)\n this._stringify =\n typeof this.options.stringify === \"function\"\n ? this.options.stringify\n : JSON.stringify;\n\n // ready promise lifecycle managed by helpers to avoid race conditions\n this._createReady();\n }\n\n _createReady() {\n this.ready = new Promise((resolve, reject) => {\n this._resolveReadyFn = resolve;\n this._rejectReadyFn = reject;\n });\n }\n\n _resolveReady(value: any) {\n if (this._resolveReadyFn) {\n try {\n this._resolveReadyFn(value);\n } catch (e) { }\n this._resolveReadyFn = null;\n this._rejectReadyFn = null;\n }\n }\n\n _rejectReady(err: Error) {\n if (this._rejectReadyFn) {\n // Use process.nextTick to defer the rejection, preventing unhandled errors\n // when called from event handlers\n const rejectFn = this._rejectReadyFn;\n this._resolveReadyFn = null;\n this._rejectReadyFn = null;\n\n process.nextTick(() => {\n try {\n rejectFn(err);\n } catch (e) {\n // Silently ignore - promise already rejected\n }\n });\n }\n }\n\n /**\n * Check if connected\n */\n get connected(): boolean {\n return this._connected;\n }\n\n /**\n * Connect to server and authenticate. Returns a Promise that resolves when authenticated.\n */\n connect() {\n // avoid double connect\n if (this._connecting) return this._connecting;\n\n this._connecting = new Promise((resolve, reject) => {\n const opts = { host: this.host, port: this.port };\n const onConnect = () => {\n console.log(\"ScriptDBClient: Connected to server at\", opts.host, opts.port);\n this.logger?.info?.(\"Connected to server\");\n this._connected = true;\n this._currentRetries = 0;\n console.log(\"ScriptDBClient: Setting up listeners...\");\n this._setupListeners();\n console.log(\"ScriptDBClient: Authenticating...\");\n this.authenticate()\n .then(() => {\n // reset pending queue processing after auth\n this._processQueue();\n resolve(this);\n })\n .catch((err) => {\n reject(err);\n });\n };\n\n try {\n if (this.secure) {\n // Create a separate object for host and port to avoid type conflicts\n const connectionOpts = { host: opts.host, port: opts.port };\n const tlsOptions: any = Object.assign(\n {},\n this.options.tlsOptions || {},\n connectionOpts\n );\n // safe default\n if (typeof tlsOptions.rejectUnauthorized === \"undefined\")\n tlsOptions.rejectUnauthorized = true;\n this.client = tls.connect(tlsOptions as tls.ConnectionOptions, onConnect);\n } else {\n this.client = net.createConnection(opts, onConnect);\n }\n } catch (e) {\n const error = e as Error;\n this.logger?.error?.(\"Connection failed\", error.message);\n // reject ready if present and clear handlers\n this._rejectReady(error);\n // make sure ready is recreated on next attempt\n this._createReady();\n // allow future connect attempts\n this._connecting = null;\n return reject(error);\n }\n\n // Guard against client not being set (shouldn't happen, but TypeScript needs it)\n if (!this.client) {\n const error = new Error(\"Failed to create client socket\");\n this.logger?.error?.(\"Connection failed\", error.message);\n this._connecting = null;\n return reject(error);\n }\n\n // attach top-level handlers for errors/close to trigger reconnect logic\n const onError = (err: Error) => {\n this.logger?.error?.(\n \"Client socket error:\",\n err && err.message ? err.message : err\n );\n this._handleDisconnect(err);\n };\n const onClose = (hadError: boolean) => {\n this.logger?.info?.(\"Server closed connection\");\n // Don't pass error to avoid double error throwing\n this._handleDisconnect(null);\n };\n this.client.on(\"error\", onError);\n this.client.on(\"close\", onClose);\n // socket timeouts\n if (this.socketTimeout > 0 && this.client) {\n this.client.setTimeout(this.socketTimeout);\n this.client.on(\"timeout\", () => {\n this.logger?.warn?.(\"Socket timeout, destroying connection\");\n try {\n this.client?.destroy();\n } catch (e) { }\n });\n }\n }).catch((err) => {\n // Ensure errors are properly propagated without additional throwing\n this._connecting = null;\n throw err;\n });\n\n return this._connecting;\n }\n\n _setupListeners() {\n if (!this.client) return;\n console.log(\"ScriptDBClient _setupListeners: called, client exists:\", !!this.client);\n // clear any previous data listeners and reset buffer\n this.client.removeAllListeners(\"data\");\n this.buffer = Buffer.alloc(0);\n\n console.log(\"ScriptDBClient _setupListeners: frame mode:\", this.frame);\n\n // Parser depends on framing\n if (this.frame === \"length-prefix\") {\n // length-prefixed framing: [uint32BE length][payload]\n this.client.on(\"data\", (chunk) => {\n if (!Buffer.isBuffer(chunk)) {\n try {\n chunk = Buffer.from(chunk);\n } catch (e) {\n return;\n }\n }\n // fast path: append and scan (we keep concat here for simplicity)\n this.buffer = Buffer.concat([this.buffer, chunk]);\n while (this.buffer.length >= 4) {\n const len = this.buffer.readUInt32BE(0);\n // enforce max message/frame size\n if (len > this.maxMessageSize) {\n this.logger?.error?.(\n \"Incoming length-prefixed frame exceeds maxMessageSize — closing connection\"\n );\n try {\n this.client?.destroy();\n } catch (e) { }\n return;\n }\n if (this.buffer.length < 4 + len) break;\n const payload = this.buffer.slice(4, 4 + len);\n this.buffer = this.buffer.slice(4 + len);\n let msg;\n try {\n msg = JSON.parse(payload.toString(\"utf8\"));\n } catch (e) {\n this.logger?.error?.(\n \"Invalid JSON frame\",\n e && (e as Error).message ? (e as Error).message : e\n );\n continue;\n }\n // validate schema\n if (!msg || typeof msg !== \"object\") continue;\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\") &&\n (typeof msg.data === \"object\" ||\n typeof msg.data === \"undefined\" ||\n msg.data === null);\n if (!validSchema) {\n this.logger?.warn?.(\"Message failed schema validation — ignoring\");\n continue;\n }\n this._handleMessage(msg);\n }\n });\n } else {\n // Buffer-aware NDJSON parser: avoid repeated string concatenation\n console.log(\"ScriptDBClient _setupListeners: Setting up NDJSON data listener\");\n this.client.on(\"data\", (chunk) => {\n console.log(\"ScriptDBClient: Received data chunk, length:\", chunk.length);\n if (!Buffer.isBuffer(chunk)) {\n try {\n chunk = Buffer.from(chunk);\n } catch (e) {\n return;\n }\n }\n\n // If buffer is empty and chunk contains no trailing partial line, avoid concat\n const idxLastNewline = chunk.indexOf(0x0a);\n if (this.buffer.length === 0 && idxLastNewline === chunk.length - 1) {\n // chunk ends with newline and no previous partial: process in-place\n let start = 0;\n let idx;\n while ((idx = chunk.indexOf(0x0a, start)) !== -1) {\n const lineBuf = chunk.slice(start, idx);\n start = idx + 1;\n if (lineBuf.length === 0) continue;\n let msg;\n try {\n msg = JSON.parse(lineBuf.toString(\"utf8\"));\n } catch (e: any) {\n this.logger?.error?.(\n \"Invalid JSON from server\",\n e && e.message ? e.message : e\n );\n continue;\n }\n // schema check\n if (!msg || typeof msg !== \"object\") continue;\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\");\n if (!validSchema) continue;\n this._handleMessage(msg);\n }\n return;\n }\n\n // fallback: append chunk to buffer (infrequent), then scan\n this.buffer = Buffer.concat([this.buffer, chunk]);\n\n // enforce max message size\n // enforce max message size using configured value\n if (this.buffer.length > this.maxMessageSize) {\n this.logger?.error?.(\n \"Incoming message exceeds maxMessageSize — closing connection\"\n );\n try {\n this.client?.destroy();\n } catch (e) { }\n return;\n }\n\n let idx;\n while ((idx = this.buffer.indexOf(0x0a)) !== -1) {\n const lineBuf = this.buffer.slice(0, idx);\n this.buffer = this.buffer.slice(idx + 1);\n if (lineBuf.length === 0) continue;\n let msg;\n try {\n msg = JSON.parse(lineBuf.toString(\"utf8\"));\n } catch (e: any) {\n this.logger?.error?.(\n \"Invalid JSON from server\",\n e && (e as Error).message ? (e as Error).message : e\n );\n continue;\n }\n\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\");\n if (!validSchema) {\n this.logger?.warn?.(\"Message failed schema validation — ignoring\");\n continue;\n }\n\n this._handleMessage(msg);\n }\n });\n }\n }\n\n // build the final buffer for sending using current token and signing settings\n _buildFinalBuffer(payloadBase: Message, id: number) {\n // payloadBase is { action, data }\n const payloadObj: Message = Object.assign(\n { id, action: payloadBase.action },\n payloadBase.data !== undefined ? { data: payloadBase.data } : {}\n );\n // attach current token at send time\n if (this.token) payloadObj.token = this.token;\n\n const payloadStr = this._stringify(payloadObj);\n\n if (this.signing && this.signing.secret) {\n const hmac = crypto.createHmac(\n this.signing.algorithm || \"sha256\",\n this.signing.secret\n );\n hmac.update(payloadStr);\n const sig = hmac.digest(\"hex\");\n const envelope = { id, signature: sig, payload: payloadObj };\n const envelopeStr = this._stringify(envelope);\n if (this.frame === \"length-prefix\") {\n const body = Buffer.from(envelopeStr, \"utf8\");\n const buf = Buffer.allocUnsafe(4 + body.length);\n buf.writeUInt32BE(body.length, 0);\n body.copy(buf, 4);\n return buf;\n }\n return Buffer.from(envelopeStr + \"\\n\", \"utf8\");\n }\n\n // no signing\n if (this.frame === \"length-prefix\") {\n const body = Buffer.from(payloadStr, \"utf8\");\n const buf = Buffer.allocUnsafe(4 + body.length);\n buf.writeUInt32BE(body.length, 0);\n body.copy(buf, 4);\n return buf;\n }\n return Buffer.from(payloadStr + \"\\n\", \"utf8\");\n }\n\n _handleMessage(msg: Message) {\n console.log('ScriptDBClient _handleMessage:', JSON.stringify(msg));\n console.log('ScriptDBClient _handleMessage msg.id:', msg.id, 'msg.action:', msg.action, 'msg.command:', (msg as any).command, 'msg.message:', msg.message);\n\n // message with id for request/response mapping (check this FIRST)\n if (msg && typeof msg.id !== \"undefined\") {\n console.log('Handling message with id:', msg.id, 'action:', msg.action, 'message:', msg.message);\n const pending = this._pending.get(msg.id);\n if (!pending) {\n console.log('No pending request for id', msg.id, 'pending map size:', this._pending.size);\n this.logger?.debug?.(\"No pending request for id\", msg.id);\n return;\n }\n const { resolve, reject, timer } = pending;\n if (timer) clearTimeout(timer);\n this._pending.delete(msg.id);\n // process next queued request if any\n this._processQueue();\n\n // Handle login responses with id\n if (msg.action === \"login\" || msg.command === \"login\") {\n console.log('Processing login response with id');\n if (msg.message === \"AUTH OK\") {\n console.log('AUTH OK - setting token and resolving');\n this.token = msg.data && msg.data.token ? msg.data.token : null;\n this._resolveReady(null);\n return resolve(msg.data);\n } else {\n console.log('AUTH FAILED:', msg.data);\n this._rejectReady(new Error(\"Authentication failed\"));\n const errorMsg = msg.data || \"Authentication failed\";\n // Close the connection after receiving AUTH FAIL\n try {\n this.client?.end();\n } catch (e) { }\n return reject(new Error(typeof errorMsg === 'string' ? errorMsg : \"Authentication failed\"));\n }\n }\n\n if ((msg.action === \"script-code\" || msg.command === \"script-code\") && msg.message === \"OK\")\n return resolve(msg.data);\n if ((msg.action === \"script-code\" || msg.command === \"script-code\") && msg.message === \"ERROR\")\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Server returned ERROR\"));\n\n // Handle create-db responses\n if (msg.action === \"create-db\" && msg.message === \"SUCCESS\")\n return resolve(msg.data);\n if (msg.action === \"create-db\" && msg.message === \"ERROR\")\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Failed to create database\"));\n\n // Default: resolve for OK/SUCCESS, reject for ERROR\n if (msg.message === \"OK\" || msg.message === \"SUCCESS\") {\n return resolve(msg.data);\n } else if (msg.message === \"ERROR\") {\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Request failed\"));\n }\n\n return reject(new Error(\"Invalid response from server\"));\n }\n\n // otherwise, unhandled message\n console.log('Unhandled message:', msg);\n this.logger?.debug?.(\"Unhandled message from server\", this._mask(msg));\n }\n\n authenticate() {\n if (this._authenticating)\n return Promise.reject(new Error(\"Already authenticating\"));\n this._authenticating = true;\n\n return new Promise((resolve, reject) => {\n const id = this._nextId++;\n const payload: Message = {\n id,\n action: \"login\",\n data: { username: this.username, password: this.password },\n };\n\n // create a timer only when requestTimeout is enabled (>0)\n let timer: any = null;\n if (this.requestTimeout > 0) {\n timer = setTimeout(() => {\n this._pending.delete(id);\n this._authenticating = false;\n reject(new Error(\"Auth timeout\"));\n this.close();\n }, this.requestTimeout);\n }\n\n this._pending.set(id, {\n resolve: (data: any) => {\n if (timer) clearTimeout(timer);\n this._authenticating = false;\n // server may still send a login message; set token if present\n if (data && (data as any).token) this.token = (data as any).token;\n resolve(data);\n },\n reject: (err: any) => {\n if (timer) clearTimeout(timer);\n this._authenticating = false;\n reject(err);\n },\n timer,\n });\n\n try {\n // use _write to respect backpressure\n const buf = Buffer.from(JSON.stringify(payload) + \"\\n\", \"utf8\");\n this._write(buf).catch((err: any) => {\n if (timer) clearTimeout(timer);\n this._pending.delete(id);\n this._authenticating = false;\n reject(err);\n });\n } catch (e: any) {\n clearTimeout(timer);\n this._pending.delete(id);\n this._authenticating = false;\n reject(e);\n }\n })\n .then((data: any) => {\n // mark ready if token present\n if (data && (data as any).token) {\n this.token = (data as any).token;\n this._resolveReady(null);\n }\n return data;\n })\n .catch((err: any) => {\n this._rejectReady(err);\n throw err;\n });\n }\n\n // internal write helper that respects backpressure\n _write(buf: any) {\n return new Promise((resolve, reject) => {\n if (!this.client || !this._connected)\n return reject(new Error(\"Not connected\"));\n try {\n const ok = this.client.write(buf, (err) => {\n if (err) return reject(err);\n resolve(undefined);\n });\n if (!ok) {\n // wait for drain\n this.client.once(\"drain\", () => resolve(undefined));\n }\n // if ok was true, the callback above resolves\n } catch (e) {\n reject(e);\n }\n });\n }\n\n async _processQueue() {\n while (\n this._pending.size < this._maxPending &&\n this._pendingQueue.length > 0\n ) {\n const item: any = this._pendingQueue.shift();\n const { payloadBase, id, resolve, reject, timer } = item;\n // ensure token valid or attempt refresh\n if (this.tokenExpiry && Date.now() >= this.tokenExpiry) {\n const refreshed = await this._maybeRefreshToken();\n if (!refreshed) {\n clearTimeout(timer);\n try {\n reject(new Error(\"Token expired and refresh failed\"));\n } catch (e) { }\n continue;\n }\n }\n\n // build final buffer at send time so token is fresh and we don't store tokens in queue\n let buf;\n try {\n buf = this._buildFinalBuffer(payloadBase, id);\n } catch (e) {\n clearTimeout(timer);\n try {\n reject(e);\n } catch (er) { }\n continue;\n }\n\n // register pending before writing so that responses arriving quickly are handled\n this._pending.set(id, { resolve, reject, timer });\n // write with backpressure\n try {\n await this._write(buf);\n } catch (e) {\n clearTimeout(timer);\n this._pending.delete(id);\n try {\n reject(e);\n } catch (er) { }\n }\n }\n }\n\n /**\n * Execute a command. Supports concurrent requests via request id mapping.\n * Returns a Promise resolved with response.data or rejected on ERROR/timeout.\n */\n async execute(payload: Message) {\n // wait until authenticated\n try {\n await this.ready;\n } catch (err: any) {\n throw new Error(\n \"Not authenticated: \" + (err && err.message ? err.message : err)\n );\n }\n\n if (!this.token) throw new Error(\"Not authenticated\");\n\n const id = this._nextId++;\n\n // payloadBase stored in queue; final buffer will be built at send time\n const payloadBase: PayloadOptions = { action: payload.action, data: payload.data };\n\n // if token expired, try refresh before proceeding\n if (this.tokenExpiry && Date.now() >= this.tokenExpiry) {\n const refreshed = await this._maybeRefreshToken();\n if (!refreshed) throw new Error(\"Token expired\");\n }\n\n return new Promise((resolve, reject) => {\n // create request timer only if requestTimeout > 0\n let timer: any = null;\n if (this.requestTimeout > 0) {\n timer = setTimeout(() => {\n if (this._pending.has(id)) {\n this._pending.delete(id);\n reject(new Error(\"Request timeout\"));\n }\n }, this.requestTimeout);\n }\n\n // if too many pending, queue this request\n if (this._pending.size >= this._maxPending) {\n if (this._pendingQueue.length >= this._maxQueue) {\n if (timer) clearTimeout(timer);\n return reject(new Error(\"Pending queue full\"));\n }\n // enqueue payload base so we don't store tokens in the queue\n this._pendingQueue.push({ payloadBase, id, resolve, reject, timer });\n // try to process queue (async)\n this._processQueue().catch(() => { });\n return;\n }\n\n // build final buffer now using current token\n let finalBuf;\n try {\n finalBuf = this._buildFinalBuffer(payloadBase, id);\n } catch (e) {\n clearTimeout(timer);\n return reject(e);\n }\n\n this._pending.set(id, { resolve, reject, timer });\n // write with backpressure handling\n this._write(finalBuf).catch((e) => {\n if (timer) clearTimeout(timer);\n this._pending.delete(id);\n reject(e);\n });\n });\n }\n /**\n * Attempt to refresh token using provided tokenRefresh option if token expired.\n * options.tokenRefresh should be async function that returns { token, expiresAt }\n */\n async _maybeRefreshToken() {\n if (\n !this.options.tokenRefresh ||\n typeof this.options.tokenRefresh !== \"function\"\n )\n return false;\n try {\n const res = await this.options.tokenRefresh();\n if (res && res.token) {\n this.token = res.token;\n if (res.expiresAt) this.tokenExpiry = res.expiresAt;\n return true;\n }\n } catch (e) {\n this.logger?.error?.(\n \"Token refresh failed\",\n e && (e as Error).message ? (e as Error).message : String(e)\n );\n }\n return false;\n }\n\n destroy() {\n this._destroyed = true;\n if (this._reconnectTimer) {\n clearTimeout(this._reconnectTimer);\n this._reconnectTimer = null;\n }\n // reject ready and clear queues/pending\n this._rejectReady(new Error(\"Client destroyed\"));\n this._pending.forEach((pending, id) => {\n if (pending.timer) clearTimeout(pending.timer);\n try {\n pending.reject(new Error(\"Client destroyed\"));\n } catch (e: any) { }\n this._pending.delete(id);\n });\n this._pendingQueue = [];\n try {\n if (this.client) this.client.destroy();\n } catch (e: any) { }\n this.client = null;\n }\n\n _handleDisconnect(err: any) {\n // Prevent handling disconnect multiple times\n if (!this._connected && !this._authenticating) {\n return;\n }\n\n // Check if we're disconnecting during authentication - likely an AUTH FAIL\n const wasAuthenticating = this._authenticating;\n\n // cleanup pending requests\n this._pending.forEach((pending, id) => {\n if (pending.timer) clearTimeout(pending.timer);\n\n // Defer rejection to next tick to allow outer promise chain to catch it\n const errorMsg = wasAuthenticating\n ? \"Authentication failed - credentials may be required\"\n : (err && err.message ? err.message : \"Disconnected\");\n\n process.nextTick(() => {\n try {\n // Create Error here to avoid Bun logging it immediately\n pending.reject(new Error(errorMsg));\n } catch (e: any) {\n // Ignore - rejection already handled\n }\n });\n\n this._pending.delete(id);\n });\n\n this._connected = false;\n // allow new connect() calls to create a fresh connection\n this._connecting = null;\n // reset authenticating state so future connect/auth attempts are clean\n this._authenticating = false;\n\n // DON'T reconnect on auth failure when retries is 0\n if (wasAuthenticating && this.retries === 0) {\n const rejectErr = err || new Error(\"Authentication failed and no retries configured\");\n try {\n this._rejectReady(rejectErr);\n } catch (e: any) { }\n return;\n }\n\n // try reconnect\n if (this._currentRetries < this.retries) {\n // create a fresh ready promise for the reconnect attempt\n this._createReady();\n // add jitter to avoid thundering herd\n const base = Math.min(\n this.retryDelay * Math.pow(2, this._currentRetries),\n 30000\n );\n const jitter = Math.floor(Math.random() * Math.min(1000, base));\n const delay = base + jitter;\n this._currentRetries += 1;\n this.logger?.info?.(\n \"Attempting reconnect in \" +\n delay +\n \"ms (attempt \" +\n this._currentRetries +\n \")\"\n );\n // clear token/state before reconnect attempt\n this.token = null;\n setTimeout(() => {\n // clear any lingering pending queue when reconnecting to fresh state\n // we keep queued requests but they will be reprocessed after connect\n this.connect().catch((e: any) => {\n this.logger?.error?.(\"Reconnect failed\", e && e.message ? e.message : e);\n });\n }, delay);\n } else {\n // give up\n try {\n this._rejectReady(err || new Error(\"Disconnected and no retries left\"));\n } catch (e: any) { }\n }\n }\n\n close() {\n if (!this.client) return;\n try {\n this.client.removeAllListeners(\"data\");\n this.client.removeAllListeners(\"error\");\n this.client.removeAllListeners(\"close\");\n this.client.end();\n } catch (e: any) { }\n this.client = null;\n }\n\n /**\n * Disconnect (alias for close)\n */\n disconnect() {\n this.close();\n }\n\n /**\n * Send request helper (for public API methods)\n */\n async sendRequest(action: Action, data: any = {}): Promise<any> {\n return this.execute({ action, data });\n }\n\n // ========== Public API Methods ==========\n\n /**\n * Login with username and password\n */\n async login(username: string, password: string): Promise<any> {\n return this.sendRequest('login', { username, password });\n }\n\n /**\n * Logout from server\n */\n async logout(): Promise<any> {\n return this.sendRequest('logout', {});\n }\n\n /**\n * List all databases\n */\n async listDatabases(): Promise<any> {\n return this.sendRequest('list-dbs', {});\n }\n\n /**\n * Create a new database\n */\n async createDatabase(name: string): Promise<any> {\n return this.sendRequest('create-db', { databaseName: name });\n }\n\n /**\n * Remove a database\n */\n async removeDatabase(name: string): Promise<any> {\n return this.sendRequest('remove-db', { databaseName: name });\n }\n\n /**\n * Rename a database\n */\n async renameDatabase(oldName: string, newName: string): Promise<any> {\n return this.sendRequest('rename-db', { databaseName: oldName, newName });\n }\n\n /**\n * Execute code in a database\n */\n async run(code: string|Function, databaseName: string): Promise<any> {\n let stringCode: string;\n if (typeof code === 'function') {\n const funcStr = code.toString();\n // ตัด arrow function หรือ function keyword และ opening brace ออก\n const arrowMatch = funcStr.match(/^[\\s]*\\(?\\s*\\)?\\s*=>\\s*{?/);\n const functionMatch = funcStr.match(/^[\\s]*function\\s*\\(?[\\w\\s]*\\)?\\s*{/);\n const match = arrowMatch || functionMatch;\n const start = match ? match[0].length : 0;\n const end = funcStr.lastIndexOf('}');\n stringCode = funcStr.substring(start, end);\n // Trim leading newline, spaces, and trailing\n stringCode = stringCode.replace(/^[\\s\\r\\n]+/, '').replace(/[\\s\\r\\n]+$/, '');\n\n // Transform import(aa).from(\"module\") to import aa from \"module\"\n stringCode = stringCode.replace(\n /import\\s*\\(\\s*([^)]+?)\\s*\\)\\s*\\.from\\s*\\(\\s*(['\"])([^'\"]+)\\2\\s*\\)/g,\n (_, importArg, quote, modulePath) => {\n // Check if importArg is wrapped in braces (destructuring)\n const trimmed = importArg.trim();\n if (trimmed.startsWith('{') && trimmed.endsWith('}')) {\n // Destructuring: import({bb}) -> import { bb }\n const inner = trimmed.slice(1, -1).trim();\n return `import { ${inner} } from ${quote}${modulePath}${quote}`;\n } else {\n // Default: import(aa) -> import aa\n return `import ${trimmed} from ${quote}${modulePath}${quote}`;\n }\n }\n );\n\n // Trim leading whitespace from each line\n stringCode = stringCode.split('\\n').map(line => line.trim()).join('\\n').trim();\n } else {\n stringCode = code;\n }\n return this.sendRequest('script-code', { code: stringCode, databaseName });\n }\n\n /**\n * Save a database to disk\n */\n async saveDatabase(databaseName: string): Promise<any> {\n return this.sendRequest('save-db', { databaseName });\n }\n\n /**\n * Update database metadata\n */\n async updateDatabase(databaseName: string, data: any): Promise<any> {\n return this.sendRequest('update-db', { databaseName, ...data });\n }\n\n /**\n * Get server information\n */\n async getInfo(): Promise<any> {\n return this.sendRequest('get-info', {});\n }\n\n /**\n * Execute shell command on server\n */\n async executeShell(command: string): Promise<{ stdout: string; stderr: string }> {\n return this.sendRequest('shell-command', { command });\n }\n}\n\nexport default ScriptDBClient;\n"],"mappings":"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","names":["idx"]}
|
package/dist/index.mjs
CHANGED
|
@@ -802,7 +802,33 @@ var ScriptDBClient = class {
|
|
|
802
802
|
* Execute code in a database
|
|
803
803
|
*/
|
|
804
804
|
async run(code, databaseName) {
|
|
805
|
-
|
|
805
|
+
let stringCode;
|
|
806
|
+
if (typeof code === "function") {
|
|
807
|
+
const funcStr = code.toString();
|
|
808
|
+
const arrowMatch = funcStr.match(/^[\s]*\(?\s*\)?\s*=>\s*{?/);
|
|
809
|
+
const functionMatch = funcStr.match(/^[\s]*function\s*\(?[\w\s]*\)?\s*{/);
|
|
810
|
+
const match = arrowMatch || functionMatch;
|
|
811
|
+
const start = match ? match[0].length : 0;
|
|
812
|
+
const end = funcStr.lastIndexOf("}");
|
|
813
|
+
stringCode = funcStr.substring(start, end);
|
|
814
|
+
stringCode = stringCode.replace(/^[\s\r\n]+/, "").replace(/[\s\r\n]+$/, "");
|
|
815
|
+
stringCode = stringCode.replace(
|
|
816
|
+
/import\s*\(\s*([^)]+?)\s*\)\s*\.from\s*\(\s*(['"])([^'"]+)\2\s*\)/g,
|
|
817
|
+
(_, importArg, quote, modulePath) => {
|
|
818
|
+
const trimmed = importArg.trim();
|
|
819
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
820
|
+
const inner = trimmed.slice(1, -1).trim();
|
|
821
|
+
return `import { ${inner} } from ${quote}${modulePath}${quote}`;
|
|
822
|
+
} else {
|
|
823
|
+
return `import ${trimmed} from ${quote}${modulePath}${quote}`;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
);
|
|
827
|
+
stringCode = stringCode.split("\n").map((line) => line.trim()).join("\n").trim();
|
|
828
|
+
} else {
|
|
829
|
+
stringCode = code;
|
|
830
|
+
}
|
|
831
|
+
return this.sendRequest("script-code", { code: stringCode, databaseName });
|
|
806
832
|
}
|
|
807
833
|
/**
|
|
808
834
|
* Save a database to disk
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import * as net from \"net\";\nimport * as tls from \"tls\";\nimport { URL } from \"url\";\nimport * as crypto from \"crypto\";\n\ntype Action = 'script-code' | 'save-db' | 'remove-db' | 'rename-db' | 'login' | 'logout' | 'get-info' | 'list-dbs' | 'create-db' | 'update-db' | 'get-db' | 'shell-command' | 'string';\n\ninterface DataOptions {\n code?: string | any;\n databaseName?: string | any;\n token?: string | any;\n username?: string | any;\n password?: string | any;\n newName?: string | any;\n}\n\ninterface PayloadOptions {\n id?: number;\n action?: Action;\n data?: DataOptions;\n}\n// Type definitions\ninterface Logger {\n debug?: (...args: any[]) => void;\n info?: (...args: any[]) => void;\n warn?: (...args: any[]) => void;\n error?: (...args: any[]) => void;\n}\n\ninterface ClientOptions {\n secure?: boolean;\n logger?: Logger;\n requestTimeout?: number;\n socketTimeout?: number;\n retries?: number;\n retryDelay?: number;\n tlsOptions?: tls.TlsOptions;\n frame?: 'ndjson' | 'length-prefix';\n preferLengthPrefix?: boolean;\n maxPending?: number;\n maxQueue?: number;\n maxMessageSize?: number;\n signing?: {\n secret: string;\n algorithm?: string;\n };\n stringify?: (obj: any) => string;\n username?: string;\n password?: string;\n tokenRefresh?: () => Promise<{ token: string; expiresAt?: number }>;\n}\n\ninterface PendingRequest {\n resolve: (value: any) => void;\n reject: (error: Error) => void;\n timer: NodeJS.Timeout | null;\n}\n\ninterface QueuedRequest extends PendingRequest {\n payloadBase: PayloadOptions;\n id: number;\n}\n\ninterface Message {\n id?: number;\n action?: Action;\n command?: string;\n message?: string;\n data?: DataOptions;\n token?: string;\n signature?: string;\n payload?: any;\n}\n\n// Minimal no-op logger\nconst noopLogger = {\n debug: () => { },\n info: () => { },\n warn: () => { },\n error: () => { },\n};\n\nexport class ScriptDBClient {\n // Properties\n private options: ClientOptions;\n private socketTimeout: number = 0;\n private maxMessageSize: number = 0;\n private _mask: (obj: any) => any = () => { };\n private _maskArgs: (args: any[]) => any[] = () => [];\n private logger?: Logger = {};\n private secure: boolean = true;\n private requestTimeout: number = 0;\n private retries: number = 0;\n private retryDelay: number = 0;\n private frame: 'ndjson' | 'length-prefix' = 'ndjson';\n private uri: string = '';\n private protocolName: string = '';\n private username: string | null = null;\n private password: string | null = null;\n private host: string = '';\n private port: number = 0;\n private database: string | null = null;\n private client: net.Socket | tls.TLSSocket | null = null;\n private buffer: Buffer = Buffer.alloc(0);\n private _nextId: number = 1;\n private _pending: Map<number, PendingRequest> = new Map();\n private _maxPending: number = 0;\n private _maxQueue: number = 0;\n private _pendingQueue: QueuedRequest[] = [];\n private _connected: boolean = false;\n private _authenticating: boolean = false;\n private token: string | null = null;\n private _currentRetries: number = 0;\n private tokenExpiry: number | null = null;\n private _destroyed: boolean = false;\n private _reconnectTimer: NodeJS.Timeout | null = null;\n private signing: { secret: string; algorithm?: string } | null = null;\n private _stringify: (obj: any) => string = JSON.stringify;\n private ready: Promise<any> = Promise.resolve();\n private _resolveReadyFn: ((value: any) => void) | null = null;\n private _rejectReadyFn: ((err: Error) => void) | null = null;\n private _connecting: Promise<any> | null = null;\n private _authPendingId: number | null = null;\n\n /**\n * Create a new client. Do NOT auto-connect in constructor — call connect()\n * @param uri - Connection URI\n * @param options - Client options\n * @param options.secure - use TLS\n * @param options.logger - { debug, info, warn, error }\n * @param options.requestTimeout - Request timeout in ms\n * @param options.retries - Reconnection retries\n * @param options.retryDelay - Initial retry delay in ms\n * @param options.tlsOptions - Passed to tls.connect when secure\n */\n constructor(uri: string, options: ClientOptions = {}) {\n if (!uri || typeof uri !== \"string\") throw new Error(\"uri required\");\n this.options = Object.assign({}, options);\n // sensible default socket timeout (ms). 0 = disabled (no socket timeout)\n this.socketTimeout = Number.isFinite(this.options.socketTimeout)\n ? this.options.socketTimeout!\n : 0;\n // sensible default max message size (bytes)\n this.maxMessageSize = Number.isFinite(this.options.maxMessageSize)\n ? this.options.maxMessageSize!\n : 5 * 1024 * 1024; // 5MB\n\n // masking helper (used to hide tokens/passwords from logs)\n this._mask = (obj) => {\n try {\n if (!obj || typeof obj !== \"object\") return obj;\n const copy = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj);\n if (copy.token) copy.token = \"****\";\n if (copy.password) copy.password = \"****\";\n if (copy.data && copy.data.password) copy.data.password = \"****\";\n return copy;\n } catch (e) {\n return obj;\n }\n };\n\n // helper to mask any arguments passed to logger methods\n const rawLogger =\n this.options.logger && typeof this.options.logger === \"object\"\n ? this.options.logger\n : noopLogger;\n this._maskArgs = (args) => {\n return args.map((a) => {\n if (!a) return a;\n if (typeof a === \"string\") return a;\n return this._mask(a);\n });\n };\n\n // wrapper logger that masks sensitive fields in objects before delegating\n this.logger = {\n debug: (...args) =>\n rawLogger.debug && rawLogger.debug(...this._maskArgs(args)),\n info: (...args) =>\n rawLogger.info && rawLogger.info(...this._maskArgs(args)),\n warn: (...args) =>\n rawLogger.warn && rawLogger.warn(...this._maskArgs(args)),\n error: (...args) =>\n rawLogger.error && rawLogger.error(...this._maskArgs(args)),\n };\n // secure by default; warn if user explicitly disables secure\n this.secure =\n typeof this.options.secure === \"boolean\" ? !!this.options.secure : true;\n if (!this.secure)\n this.logger.warn?.(\n \"Warning: connecting in insecure mode (secure=false). This is not recommended.\"\n );\n // By default do not set a per-request timeout (0 = disabled).\n this.requestTimeout = Number.isFinite(this.options.requestTimeout)\n ? this.options.requestTimeout!\n : 0;\n this.retries = Number.isFinite(this.options.retries)\n ? this.options.retries!\n : 3;\n this.retryDelay = Number.isFinite(this.options.retryDelay)\n ? this.options.retryDelay!\n : 1000;\n // framing: 'ndjson' (default) or 'length-prefix'. If the caller prefers higher throughput\n // they can set options.preferLengthPrefix = true or options.frame = 'length-prefix'.\n this.frame =\n this.options.frame === \"length-prefix\" || this.options.preferLengthPrefix\n ? \"length-prefix\"\n : \"ndjson\";\n\n // Validate and parse URI - only accept scriptdb:// protocol\n let parsed;\n try {\n parsed = new URL(uri);\n } catch (e) {\n throw new Error(\"Invalid uri\");\n }\n\n // Validate protocol\n if (parsed.protocol !== \"scriptdb:\") {\n throw new Error(\"URI must use scriptdb:// protocol\");\n }\n\n this.uri = uri;\n this.protocolName = parsed.protocol\n ? parsed.protocol.replace(\":\", \"\")\n : \"scriptdb\";\n // prefer explicit credentials passed in options over credentials embedded in the URI\n this.username =\n (typeof this.options.username === \"string\"\n ? this.options.username\n : parsed.username) || null;\n this.password =\n (typeof this.options.password === \"string\"\n ? this.options.password\n : parsed.password) || null;\n if (parsed.username && !(typeof this.options.username === \"string\")) {\n this.logger.warn?.(\n \"Credentials found in URI — consider passing credentials via options instead of embedding in URI\"\n );\n }\n // do not keep credentials in the stored URI representation\n try {\n parsed.username = \"\";\n parsed.password = \"\";\n this.uri = parsed.toString();\n } catch (e) {\n // fallback to original uri\n this.uri = uri;\n }\n this.host = parsed.hostname || \"localhost\";\n this.port = parsed.port ? parseInt(parsed.port, 10) : 1234;\n this.database =\n parsed.pathname && parsed.pathname.length > 1\n ? parsed.pathname.slice(1)\n : null;\n\n // internal state\n this.client = null;\n this.buffer = Buffer.alloc(0);\n this._nextId = 1; // request id generator\n this._pending = new Map(); // id -> {resolve,reject,timer}\n this._maxPending = Number.isFinite(this.options.maxPending)\n ? this.options.maxPending!\n : 100;\n this._maxQueue = Number.isFinite(this.options.maxQueue)\n ? this.options.maxQueue!\n : 1000;\n this._pendingQueue = []; // queued requests when pending >= max\n this._connected = false;\n this._authenticating = false;\n this.token = null;\n this._currentRetries = 0;\n this.tokenExpiry = null; // ms timestamp when token expires\n this._destroyed = false;\n this._reconnectTimer = null;\n\n // signing options: { secret: '...', algorithm: 'sha256' }\n this.signing =\n this.options.signing && this.options.signing.secret\n ? this.options.signing\n : null;\n\n // fast stringify support: allow user to pass a custom stringify function (e.g. fast-json-stringify)\n this._stringify =\n typeof this.options.stringify === \"function\"\n ? this.options.stringify\n : JSON.stringify;\n\n // ready promise lifecycle managed by helpers to avoid race conditions\n this._createReady();\n }\n\n _createReady() {\n this.ready = new Promise((resolve, reject) => {\n this._resolveReadyFn = resolve;\n this._rejectReadyFn = reject;\n });\n }\n\n _resolveReady(value: any) {\n if (this._resolveReadyFn) {\n try {\n this._resolveReadyFn(value);\n } catch (e) { }\n this._resolveReadyFn = null;\n this._rejectReadyFn = null;\n }\n }\n\n _rejectReady(err: Error) {\n if (this._rejectReadyFn) {\n // Use process.nextTick to defer the rejection, preventing unhandled errors\n // when called from event handlers\n const rejectFn = this._rejectReadyFn;\n this._resolveReadyFn = null;\n this._rejectReadyFn = null;\n \n process.nextTick(() => {\n try {\n rejectFn(err);\n } catch (e) {\n // Silently ignore - promise already rejected\n }\n });\n }\n }\n\n /**\n * Check if connected\n */\n get connected(): boolean {\n return this._connected;\n }\n\n /**\n * Connect to server and authenticate. Returns a Promise that resolves when authenticated.\n */\n connect() {\n // avoid double connect\n if (this._connecting) return this._connecting;\n\n this._connecting = new Promise((resolve, reject) => {\n const opts = { host: this.host, port: this.port };\n const onConnect = () => {\n console.log(\"ScriptDBClient: Connected to server at\", opts.host, opts.port);\n this.logger?.info?.(\"Connected to server\");\n this._connected = true;\n this._currentRetries = 0;\n console.log(\"ScriptDBClient: Setting up listeners...\");\n this._setupListeners();\n console.log(\"ScriptDBClient: Authenticating...\");\n this.authenticate()\n .then(() => {\n // reset pending queue processing after auth\n this._processQueue();\n resolve(this);\n })\n .catch((err) => {\n reject(err);\n });\n };\n\n try {\n if (this.secure) {\n // Create a separate object for host and port to avoid type conflicts\n const connectionOpts = { host: opts.host, port: opts.port };\n const tlsOptions: any = Object.assign(\n {},\n this.options.tlsOptions || {},\n connectionOpts\n );\n // safe default\n if (typeof tlsOptions.rejectUnauthorized === \"undefined\")\n tlsOptions.rejectUnauthorized = true;\n this.client = tls.connect(tlsOptions as tls.ConnectionOptions, onConnect);\n } else {\n this.client = net.createConnection(opts, onConnect);\n }\n } catch (e) {\n const error = e as Error;\n this.logger?.error?.(\"Connection failed\", error.message);\n // reject ready if present and clear handlers\n this._rejectReady(error);\n // make sure ready is recreated on next attempt\n this._createReady();\n // allow future connect attempts\n this._connecting = null;\n return reject(error);\n }\n\n // Guard against client not being set (shouldn't happen, but TypeScript needs it)\n if (!this.client) {\n const error = new Error(\"Failed to create client socket\");\n this.logger?.error?.(\"Connection failed\", error.message);\n this._connecting = null;\n return reject(error);\n }\n\n // attach top-level handlers for errors/close to trigger reconnect logic\n const onError = (err: Error) => {\n this.logger?.error?.(\n \"Client socket error:\",\n err && err.message ? err.message : err\n );\n this._handleDisconnect(err);\n };\n const onClose = (hadError: boolean) => {\n this.logger?.info?.(\"Server closed connection\");\n // Don't pass error to avoid double error throwing\n this._handleDisconnect(null);\n };\n this.client.on(\"error\", onError);\n this.client.on(\"close\", onClose);\n // socket timeouts\n if (this.socketTimeout > 0 && this.client) {\n this.client.setTimeout(this.socketTimeout);\n this.client.on(\"timeout\", () => {\n this.logger?.warn?.(\"Socket timeout, destroying connection\");\n try {\n this.client?.destroy();\n } catch (e) { }\n });\n }\n }).catch((err) => {\n // Ensure errors are properly propagated without additional throwing\n this._connecting = null;\n throw err;\n });\n\n return this._connecting;\n }\n\n _setupListeners() {\n if (!this.client) return;\n console.log(\"ScriptDBClient _setupListeners: called, client exists:\", !!this.client);\n // clear any previous data listeners and reset buffer\n this.client.removeAllListeners(\"data\");\n this.buffer = Buffer.alloc(0);\n\n console.log(\"ScriptDBClient _setupListeners: frame mode:\", this.frame);\n \n // Parser depends on framing\n if (this.frame === \"length-prefix\") {\n // length-prefixed framing: [uint32BE length][payload]\n this.client.on(\"data\", (chunk) => {\n if (!Buffer.isBuffer(chunk)) {\n try {\n chunk = Buffer.from(chunk);\n } catch (e) {\n return;\n }\n }\n // fast path: append and scan (we keep concat here for simplicity)\n this.buffer = Buffer.concat([this.buffer, chunk]);\n while (this.buffer.length >= 4) {\n const len = this.buffer.readUInt32BE(0);\n // enforce max message/frame size\n if (len > this.maxMessageSize) {\n this.logger?.error?.(\n \"Incoming length-prefixed frame exceeds maxMessageSize — closing connection\"\n );\n try {\n this.client?.destroy();\n } catch (e) { }\n return;\n }\n if (this.buffer.length < 4 + len) break;\n const payload = this.buffer.slice(4, 4 + len);\n this.buffer = this.buffer.slice(4 + len);\n let msg;\n try {\n msg = JSON.parse(payload.toString(\"utf8\"));\n } catch (e) {\n this.logger?.error?.(\n \"Invalid JSON frame\",\n e && (e as Error).message ? (e as Error).message : e\n );\n continue;\n }\n // validate schema\n if (!msg || typeof msg !== \"object\") continue;\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\") &&\n (typeof msg.data === \"object\" ||\n typeof msg.data === \"undefined\" ||\n msg.data === null);\n if (!validSchema) {\n this.logger?.warn?.(\"Message failed schema validation — ignoring\");\n continue;\n }\n this._handleMessage(msg);\n }\n });\n } else {\n // Buffer-aware NDJSON parser: avoid repeated string concatenation\n console.log(\"ScriptDBClient _setupListeners: Setting up NDJSON data listener\");\n this.client.on(\"data\", (chunk) => {\n console.log(\"ScriptDBClient: Received data chunk, length:\", chunk.length);\n if (!Buffer.isBuffer(chunk)) {\n try {\n chunk = Buffer.from(chunk);\n } catch (e) {\n return;\n }\n }\n\n // If buffer is empty and chunk contains no trailing partial line, avoid concat\n const idxLastNewline = chunk.indexOf(0x0a);\n if (this.buffer.length === 0 && idxLastNewline === chunk.length - 1) {\n // chunk ends with newline and no previous partial: process in-place\n let start = 0;\n let idx;\n while ((idx = chunk.indexOf(0x0a, start)) !== -1) {\n const lineBuf = chunk.slice(start, idx);\n start = idx + 1;\n if (lineBuf.length === 0) continue;\n let msg;\n try {\n msg = JSON.parse(lineBuf.toString(\"utf8\"));\n } catch (e: any) {\n this.logger?.error?.(\n \"Invalid JSON from server\",\n e && e.message ? e.message : e\n );\n continue;\n }\n // schema check\n if (!msg || typeof msg !== \"object\") continue;\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\");\n if (!validSchema) continue;\n this._handleMessage(msg);\n }\n return;\n }\n\n // fallback: append chunk to buffer (infrequent), then scan\n this.buffer = Buffer.concat([this.buffer, chunk]);\n\n // enforce max message size\n // enforce max message size using configured value\n if (this.buffer.length > this.maxMessageSize) {\n this.logger?.error?.(\n \"Incoming message exceeds maxMessageSize — closing connection\"\n );\n try {\n this.client?.destroy();\n } catch (e) { }\n return;\n }\n\n let idx;\n while ((idx = this.buffer.indexOf(0x0a)) !== -1) {\n const lineBuf = this.buffer.slice(0, idx);\n this.buffer = this.buffer.slice(idx + 1);\n if (lineBuf.length === 0) continue;\n let msg;\n try {\n msg = JSON.parse(lineBuf.toString(\"utf8\"));\n } catch (e: any) {\n this.logger?.error?.(\n \"Invalid JSON from server\",\n e && (e as Error).message ? (e as Error).message : e\n );\n continue;\n }\n\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\");\n if (!validSchema) {\n this.logger?.warn?.(\"Message failed schema validation — ignoring\");\n continue;\n }\n\n this._handleMessage(msg);\n }\n });\n }\n }\n\n // build the final buffer for sending using current token and signing settings\n _buildFinalBuffer(payloadBase: Message, id: number) {\n // payloadBase is { action, data }\n const payloadObj: Message = Object.assign(\n { id, action: payloadBase.action },\n payloadBase.data !== undefined ? { data: payloadBase.data } : {}\n );\n // attach current token at send time\n if (this.token) payloadObj.token = this.token;\n\n const payloadStr = this._stringify(payloadObj);\n\n if (this.signing && this.signing.secret) {\n const hmac = crypto.createHmac(\n this.signing.algorithm || \"sha256\",\n this.signing.secret\n );\n hmac.update(payloadStr);\n const sig = hmac.digest(\"hex\");\n const envelope = { id, signature: sig, payload: payloadObj };\n const envelopeStr = this._stringify(envelope);\n if (this.frame === \"length-prefix\") {\n const body = Buffer.from(envelopeStr, \"utf8\");\n const buf = Buffer.allocUnsafe(4 + body.length);\n buf.writeUInt32BE(body.length, 0);\n body.copy(buf, 4);\n return buf;\n }\n return Buffer.from(envelopeStr + \"\\n\", \"utf8\");\n }\n\n // no signing\n if (this.frame === \"length-prefix\") {\n const body = Buffer.from(payloadStr, \"utf8\");\n const buf = Buffer.allocUnsafe(4 + body.length);\n buf.writeUInt32BE(body.length, 0);\n body.copy(buf, 4);\n return buf;\n }\n return Buffer.from(payloadStr + \"\\n\", \"utf8\");\n }\n\n _handleMessage(msg: Message) {\n console.log('ScriptDBClient _handleMessage:', JSON.stringify(msg));\n console.log('ScriptDBClient _handleMessage msg.id:', msg.id, 'msg.action:', msg.action, 'msg.command:', (msg as any).command, 'msg.message:', msg.message);\n \n // message with id for request/response mapping (check this FIRST)\n if (msg && typeof msg.id !== \"undefined\") {\n console.log('Handling message with id:', msg.id, 'action:', msg.action, 'message:', msg.message);\n const pending = this._pending.get(msg.id);\n if (!pending) {\n console.log('No pending request for id', msg.id, 'pending map size:', this._pending.size);\n this.logger?.debug?.(\"No pending request for id\", msg.id);\n return;\n }\n const { resolve, reject, timer } = pending;\n if (timer) clearTimeout(timer);\n this._pending.delete(msg.id);\n // process next queued request if any\n this._processQueue();\n\n // Handle login responses with id\n if (msg.action === \"login\" || msg.command === \"login\") {\n console.log('Processing login response with id');\n if (msg.message === \"AUTH OK\") {\n console.log('AUTH OK - setting token and resolving');\n this.token = msg.data && msg.data.token ? msg.data.token : null;\n this._resolveReady(null);\n return resolve(msg.data);\n } else {\n console.log('AUTH FAILED:', msg.data);\n this._rejectReady(new Error(\"Authentication failed\"));\n const errorMsg = msg.data || \"Authentication failed\";\n // Close the connection after receiving AUTH FAIL\n try {\n this.client?.end();\n } catch (e) {}\n return reject(new Error(typeof errorMsg === 'string' ? errorMsg : \"Authentication failed\"));\n }\n }\n\n if ((msg.action === \"script-code\" || msg.command === \"script-code\") && msg.message === \"OK\")\n return resolve(msg.data);\n if ((msg.action === \"script-code\" || msg.command === \"script-code\") && msg.message === \"ERROR\")\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Server returned ERROR\"));\n \n // Handle create-db responses\n if (msg.action === \"create-db\" && msg.message === \"SUCCESS\")\n return resolve(msg.data);\n if (msg.action === \"create-db\" && msg.message === \"ERROR\")\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Failed to create database\"));\n \n // Default: resolve for OK/SUCCESS, reject for ERROR\n if (msg.message === \"OK\" || msg.message === \"SUCCESS\") {\n return resolve(msg.data);\n } else if (msg.message === \"ERROR\") {\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Request failed\"));\n }\n \n return reject(new Error(\"Invalid response from server\"));\n }\n\n // otherwise, unhandled message\n console.log('Unhandled message:', msg);\n this.logger?.debug?.(\"Unhandled message from server\", this._mask(msg));\n }\n\n authenticate() {\n if (this._authenticating)\n return Promise.reject(new Error(\"Already authenticating\"));\n this._authenticating = true;\n\n return new Promise((resolve, reject) => {\n const id = this._nextId++;\n const payload:Message = {\n id,\n action: \"login\",\n data: { username: this.username, password: this.password },\n };\n\n // create a timer only when requestTimeout is enabled (>0)\n let timer: any = null;\n if (this.requestTimeout > 0) {\n timer = setTimeout(() => {\n this._pending.delete(id);\n this._authenticating = false;\n reject(new Error(\"Auth timeout\"));\n this.close();\n }, this.requestTimeout);\n }\n\n this._pending.set(id, {\n resolve: (data: any) => {\n if (timer) clearTimeout(timer);\n this._authenticating = false;\n // server may still send a login message; set token if present\n if (data && (data as any).token) this.token = (data as any).token;\n resolve(data);\n },\n reject: (err: any) => {\n if (timer) clearTimeout(timer);\n this._authenticating = false;\n reject(err);\n },\n timer,\n });\n\n try {\n // use _write to respect backpressure\n const buf = Buffer.from(JSON.stringify(payload) + \"\\n\", \"utf8\");\n this._write(buf).catch((err: any) => {\n if (timer) clearTimeout(timer);\n this._pending.delete(id);\n this._authenticating = false;\n reject(err);\n });\n } catch (e: any) {\n clearTimeout(timer);\n this._pending.delete(id);\n this._authenticating = false;\n reject(e);\n }\n })\n .then((data: any) => {\n // mark ready if token present\n if (data && (data as any).token) {\n this.token = (data as any).token;\n this._resolveReady(null);\n }\n return data;\n })\n .catch((err: any) => {\n this._rejectReady(err);\n throw err;\n });\n }\n\n // internal write helper that respects backpressure\n _write(buf: any) {\n return new Promise((resolve, reject) => {\n if (!this.client || !this._connected)\n return reject(new Error(\"Not connected\"));\n try {\n const ok = this.client.write(buf, (err) => {\n if (err) return reject(err);\n resolve(undefined);\n });\n if (!ok) {\n // wait for drain\n this.client.once(\"drain\", () => resolve(undefined));\n }\n // if ok was true, the callback above resolves\n } catch (e) {\n reject(e);\n }\n });\n }\n\n async _processQueue() {\n while (\n this._pending.size < this._maxPending &&\n this._pendingQueue.length > 0\n ) {\n const item: any = this._pendingQueue.shift();\n const { payloadBase, id, resolve, reject, timer } = item;\n // ensure token valid or attempt refresh\n if (this.tokenExpiry && Date.now() >= this.tokenExpiry) {\n const refreshed = await this._maybeRefreshToken();\n if (!refreshed) {\n clearTimeout(timer);\n try {\n reject(new Error(\"Token expired and refresh failed\"));\n } catch (e) { }\n continue;\n }\n }\n\n // build final buffer at send time so token is fresh and we don't store tokens in queue\n let buf;\n try {\n buf = this._buildFinalBuffer(payloadBase, id);\n } catch (e) {\n clearTimeout(timer);\n try {\n reject(e);\n } catch (er) { }\n continue;\n }\n\n // register pending before writing so that responses arriving quickly are handled\n this._pending.set(id, { resolve, reject, timer });\n // write with backpressure\n try {\n await this._write(buf);\n } catch (e) {\n clearTimeout(timer);\n this._pending.delete(id);\n try {\n reject(e);\n } catch (er) { }\n }\n }\n }\n\n /**\n * Execute a command. Supports concurrent requests via request id mapping.\n * Returns a Promise resolved with response.data or rejected on ERROR/timeout.\n */\n async execute(payload:Message) {\n // wait until authenticated\n try {\n await this.ready;\n } catch (err: any) {\n throw new Error(\n \"Not authenticated: \" + (err && err.message ? err.message : err)\n );\n }\n\n if (!this.token) throw new Error(\"Not authenticated\");\n\n const id = this._nextId++;\n\n // payloadBase stored in queue; final buffer will be built at send time\n const payloadBase: PayloadOptions = { action: payload.action, data: payload.data };\n\n // if token expired, try refresh before proceeding\n if (this.tokenExpiry && Date.now() >= this.tokenExpiry) {\n const refreshed = await this._maybeRefreshToken();\n if (!refreshed) throw new Error(\"Token expired\");\n }\n\n return new Promise((resolve, reject) => {\n // create request timer only if requestTimeout > 0\n let timer: any = null;\n if (this.requestTimeout > 0) {\n timer = setTimeout(() => {\n if (this._pending.has(id)) {\n this._pending.delete(id);\n reject(new Error(\"Request timeout\"));\n }\n }, this.requestTimeout);\n }\n\n // if too many pending, queue this request\n if (this._pending.size >= this._maxPending) {\n if (this._pendingQueue.length >= this._maxQueue) {\n if (timer) clearTimeout(timer);\n return reject(new Error(\"Pending queue full\"));\n }\n // enqueue payload base so we don't store tokens in the queue\n this._pendingQueue.push({ payloadBase, id, resolve, reject, timer });\n // try to process queue (async)\n this._processQueue().catch(() => { });\n return;\n }\n\n // build final buffer now using current token\n let finalBuf;\n try {\n finalBuf = this._buildFinalBuffer(payloadBase, id);\n } catch (e) {\n clearTimeout(timer);\n return reject(e);\n }\n\n this._pending.set(id, { resolve, reject, timer });\n // write with backpressure handling\n this._write(finalBuf).catch((e) => {\n if (timer) clearTimeout(timer);\n this._pending.delete(id);\n reject(e);\n });\n });\n }\n /**\n * Attempt to refresh token using provided tokenRefresh option if token expired.\n * options.tokenRefresh should be async function that returns { token, expiresAt }\n */\n async _maybeRefreshToken() {\n if (\n !this.options.tokenRefresh ||\n typeof this.options.tokenRefresh !== \"function\"\n )\n return false;\n try {\n const res = await this.options.tokenRefresh();\n if (res && res.token) {\n this.token = res.token;\n if (res.expiresAt) this.tokenExpiry = res.expiresAt;\n return true;\n }\n } catch (e) {\n this.logger?.error?.(\n \"Token refresh failed\",\n e && (e as Error).message ? (e as Error).message : String(e)\n );\n }\n return false;\n }\n\n destroy() {\n this._destroyed = true;\n if (this._reconnectTimer) {\n clearTimeout(this._reconnectTimer);\n this._reconnectTimer = null;\n }\n // reject ready and clear queues/pending\n this._rejectReady(new Error(\"Client destroyed\"));\n this._pending.forEach((pending, id) => {\n if (pending.timer) clearTimeout(pending.timer);\n try {\n pending.reject(new Error(\"Client destroyed\"));\n } catch (e: any) { }\n this._pending.delete(id);\n });\n this._pendingQueue = [];\n try {\n if (this.client) this.client.destroy();\n } catch (e: any) { }\n this.client = null;\n }\n\n _handleDisconnect(err: any) {\n // Prevent handling disconnect multiple times\n if (!this._connected && !this._authenticating) {\n return;\n }\n \n // Check if we're disconnecting during authentication - likely an AUTH FAIL\n const wasAuthenticating = this._authenticating;\n \n // cleanup pending requests\n this._pending.forEach((pending, id) => {\n if (pending.timer) clearTimeout(pending.timer);\n \n // Defer rejection to next tick to allow outer promise chain to catch it\n const errorMsg = wasAuthenticating \n ? \"Authentication failed - credentials may be required\"\n : (err && err.message ? err.message : \"Disconnected\");\n \n process.nextTick(() => {\n try {\n // Create Error here to avoid Bun logging it immediately\n pending.reject(new Error(errorMsg));\n } catch (e: any) { \n // Ignore - rejection already handled\n }\n });\n \n this._pending.delete(id);\n });\n\n this._connected = false;\n // allow new connect() calls to create a fresh connection\n this._connecting = null;\n // reset authenticating state so future connect/auth attempts are clean\n this._authenticating = false;\n\n // DON'T reconnect on auth failure when retries is 0\n if (wasAuthenticating && this.retries === 0) {\n const rejectErr = err || new Error(\"Authentication failed and no retries configured\");\n try {\n this._rejectReady(rejectErr);\n } catch (e: any) { }\n return;\n }\n\n // try reconnect\n if (this._currentRetries < this.retries) {\n // create a fresh ready promise for the reconnect attempt\n this._createReady();\n // add jitter to avoid thundering herd\n const base = Math.min(\n this.retryDelay * Math.pow(2, this._currentRetries),\n 30000\n );\n const jitter = Math.floor(Math.random() * Math.min(1000, base));\n const delay = base + jitter;\n this._currentRetries += 1;\n this.logger?.info?.(\n \"Attempting reconnect in \" +\n delay +\n \"ms (attempt \" +\n this._currentRetries +\n \")\"\n );\n // clear token/state before reconnect attempt\n this.token = null;\n setTimeout(() => {\n // clear any lingering pending queue when reconnecting to fresh state\n // we keep queued requests but they will be reprocessed after connect\n this.connect().catch((e: any) => {\n this.logger?.error?.(\"Reconnect failed\", e && e.message ? e.message : e);\n });\n }, delay);\n } else {\n // give up\n try {\n this._rejectReady(err || new Error(\"Disconnected and no retries left\"));\n } catch (e: any) { }\n }\n }\n\n close() {\n if (!this.client) return;\n try {\n this.client.removeAllListeners(\"data\");\n this.client.removeAllListeners(\"error\");\n this.client.removeAllListeners(\"close\");\n this.client.end();\n } catch (e: any) { }\n this.client = null;\n }\n\n /**\n * Disconnect (alias for close)\n */\n disconnect() {\n this.close();\n }\n\n /**\n * Send request helper (for public API methods)\n */\n async sendRequest(action: Action, data: any = {}): Promise<any> {\n return this.execute({ action, data });\n }\n\n // ========== Public API Methods ==========\n\n /**\n * Login with username and password\n */\n async login(username: string, password: string): Promise<any> {\n return this.sendRequest('login', { username, password });\n }\n\n /**\n * Logout from server\n */\n async logout(): Promise<any> {\n return this.sendRequest('logout', {});\n }\n\n /**\n * List all databases\n */\n async listDatabases(): Promise<any> {\n return this.sendRequest('list-dbs', {});\n }\n\n /**\n * Create a new database\n */\n async createDatabase(name: string): Promise<any> {\n return this.sendRequest('create-db', { databaseName: name });\n }\n\n /**\n * Remove a database\n */\n async removeDatabase(name: string): Promise<any> {\n return this.sendRequest('remove-db', { databaseName: name });\n }\n\n /**\n * Rename a database\n */\n async renameDatabase(oldName: string, newName: string): Promise<any> {\n return this.sendRequest('rename-db', { databaseName: oldName, newName });\n }\n\n /**\n * Execute code in a database\n */\n async run(code: string, databaseName: string): Promise<any> {\n return this.sendRequest('script-code', { code, databaseName });\n }\n\n /**\n * Save a database to disk\n */\n async saveDatabase(databaseName: string): Promise<any> {\n return this.sendRequest('save-db', { databaseName });\n }\n\n /**\n * Update database metadata\n */\n async updateDatabase(databaseName: string, data: any): Promise<any> {\n return this.sendRequest('update-db', { databaseName, ...data });\n }\n\n /**\n * Get server information\n */\n async getInfo(): Promise<any> {\n return this.sendRequest('get-info', {});\n }\n\n /**\n * Execute shell command on server\n */\n async executeShell(command: string): Promise<{ stdout: string; stderr: string }> {\n return this.sendRequest('shell-command', { command });\n }\n}\n\nexport default ScriptDBClient;\n"],"mappings":"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","names":["idx"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import * as net from \"net\";\nimport * as tls from \"tls\";\nimport { URL } from \"url\";\nimport * as crypto from \"crypto\";\n\ntype Action = 'script-code' | 'save-db' | 'remove-db' | 'rename-db' | 'login' | 'logout' | 'get-info' | 'list-dbs' | 'create-db' | 'update-db' | 'get-db' | 'shell-command' | 'string';\n\ninterface DataOptions {\n code?: string | any;\n databaseName?: string | any;\n token?: string | any;\n username?: string | any;\n password?: string | any;\n newName?: string | any;\n}\n\ninterface PayloadOptions {\n id?: number;\n action?: Action;\n data?: DataOptions;\n}\n// Type definitions\ninterface Logger {\n debug?: (...args: any[]) => void;\n info?: (...args: any[]) => void;\n warn?: (...args: any[]) => void;\n error?: (...args: any[]) => void;\n}\n\ninterface ClientOptions {\n secure?: boolean;\n logger?: Logger;\n requestTimeout?: number;\n socketTimeout?: number;\n retries?: number;\n retryDelay?: number;\n tlsOptions?: tls.TlsOptions;\n frame?: 'ndjson' | 'length-prefix';\n preferLengthPrefix?: boolean;\n maxPending?: number;\n maxQueue?: number;\n maxMessageSize?: number;\n signing?: {\n secret: string;\n algorithm?: string;\n };\n stringify?: (obj: any) => string;\n username?: string;\n password?: string;\n tokenRefresh?: () => Promise<{ token: string; expiresAt?: number }>;\n}\n\ninterface PendingRequest {\n resolve: (value: any) => void;\n reject: (error: Error) => void;\n timer: NodeJS.Timeout | null;\n}\n\ninterface QueuedRequest extends PendingRequest {\n payloadBase: PayloadOptions;\n id: number;\n}\n\ninterface Message {\n id?: number;\n action?: Action;\n command?: string;\n message?: string;\n data?: DataOptions;\n token?: string;\n signature?: string;\n payload?: any;\n}\n\n// Minimal no-op logger\nconst noopLogger = {\n debug: () => { },\n info: () => { },\n warn: () => { },\n error: () => { },\n};\n\nexport class ScriptDBClient {\n // Properties\n private options: ClientOptions;\n private socketTimeout: number = 0;\n private maxMessageSize: number = 0;\n private _mask: (obj: any) => any = () => { };\n private _maskArgs: (args: any[]) => any[] = () => [];\n private logger?: Logger = {};\n private secure: boolean = true;\n private requestTimeout: number = 0;\n private retries: number = 0;\n private retryDelay: number = 0;\n private frame: 'ndjson' | 'length-prefix' = 'ndjson';\n private uri: string = '';\n private protocolName: string = '';\n private username: string | null = null;\n private password: string | null = null;\n private host: string = '';\n private port: number = 0;\n private database: string | null = null;\n private client: net.Socket | tls.TLSSocket | null = null;\n private buffer: Buffer = Buffer.alloc(0);\n private _nextId: number = 1;\n private _pending: Map<number, PendingRequest> = new Map();\n private _maxPending: number = 0;\n private _maxQueue: number = 0;\n private _pendingQueue: QueuedRequest[] = [];\n private _connected: boolean = false;\n private _authenticating: boolean = false;\n private token: string | null = null;\n private _currentRetries: number = 0;\n private tokenExpiry: number | null = null;\n private _destroyed: boolean = false;\n private _reconnectTimer: NodeJS.Timeout | null = null;\n private signing: { secret: string; algorithm?: string } | null = null;\n private _stringify: (obj: any) => string = JSON.stringify;\n private ready: Promise<any> = Promise.resolve();\n private _resolveReadyFn: ((value: any) => void) | null = null;\n private _rejectReadyFn: ((err: Error) => void) | null = null;\n private _connecting: Promise<any> | null = null;\n private _authPendingId: number | null = null;\n\n /**\n * Create a new client. Do NOT auto-connect in constructor — call connect()\n * @param uri - Connection URI\n * @param options - Client options\n * @param options.secure - use TLS\n * @param options.logger - { debug, info, warn, error }\n * @param options.requestTimeout - Request timeout in ms\n * @param options.retries - Reconnection retries\n * @param options.retryDelay - Initial retry delay in ms\n * @param options.tlsOptions - Passed to tls.connect when secure\n */\n constructor(uri: string, options: ClientOptions = {}) {\n if (!uri || typeof uri !== \"string\") throw new Error(\"uri required\");\n this.options = Object.assign({}, options);\n // sensible default socket timeout (ms). 0 = disabled (no socket timeout)\n this.socketTimeout = Number.isFinite(this.options.socketTimeout)\n ? this.options.socketTimeout!\n : 0;\n // sensible default max message size (bytes)\n this.maxMessageSize = Number.isFinite(this.options.maxMessageSize)\n ? this.options.maxMessageSize!\n : 5 * 1024 * 1024; // 5MB\n\n // masking helper (used to hide tokens/passwords from logs)\n this._mask = (obj) => {\n try {\n if (!obj || typeof obj !== \"object\") return obj;\n const copy = Array.isArray(obj) ? obj.slice() : Object.assign({}, obj);\n if (copy.token) copy.token = \"****\";\n if (copy.password) copy.password = \"****\";\n if (copy.data && copy.data.password) copy.data.password = \"****\";\n return copy;\n } catch (e) {\n return obj;\n }\n };\n\n // helper to mask any arguments passed to logger methods\n const rawLogger =\n this.options.logger && typeof this.options.logger === \"object\"\n ? this.options.logger\n : noopLogger;\n this._maskArgs = (args) => {\n return args.map((a) => {\n if (!a) return a;\n if (typeof a === \"string\") return a;\n return this._mask(a);\n });\n };\n\n // wrapper logger that masks sensitive fields in objects before delegating\n this.logger = {\n debug: (...args) =>\n rawLogger.debug && rawLogger.debug(...this._maskArgs(args)),\n info: (...args) =>\n rawLogger.info && rawLogger.info(...this._maskArgs(args)),\n warn: (...args) =>\n rawLogger.warn && rawLogger.warn(...this._maskArgs(args)),\n error: (...args) =>\n rawLogger.error && rawLogger.error(...this._maskArgs(args)),\n };\n // secure by default; warn if user explicitly disables secure\n this.secure =\n typeof this.options.secure === \"boolean\" ? !!this.options.secure : true;\n if (!this.secure)\n this.logger.warn?.(\n \"Warning: connecting in insecure mode (secure=false). This is not recommended.\"\n );\n // By default do not set a per-request timeout (0 = disabled).\n this.requestTimeout = Number.isFinite(this.options.requestTimeout)\n ? this.options.requestTimeout!\n : 0;\n this.retries = Number.isFinite(this.options.retries)\n ? this.options.retries!\n : 3;\n this.retryDelay = Number.isFinite(this.options.retryDelay)\n ? this.options.retryDelay!\n : 1000;\n // framing: 'ndjson' (default) or 'length-prefix'. If the caller prefers higher throughput\n // they can set options.preferLengthPrefix = true or options.frame = 'length-prefix'.\n this.frame =\n this.options.frame === \"length-prefix\" || this.options.preferLengthPrefix\n ? \"length-prefix\"\n : \"ndjson\";\n\n // Validate and parse URI - only accept scriptdb:// protocol\n let parsed;\n try {\n parsed = new URL(uri);\n } catch (e) {\n throw new Error(\"Invalid uri\");\n }\n\n // Validate protocol\n if (parsed.protocol !== \"scriptdb:\") {\n throw new Error(\"URI must use scriptdb:// protocol\");\n }\n\n this.uri = uri;\n this.protocolName = parsed.protocol\n ? parsed.protocol.replace(\":\", \"\")\n : \"scriptdb\";\n // prefer explicit credentials passed in options over credentials embedded in the URI\n this.username =\n (typeof this.options.username === \"string\"\n ? this.options.username\n : parsed.username) || null;\n this.password =\n (typeof this.options.password === \"string\"\n ? this.options.password\n : parsed.password) || null;\n if (parsed.username && !(typeof this.options.username === \"string\")) {\n this.logger.warn?.(\n \"Credentials found in URI — consider passing credentials via options instead of embedding in URI\"\n );\n }\n // do not keep credentials in the stored URI representation\n try {\n parsed.username = \"\";\n parsed.password = \"\";\n this.uri = parsed.toString();\n } catch (e) {\n // fallback to original uri\n this.uri = uri;\n }\n this.host = parsed.hostname || \"localhost\";\n this.port = parsed.port ? parseInt(parsed.port, 10) : 1234;\n this.database =\n parsed.pathname && parsed.pathname.length > 1\n ? parsed.pathname.slice(1)\n : null;\n\n // internal state\n this.client = null;\n this.buffer = Buffer.alloc(0);\n this._nextId = 1; // request id generator\n this._pending = new Map(); // id -> {resolve,reject,timer}\n this._maxPending = Number.isFinite(this.options.maxPending)\n ? this.options.maxPending!\n : 100;\n this._maxQueue = Number.isFinite(this.options.maxQueue)\n ? this.options.maxQueue!\n : 1000;\n this._pendingQueue = []; // queued requests when pending >= max\n this._connected = false;\n this._authenticating = false;\n this.token = null;\n this._currentRetries = 0;\n this.tokenExpiry = null; // ms timestamp when token expires\n this._destroyed = false;\n this._reconnectTimer = null;\n\n // signing options: { secret: '...', algorithm: 'sha256' }\n this.signing =\n this.options.signing && this.options.signing.secret\n ? this.options.signing\n : null;\n\n // fast stringify support: allow user to pass a custom stringify function (e.g. fast-json-stringify)\n this._stringify =\n typeof this.options.stringify === \"function\"\n ? this.options.stringify\n : JSON.stringify;\n\n // ready promise lifecycle managed by helpers to avoid race conditions\n this._createReady();\n }\n\n _createReady() {\n this.ready = new Promise((resolve, reject) => {\n this._resolveReadyFn = resolve;\n this._rejectReadyFn = reject;\n });\n }\n\n _resolveReady(value: any) {\n if (this._resolveReadyFn) {\n try {\n this._resolveReadyFn(value);\n } catch (e) { }\n this._resolveReadyFn = null;\n this._rejectReadyFn = null;\n }\n }\n\n _rejectReady(err: Error) {\n if (this._rejectReadyFn) {\n // Use process.nextTick to defer the rejection, preventing unhandled errors\n // when called from event handlers\n const rejectFn = this._rejectReadyFn;\n this._resolveReadyFn = null;\n this._rejectReadyFn = null;\n\n process.nextTick(() => {\n try {\n rejectFn(err);\n } catch (e) {\n // Silently ignore - promise already rejected\n }\n });\n }\n }\n\n /**\n * Check if connected\n */\n get connected(): boolean {\n return this._connected;\n }\n\n /**\n * Connect to server and authenticate. Returns a Promise that resolves when authenticated.\n */\n connect() {\n // avoid double connect\n if (this._connecting) return this._connecting;\n\n this._connecting = new Promise((resolve, reject) => {\n const opts = { host: this.host, port: this.port };\n const onConnect = () => {\n console.log(\"ScriptDBClient: Connected to server at\", opts.host, opts.port);\n this.logger?.info?.(\"Connected to server\");\n this._connected = true;\n this._currentRetries = 0;\n console.log(\"ScriptDBClient: Setting up listeners...\");\n this._setupListeners();\n console.log(\"ScriptDBClient: Authenticating...\");\n this.authenticate()\n .then(() => {\n // reset pending queue processing after auth\n this._processQueue();\n resolve(this);\n })\n .catch((err) => {\n reject(err);\n });\n };\n\n try {\n if (this.secure) {\n // Create a separate object for host and port to avoid type conflicts\n const connectionOpts = { host: opts.host, port: opts.port };\n const tlsOptions: any = Object.assign(\n {},\n this.options.tlsOptions || {},\n connectionOpts\n );\n // safe default\n if (typeof tlsOptions.rejectUnauthorized === \"undefined\")\n tlsOptions.rejectUnauthorized = true;\n this.client = tls.connect(tlsOptions as tls.ConnectionOptions, onConnect);\n } else {\n this.client = net.createConnection(opts, onConnect);\n }\n } catch (e) {\n const error = e as Error;\n this.logger?.error?.(\"Connection failed\", error.message);\n // reject ready if present and clear handlers\n this._rejectReady(error);\n // make sure ready is recreated on next attempt\n this._createReady();\n // allow future connect attempts\n this._connecting = null;\n return reject(error);\n }\n\n // Guard against client not being set (shouldn't happen, but TypeScript needs it)\n if (!this.client) {\n const error = new Error(\"Failed to create client socket\");\n this.logger?.error?.(\"Connection failed\", error.message);\n this._connecting = null;\n return reject(error);\n }\n\n // attach top-level handlers for errors/close to trigger reconnect logic\n const onError = (err: Error) => {\n this.logger?.error?.(\n \"Client socket error:\",\n err && err.message ? err.message : err\n );\n this._handleDisconnect(err);\n };\n const onClose = (hadError: boolean) => {\n this.logger?.info?.(\"Server closed connection\");\n // Don't pass error to avoid double error throwing\n this._handleDisconnect(null);\n };\n this.client.on(\"error\", onError);\n this.client.on(\"close\", onClose);\n // socket timeouts\n if (this.socketTimeout > 0 && this.client) {\n this.client.setTimeout(this.socketTimeout);\n this.client.on(\"timeout\", () => {\n this.logger?.warn?.(\"Socket timeout, destroying connection\");\n try {\n this.client?.destroy();\n } catch (e) { }\n });\n }\n }).catch((err) => {\n // Ensure errors are properly propagated without additional throwing\n this._connecting = null;\n throw err;\n });\n\n return this._connecting;\n }\n\n _setupListeners() {\n if (!this.client) return;\n console.log(\"ScriptDBClient _setupListeners: called, client exists:\", !!this.client);\n // clear any previous data listeners and reset buffer\n this.client.removeAllListeners(\"data\");\n this.buffer = Buffer.alloc(0);\n\n console.log(\"ScriptDBClient _setupListeners: frame mode:\", this.frame);\n\n // Parser depends on framing\n if (this.frame === \"length-prefix\") {\n // length-prefixed framing: [uint32BE length][payload]\n this.client.on(\"data\", (chunk) => {\n if (!Buffer.isBuffer(chunk)) {\n try {\n chunk = Buffer.from(chunk);\n } catch (e) {\n return;\n }\n }\n // fast path: append and scan (we keep concat here for simplicity)\n this.buffer = Buffer.concat([this.buffer, chunk]);\n while (this.buffer.length >= 4) {\n const len = this.buffer.readUInt32BE(0);\n // enforce max message/frame size\n if (len > this.maxMessageSize) {\n this.logger?.error?.(\n \"Incoming length-prefixed frame exceeds maxMessageSize — closing connection\"\n );\n try {\n this.client?.destroy();\n } catch (e) { }\n return;\n }\n if (this.buffer.length < 4 + len) break;\n const payload = this.buffer.slice(4, 4 + len);\n this.buffer = this.buffer.slice(4 + len);\n let msg;\n try {\n msg = JSON.parse(payload.toString(\"utf8\"));\n } catch (e) {\n this.logger?.error?.(\n \"Invalid JSON frame\",\n e && (e as Error).message ? (e as Error).message : e\n );\n continue;\n }\n // validate schema\n if (!msg || typeof msg !== \"object\") continue;\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\") &&\n (typeof msg.data === \"object\" ||\n typeof msg.data === \"undefined\" ||\n msg.data === null);\n if (!validSchema) {\n this.logger?.warn?.(\"Message failed schema validation — ignoring\");\n continue;\n }\n this._handleMessage(msg);\n }\n });\n } else {\n // Buffer-aware NDJSON parser: avoid repeated string concatenation\n console.log(\"ScriptDBClient _setupListeners: Setting up NDJSON data listener\");\n this.client.on(\"data\", (chunk) => {\n console.log(\"ScriptDBClient: Received data chunk, length:\", chunk.length);\n if (!Buffer.isBuffer(chunk)) {\n try {\n chunk = Buffer.from(chunk);\n } catch (e) {\n return;\n }\n }\n\n // If buffer is empty and chunk contains no trailing partial line, avoid concat\n const idxLastNewline = chunk.indexOf(0x0a);\n if (this.buffer.length === 0 && idxLastNewline === chunk.length - 1) {\n // chunk ends with newline and no previous partial: process in-place\n let start = 0;\n let idx;\n while ((idx = chunk.indexOf(0x0a, start)) !== -1) {\n const lineBuf = chunk.slice(start, idx);\n start = idx + 1;\n if (lineBuf.length === 0) continue;\n let msg;\n try {\n msg = JSON.parse(lineBuf.toString(\"utf8\"));\n } catch (e: any) {\n this.logger?.error?.(\n \"Invalid JSON from server\",\n e && e.message ? e.message : e\n );\n continue;\n }\n // schema check\n if (!msg || typeof msg !== \"object\") continue;\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\");\n if (!validSchema) continue;\n this._handleMessage(msg);\n }\n return;\n }\n\n // fallback: append chunk to buffer (infrequent), then scan\n this.buffer = Buffer.concat([this.buffer, chunk]);\n\n // enforce max message size\n // enforce max message size using configured value\n if (this.buffer.length > this.maxMessageSize) {\n this.logger?.error?.(\n \"Incoming message exceeds maxMessageSize — closing connection\"\n );\n try {\n this.client?.destroy();\n } catch (e) { }\n return;\n }\n\n let idx;\n while ((idx = this.buffer.indexOf(0x0a)) !== -1) {\n const lineBuf = this.buffer.slice(0, idx);\n this.buffer = this.buffer.slice(idx + 1);\n if (lineBuf.length === 0) continue;\n let msg;\n try {\n msg = JSON.parse(lineBuf.toString(\"utf8\"));\n } catch (e: any) {\n this.logger?.error?.(\n \"Invalid JSON from server\",\n e && (e as Error).message ? (e as Error).message : e\n );\n continue;\n }\n\n const validSchema =\n (typeof msg.id === \"undefined\" || typeof msg.id === \"number\") &&\n (typeof msg.action === \"string\" ||\n typeof msg.action === \"undefined\") &&\n (typeof msg.command === \"string\" ||\n typeof msg.command === \"undefined\") &&\n (typeof msg.message === \"string\" ||\n typeof msg.message === \"undefined\");\n if (!validSchema) {\n this.logger?.warn?.(\"Message failed schema validation — ignoring\");\n continue;\n }\n\n this._handleMessage(msg);\n }\n });\n }\n }\n\n // build the final buffer for sending using current token and signing settings\n _buildFinalBuffer(payloadBase: Message, id: number) {\n // payloadBase is { action, data }\n const payloadObj: Message = Object.assign(\n { id, action: payloadBase.action },\n payloadBase.data !== undefined ? { data: payloadBase.data } : {}\n );\n // attach current token at send time\n if (this.token) payloadObj.token = this.token;\n\n const payloadStr = this._stringify(payloadObj);\n\n if (this.signing && this.signing.secret) {\n const hmac = crypto.createHmac(\n this.signing.algorithm || \"sha256\",\n this.signing.secret\n );\n hmac.update(payloadStr);\n const sig = hmac.digest(\"hex\");\n const envelope = { id, signature: sig, payload: payloadObj };\n const envelopeStr = this._stringify(envelope);\n if (this.frame === \"length-prefix\") {\n const body = Buffer.from(envelopeStr, \"utf8\");\n const buf = Buffer.allocUnsafe(4 + body.length);\n buf.writeUInt32BE(body.length, 0);\n body.copy(buf, 4);\n return buf;\n }\n return Buffer.from(envelopeStr + \"\\n\", \"utf8\");\n }\n\n // no signing\n if (this.frame === \"length-prefix\") {\n const body = Buffer.from(payloadStr, \"utf8\");\n const buf = Buffer.allocUnsafe(4 + body.length);\n buf.writeUInt32BE(body.length, 0);\n body.copy(buf, 4);\n return buf;\n }\n return Buffer.from(payloadStr + \"\\n\", \"utf8\");\n }\n\n _handleMessage(msg: Message) {\n console.log('ScriptDBClient _handleMessage:', JSON.stringify(msg));\n console.log('ScriptDBClient _handleMessage msg.id:', msg.id, 'msg.action:', msg.action, 'msg.command:', (msg as any).command, 'msg.message:', msg.message);\n\n // message with id for request/response mapping (check this FIRST)\n if (msg && typeof msg.id !== \"undefined\") {\n console.log('Handling message with id:', msg.id, 'action:', msg.action, 'message:', msg.message);\n const pending = this._pending.get(msg.id);\n if (!pending) {\n console.log('No pending request for id', msg.id, 'pending map size:', this._pending.size);\n this.logger?.debug?.(\"No pending request for id\", msg.id);\n return;\n }\n const { resolve, reject, timer } = pending;\n if (timer) clearTimeout(timer);\n this._pending.delete(msg.id);\n // process next queued request if any\n this._processQueue();\n\n // Handle login responses with id\n if (msg.action === \"login\" || msg.command === \"login\") {\n console.log('Processing login response with id');\n if (msg.message === \"AUTH OK\") {\n console.log('AUTH OK - setting token and resolving');\n this.token = msg.data && msg.data.token ? msg.data.token : null;\n this._resolveReady(null);\n return resolve(msg.data);\n } else {\n console.log('AUTH FAILED:', msg.data);\n this._rejectReady(new Error(\"Authentication failed\"));\n const errorMsg = msg.data || \"Authentication failed\";\n // Close the connection after receiving AUTH FAIL\n try {\n this.client?.end();\n } catch (e) { }\n return reject(new Error(typeof errorMsg === 'string' ? errorMsg : \"Authentication failed\"));\n }\n }\n\n if ((msg.action === \"script-code\" || msg.command === \"script-code\") && msg.message === \"OK\")\n return resolve(msg.data);\n if ((msg.action === \"script-code\" || msg.command === \"script-code\") && msg.message === \"ERROR\")\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Server returned ERROR\"));\n\n // Handle create-db responses\n if (msg.action === \"create-db\" && msg.message === \"SUCCESS\")\n return resolve(msg.data);\n if (msg.action === \"create-db\" && msg.message === \"ERROR\")\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Failed to create database\"));\n\n // Default: resolve for OK/SUCCESS, reject for ERROR\n if (msg.message === \"OK\" || msg.message === \"SUCCESS\") {\n return resolve(msg.data);\n } else if (msg.message === \"ERROR\") {\n return reject(new Error(typeof msg.data === 'string' ? msg.data : \"Request failed\"));\n }\n\n return reject(new Error(\"Invalid response from server\"));\n }\n\n // otherwise, unhandled message\n console.log('Unhandled message:', msg);\n this.logger?.debug?.(\"Unhandled message from server\", this._mask(msg));\n }\n\n authenticate() {\n if (this._authenticating)\n return Promise.reject(new Error(\"Already authenticating\"));\n this._authenticating = true;\n\n return new Promise((resolve, reject) => {\n const id = this._nextId++;\n const payload: Message = {\n id,\n action: \"login\",\n data: { username: this.username, password: this.password },\n };\n\n // create a timer only when requestTimeout is enabled (>0)\n let timer: any = null;\n if (this.requestTimeout > 0) {\n timer = setTimeout(() => {\n this._pending.delete(id);\n this._authenticating = false;\n reject(new Error(\"Auth timeout\"));\n this.close();\n }, this.requestTimeout);\n }\n\n this._pending.set(id, {\n resolve: (data: any) => {\n if (timer) clearTimeout(timer);\n this._authenticating = false;\n // server may still send a login message; set token if present\n if (data && (data as any).token) this.token = (data as any).token;\n resolve(data);\n },\n reject: (err: any) => {\n if (timer) clearTimeout(timer);\n this._authenticating = false;\n reject(err);\n },\n timer,\n });\n\n try {\n // use _write to respect backpressure\n const buf = Buffer.from(JSON.stringify(payload) + \"\\n\", \"utf8\");\n this._write(buf).catch((err: any) => {\n if (timer) clearTimeout(timer);\n this._pending.delete(id);\n this._authenticating = false;\n reject(err);\n });\n } catch (e: any) {\n clearTimeout(timer);\n this._pending.delete(id);\n this._authenticating = false;\n reject(e);\n }\n })\n .then((data: any) => {\n // mark ready if token present\n if (data && (data as any).token) {\n this.token = (data as any).token;\n this._resolveReady(null);\n }\n return data;\n })\n .catch((err: any) => {\n this._rejectReady(err);\n throw err;\n });\n }\n\n // internal write helper that respects backpressure\n _write(buf: any) {\n return new Promise((resolve, reject) => {\n if (!this.client || !this._connected)\n return reject(new Error(\"Not connected\"));\n try {\n const ok = this.client.write(buf, (err) => {\n if (err) return reject(err);\n resolve(undefined);\n });\n if (!ok) {\n // wait for drain\n this.client.once(\"drain\", () => resolve(undefined));\n }\n // if ok was true, the callback above resolves\n } catch (e) {\n reject(e);\n }\n });\n }\n\n async _processQueue() {\n while (\n this._pending.size < this._maxPending &&\n this._pendingQueue.length > 0\n ) {\n const item: any = this._pendingQueue.shift();\n const { payloadBase, id, resolve, reject, timer } = item;\n // ensure token valid or attempt refresh\n if (this.tokenExpiry && Date.now() >= this.tokenExpiry) {\n const refreshed = await this._maybeRefreshToken();\n if (!refreshed) {\n clearTimeout(timer);\n try {\n reject(new Error(\"Token expired and refresh failed\"));\n } catch (e) { }\n continue;\n }\n }\n\n // build final buffer at send time so token is fresh and we don't store tokens in queue\n let buf;\n try {\n buf = this._buildFinalBuffer(payloadBase, id);\n } catch (e) {\n clearTimeout(timer);\n try {\n reject(e);\n } catch (er) { }\n continue;\n }\n\n // register pending before writing so that responses arriving quickly are handled\n this._pending.set(id, { resolve, reject, timer });\n // write with backpressure\n try {\n await this._write(buf);\n } catch (e) {\n clearTimeout(timer);\n this._pending.delete(id);\n try {\n reject(e);\n } catch (er) { }\n }\n }\n }\n\n /**\n * Execute a command. Supports concurrent requests via request id mapping.\n * Returns a Promise resolved with response.data or rejected on ERROR/timeout.\n */\n async execute(payload: Message) {\n // wait until authenticated\n try {\n await this.ready;\n } catch (err: any) {\n throw new Error(\n \"Not authenticated: \" + (err && err.message ? err.message : err)\n );\n }\n\n if (!this.token) throw new Error(\"Not authenticated\");\n\n const id = this._nextId++;\n\n // payloadBase stored in queue; final buffer will be built at send time\n const payloadBase: PayloadOptions = { action: payload.action, data: payload.data };\n\n // if token expired, try refresh before proceeding\n if (this.tokenExpiry && Date.now() >= this.tokenExpiry) {\n const refreshed = await this._maybeRefreshToken();\n if (!refreshed) throw new Error(\"Token expired\");\n }\n\n return new Promise((resolve, reject) => {\n // create request timer only if requestTimeout > 0\n let timer: any = null;\n if (this.requestTimeout > 0) {\n timer = setTimeout(() => {\n if (this._pending.has(id)) {\n this._pending.delete(id);\n reject(new Error(\"Request timeout\"));\n }\n }, this.requestTimeout);\n }\n\n // if too many pending, queue this request\n if (this._pending.size >= this._maxPending) {\n if (this._pendingQueue.length >= this._maxQueue) {\n if (timer) clearTimeout(timer);\n return reject(new Error(\"Pending queue full\"));\n }\n // enqueue payload base so we don't store tokens in the queue\n this._pendingQueue.push({ payloadBase, id, resolve, reject, timer });\n // try to process queue (async)\n this._processQueue().catch(() => { });\n return;\n }\n\n // build final buffer now using current token\n let finalBuf;\n try {\n finalBuf = this._buildFinalBuffer(payloadBase, id);\n } catch (e) {\n clearTimeout(timer);\n return reject(e);\n }\n\n this._pending.set(id, { resolve, reject, timer });\n // write with backpressure handling\n this._write(finalBuf).catch((e) => {\n if (timer) clearTimeout(timer);\n this._pending.delete(id);\n reject(e);\n });\n });\n }\n /**\n * Attempt to refresh token using provided tokenRefresh option if token expired.\n * options.tokenRefresh should be async function that returns { token, expiresAt }\n */\n async _maybeRefreshToken() {\n if (\n !this.options.tokenRefresh ||\n typeof this.options.tokenRefresh !== \"function\"\n )\n return false;\n try {\n const res = await this.options.tokenRefresh();\n if (res && res.token) {\n this.token = res.token;\n if (res.expiresAt) this.tokenExpiry = res.expiresAt;\n return true;\n }\n } catch (e) {\n this.logger?.error?.(\n \"Token refresh failed\",\n e && (e as Error).message ? (e as Error).message : String(e)\n );\n }\n return false;\n }\n\n destroy() {\n this._destroyed = true;\n if (this._reconnectTimer) {\n clearTimeout(this._reconnectTimer);\n this._reconnectTimer = null;\n }\n // reject ready and clear queues/pending\n this._rejectReady(new Error(\"Client destroyed\"));\n this._pending.forEach((pending, id) => {\n if (pending.timer) clearTimeout(pending.timer);\n try {\n pending.reject(new Error(\"Client destroyed\"));\n } catch (e: any) { }\n this._pending.delete(id);\n });\n this._pendingQueue = [];\n try {\n if (this.client) this.client.destroy();\n } catch (e: any) { }\n this.client = null;\n }\n\n _handleDisconnect(err: any) {\n // Prevent handling disconnect multiple times\n if (!this._connected && !this._authenticating) {\n return;\n }\n\n // Check if we're disconnecting during authentication - likely an AUTH FAIL\n const wasAuthenticating = this._authenticating;\n\n // cleanup pending requests\n this._pending.forEach((pending, id) => {\n if (pending.timer) clearTimeout(pending.timer);\n\n // Defer rejection to next tick to allow outer promise chain to catch it\n const errorMsg = wasAuthenticating\n ? \"Authentication failed - credentials may be required\"\n : (err && err.message ? err.message : \"Disconnected\");\n\n process.nextTick(() => {\n try {\n // Create Error here to avoid Bun logging it immediately\n pending.reject(new Error(errorMsg));\n } catch (e: any) {\n // Ignore - rejection already handled\n }\n });\n\n this._pending.delete(id);\n });\n\n this._connected = false;\n // allow new connect() calls to create a fresh connection\n this._connecting = null;\n // reset authenticating state so future connect/auth attempts are clean\n this._authenticating = false;\n\n // DON'T reconnect on auth failure when retries is 0\n if (wasAuthenticating && this.retries === 0) {\n const rejectErr = err || new Error(\"Authentication failed and no retries configured\");\n try {\n this._rejectReady(rejectErr);\n } catch (e: any) { }\n return;\n }\n\n // try reconnect\n if (this._currentRetries < this.retries) {\n // create a fresh ready promise for the reconnect attempt\n this._createReady();\n // add jitter to avoid thundering herd\n const base = Math.min(\n this.retryDelay * Math.pow(2, this._currentRetries),\n 30000\n );\n const jitter = Math.floor(Math.random() * Math.min(1000, base));\n const delay = base + jitter;\n this._currentRetries += 1;\n this.logger?.info?.(\n \"Attempting reconnect in \" +\n delay +\n \"ms (attempt \" +\n this._currentRetries +\n \")\"\n );\n // clear token/state before reconnect attempt\n this.token = null;\n setTimeout(() => {\n // clear any lingering pending queue when reconnecting to fresh state\n // we keep queued requests but they will be reprocessed after connect\n this.connect().catch((e: any) => {\n this.logger?.error?.(\"Reconnect failed\", e && e.message ? e.message : e);\n });\n }, delay);\n } else {\n // give up\n try {\n this._rejectReady(err || new Error(\"Disconnected and no retries left\"));\n } catch (e: any) { }\n }\n }\n\n close() {\n if (!this.client) return;\n try {\n this.client.removeAllListeners(\"data\");\n this.client.removeAllListeners(\"error\");\n this.client.removeAllListeners(\"close\");\n this.client.end();\n } catch (e: any) { }\n this.client = null;\n }\n\n /**\n * Disconnect (alias for close)\n */\n disconnect() {\n this.close();\n }\n\n /**\n * Send request helper (for public API methods)\n */\n async sendRequest(action: Action, data: any = {}): Promise<any> {\n return this.execute({ action, data });\n }\n\n // ========== Public API Methods ==========\n\n /**\n * Login with username and password\n */\n async login(username: string, password: string): Promise<any> {\n return this.sendRequest('login', { username, password });\n }\n\n /**\n * Logout from server\n */\n async logout(): Promise<any> {\n return this.sendRequest('logout', {});\n }\n\n /**\n * List all databases\n */\n async listDatabases(): Promise<any> {\n return this.sendRequest('list-dbs', {});\n }\n\n /**\n * Create a new database\n */\n async createDatabase(name: string): Promise<any> {\n return this.sendRequest('create-db', { databaseName: name });\n }\n\n /**\n * Remove a database\n */\n async removeDatabase(name: string): Promise<any> {\n return this.sendRequest('remove-db', { databaseName: name });\n }\n\n /**\n * Rename a database\n */\n async renameDatabase(oldName: string, newName: string): Promise<any> {\n return this.sendRequest('rename-db', { databaseName: oldName, newName });\n }\n\n /**\n * Execute code in a database\n */\n async run(code: string|Function, databaseName: string): Promise<any> {\n let stringCode: string;\n if (typeof code === 'function') {\n const funcStr = code.toString();\n // ตัด arrow function หรือ function keyword และ opening brace ออก\n const arrowMatch = funcStr.match(/^[\\s]*\\(?\\s*\\)?\\s*=>\\s*{?/);\n const functionMatch = funcStr.match(/^[\\s]*function\\s*\\(?[\\w\\s]*\\)?\\s*{/);\n const match = arrowMatch || functionMatch;\n const start = match ? match[0].length : 0;\n const end = funcStr.lastIndexOf('}');\n stringCode = funcStr.substring(start, end);\n // Trim leading newline, spaces, and trailing\n stringCode = stringCode.replace(/^[\\s\\r\\n]+/, '').replace(/[\\s\\r\\n]+$/, '');\n\n // Transform import(aa).from(\"module\") to import aa from \"module\"\n stringCode = stringCode.replace(\n /import\\s*\\(\\s*([^)]+?)\\s*\\)\\s*\\.from\\s*\\(\\s*(['\"])([^'\"]+)\\2\\s*\\)/g,\n (_, importArg, quote, modulePath) => {\n // Check if importArg is wrapped in braces (destructuring)\n const trimmed = importArg.trim();\n if (trimmed.startsWith('{') && trimmed.endsWith('}')) {\n // Destructuring: import({bb}) -> import { bb }\n const inner = trimmed.slice(1, -1).trim();\n return `import { ${inner} } from ${quote}${modulePath}${quote}`;\n } else {\n // Default: import(aa) -> import aa\n return `import ${trimmed} from ${quote}${modulePath}${quote}`;\n }\n }\n );\n\n // Trim leading whitespace from each line\n stringCode = stringCode.split('\\n').map(line => line.trim()).join('\\n').trim();\n } else {\n stringCode = code;\n }\n return this.sendRequest('script-code', { code: stringCode, databaseName });\n }\n\n /**\n * Save a database to disk\n */\n async saveDatabase(databaseName: string): Promise<any> {\n return this.sendRequest('save-db', { databaseName });\n }\n\n /**\n * Update database metadata\n */\n async updateDatabase(databaseName: string, data: any): Promise<any> {\n return this.sendRequest('update-db', { databaseName, ...data });\n }\n\n /**\n * Get server information\n */\n async getInfo(): Promise<any> {\n return this.sendRequest('get-info', {});\n }\n\n /**\n * Execute shell command on server\n */\n async executeShell(command: string): Promise<{ stdout: string; stderr: string }> {\n return this.sendRequest('shell-command', { command });\n }\n}\n\nexport default ScriptDBClient;\n"],"mappings":"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","names":["idx"]}
|