/** * Legacy adapter that provides backward compatibility * Maps legacy API to the new core module */ import * as core from '../core/index.js'; import * as plugins from '../core/plugins.js'; const smartpromise = plugins.smartpromise; // Re-export types for backward compatibility export { type IExtendedIncomingMessage } from '../core/types.js'; export interface ISmartRequestOptions extends core.ICoreRequestOptions { autoJsonParse?: boolean; responseType?: 'json' | 'text' | 'binary' | 'stream'; } // Re-export interface for form fields export interface IFormField { name: string; type: 'string' | 'filePath' | 'Buffer'; payload: string | Buffer; fileName?: string; contentType?: string; } /** * Helper function to convert stream to IExtendedIncomingMessage for legacy compatibility */ async function streamToExtendedMessage( stream: plugins.http.IncomingMessage, autoJsonParse = true ): Promise { const done = smartpromise.defer(); const chunks: Buffer[] = []; stream.on('data', (chunk: Buffer) => { chunks.push(chunk); }); stream.on('end', () => { const buffer = Buffer.concat(chunks); const extendedMessage = stream as core.IExtendedIncomingMessage; if (autoJsonParse) { const text = buffer.toString('utf-8'); try { extendedMessage.body = JSON.parse(text); } catch (err) { extendedMessage.body = text; } } else { extendedMessage.body = buffer; } done.resolve(extendedMessage); }); stream.on('error', (err) => { done.reject(err); }); return done.promise; } /** * Legacy request function that returns IExtendedIncomingMessage */ export async function request( urlArg: string, optionsArg: ISmartRequestOptions = {}, responseStreamArg = false, requestDataFunc?: (req: plugins.http.ClientRequest) => void ): Promise { const stream = await core.coreRequest(urlArg, optionsArg, requestDataFunc); if (responseStreamArg) { // For stream responses, just cast and return return stream as core.IExtendedIncomingMessage; } // Convert stream to IExtendedIncomingMessage const autoJsonParse = optionsArg.autoJsonParse !== false; return streamToExtendedMessage(stream, autoJsonParse); } /** * Safe GET request */ export async function safeGet(urlArg: string): Promise { const agentToUse = urlArg.startsWith('http://') ? new plugins.http.Agent() : new plugins.https.Agent(); try { const response = await request(urlArg, { method: 'GET', agent: agentToUse, timeout: 5000, hardDataCuttingTimeout: 5000, autoJsonParse: false, }); return response; } catch (err) { console.error(err); return null; } } /** * GET JSON request */ export async function getJson(urlArg: string, optionsArg: ISmartRequestOptions = {}) { optionsArg.method = 'GET'; return request(urlArg, optionsArg); } /** * POST JSON request */ export async function postJson(urlArg: string, optionsArg: ISmartRequestOptions = {}) { optionsArg.method = 'POST'; if ( typeof optionsArg.requestBody === 'object' && (!optionsArg.headers || !optionsArg.headers['Content-Type']) ) { // make sure headers exist if (!optionsArg.headers) { optionsArg.headers = {}; } // assign the right Content-Type, leaving all other headers in place optionsArg.headers = { ...optionsArg.headers, 'Content-Type': 'application/json', }; } return request(urlArg, optionsArg); } /** * PUT JSON request */ export async function putJson(urlArg: string, optionsArg: ISmartRequestOptions = {}) { optionsArg.method = 'PUT'; return request(urlArg, optionsArg); } /** * DELETE JSON request */ export async function delJson(urlArg: string, optionsArg: ISmartRequestOptions = {}) { optionsArg.method = 'DELETE'; return request(urlArg, optionsArg); } /** * GET binary data */ export async function getBinary(urlArg: string, optionsArg: ISmartRequestOptions = {}) { optionsArg = { ...optionsArg, autoJsonParse: false, responseType: 'binary' }; return request(urlArg, optionsArg); } /** * POST form data */ export async function postFormData(urlArg: string, formFields: IFormField[], optionsArg: ISmartRequestOptions = {}) { const form = new plugins.formData(); for (const formField of formFields) { if (formField.type === 'filePath') { const fileData = plugins.fs.readFileSync( plugins.path.isAbsolute(formField.payload as string) ? formField.payload as string : plugins.path.join(process.cwd(), formField.payload as string) ); form.append(formField.name, fileData, { filename: formField.fileName || plugins.path.basename(formField.payload as string), contentType: formField.contentType }); } else if (formField.type === 'Buffer') { form.append(formField.name, formField.payload, { filename: formField.fileName, contentType: formField.contentType }); } else { form.append(formField.name, formField.payload); } } optionsArg.method = 'POST'; optionsArg.requestBody = form; if (!optionsArg.headers) { optionsArg.headers = {}; } optionsArg.headers = { ...optionsArg.headers, ...form.getHeaders() }; return request(urlArg, optionsArg); } /** * POST URL encoded form data */ export async function postFormDataUrlEncoded( urlArg: string, formFields: { key: string; content: string }[], optionsArg: ISmartRequestOptions = {} ) { optionsArg.method = 'POST'; if (!optionsArg.headers) { optionsArg.headers = {}; } optionsArg.headers['Content-Type'] = 'application/x-www-form-urlencoded'; const urlEncodedBody = formFields .map(field => `${encodeURIComponent(field.key)}=${encodeURIComponent(field.content)}`) .join('&'); optionsArg.requestBody = urlEncodedBody; return request(urlArg, optionsArg); } /** * GET stream */ export async function getStream( urlArg: string, optionsArg: ISmartRequestOptions = {} ): Promise { optionsArg.method = 'GET'; const response = await request(urlArg, optionsArg, true); return response; }