UNPKG

ccxt

Version:

A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go

132 lines (131 loc) 4.31 kB
/* ------------------------------------------------------------------------ */ import { isNode } from './platform.js'; /* ------------------------------------------------------------------------ */ let fsSyncModule = null; let osSyncModule = null; let pathSyncModule = null; /* ------------------------------------------------------------------------ */ /** * Initialize synchronous file system module (Node.js only) * Uses dynamic import to prevent bundling in browser builds */ export async function initFileSystem() { if (isNode) { if (fsSyncModule === null) { try { // Dynamic import with webpackIgnore to prevent bundling fsSyncModule = await import(/* webpackIgnore: true */ 'node:fs'); } catch (e) { } // Silent fail in browser or if fs is unavailable } if (osSyncModule === null) { try { osSyncModule = await import(/* webpackIgnore: true */ 'node:os'); } catch (e) { } // Silent fail in browser or if os is unavailable } if (pathSyncModule === null) { try { pathSyncModule = await import(/* webpackIgnore: true */ 'node:path'); } catch (e) { } // Silent fail in browser or if path is unavailable } } } if (isNode) { // Pre-initialize synchronous fs module for sync methods initFileSystem(); } /* ------------------------------------------------------------------------ */ /** * Get system temporary directory (Node.js only) * @returns Temporary directory path with trailing slash, or undefined */ export function getTempDir() { if (!isNode || osSyncModule === null) { return undefined; } try { const tmpDir = pathSyncModule.resolve(osSyncModule.tmpdir()); const sep = pathSyncModule ? pathSyncModule.sep : '/'; return tmpDir.endsWith(sep) ? tmpDir : tmpDir + sep; } catch (e) { return undefined; } } /** * Check if file path is ccxt-cache file, so users are ensured there is no access possible to other files * @param path File path to check */ function ensureWhitelistedFile(filePath) { if (pathSyncModule === null) { throw new Error('path module is not available'); } const sanitizedFilePath = pathSyncModule.resolve(filePath); if ((sanitizedFilePath.startsWith(filePath) && sanitizedFilePath.endsWith('.ccxtfile')) || sanitizedFilePath.endsWith('.wasm')) { return; } throw new Error('invalid file path: ' + filePath); } /* ------------------------------------------------------------------------ */ /** * Read file contents synchronously (Node.js only) * @param path File path to read * @param encoding File encoding (default: 'utf8') * @returns File contents as string, or undefined in browser */ export function readFile(path, encoding = 'utf8') { if (!isNode || fsSyncModule === null) { // Sync module not initialized yet return undefined; } ensureWhitelistedFile(path); try { return fsSyncModule.readFileSync(path, encoding); } catch (e) { return undefined; } } /* ------------------------------------------------------------------------ */ /** * Write file contents synchronously (Node.js only) * @param path File path to write * @param data Data to write * @param encoding File encoding (default: 'utf8') */ export function writeFile(path, data, encoding = 'utf8') { if (!isNode || fsSyncModule === null) { return false; } ensureWhitelistedFile(path); try { fsSyncModule.writeFileSync(path, data, encoding); return true; } catch (e) { // Silent fail return false; } } /* ------------------------------------------------------------------------ */ /** * Check if file exists synchronously (Node.js only) * @param path File path to check * @returns true if file exists, false otherwise */ export function existsFile(path) { if (!isNode || fsSyncModule === null) { // Sync module not initialized yet return false; } ensureWhitelistedFile(path); try { fsSyncModule.accessSync(path); return true; } catch (e) { return false; } }