66 * - ~/.xano-tools/config.json (global configuration)
77 * - ~/.xano-tools/tokens/ (API tokens with restricted permissions)
88 */
9- import fs from 'fs' ;
10- import path from 'path' ;
11- import os from 'os' ;
9+ import fs from 'node:fs' ;
10+ import path from 'node:path' ;
11+ import { tmpdir , homedir } from 'node:os' ;
12+ import { join } from 'node:path' ;
13+ import { Readable } from 'node:stream' ;
1214import { x } from 'tar' ;
13- import { tmpdir } from 'os' ;
14- import { join } from 'path' ;
1515import { ConfigStorage , InstanceConfig } from '@calycode/types' ;
1616
17- const BASE_DIR = path . join ( os . homedir ( ) , '.xano-tools' ) ;
17+ const BASE_DIR = path . join ( homedir ( ) , '.xano-tools' ) ;
1818const GLOBAL_CONFIG_PATH = path . join ( BASE_DIR , 'config.json' ) ;
1919const TOKENS_DIR = path . join ( BASE_DIR , 'tokens' ) ;
2020const DEFAULT_LOCAL_CONFIG_FILE = 'instance.config.json' ;
@@ -226,7 +226,7 @@ export const nodeConfigStorage: ConfigStorage = {
226226 getStartDir ( ) {
227227 return process . cwd ( ) ;
228228 } ,
229- //
229+ //
230230 // ----- FILESYSTEM OPS -----
231231 async mkdir ( dirPath , options ) {
232232 await fs . promises . mkdir ( dirPath , options ) ;
@@ -237,6 +237,30 @@ export const nodeConfigStorage: ConfigStorage = {
237237 async writeFile ( filePath , data ) {
238238 await fs . promises . writeFile ( filePath , data ) ;
239239 } ,
240+ async streamToFile (
241+ destinationPath : string ,
242+ source : ReadableStream | NodeJS . ReadableStream
243+ ) : Promise < void > {
244+ const dest = fs . createWriteStream ( destinationPath , { mode : 0o600 } ) ;
245+ let nodeStream : NodeJS . ReadableStream ;
246+
247+ // Convert if necessary
248+ if ( typeof ( source as any ) . pipe === 'function' ) {
249+ // already a NodeJS stream
250+ nodeStream = source as NodeJS . ReadableStream ;
251+ } else {
252+ // WHATWG stream (from fetch in Node 18+)
253+ // Can only use fromWeb if available in the environment
254+ nodeStream = Readable . fromWeb ( source as any ) ;
255+ }
256+
257+ await new Promise < void > ( ( resolve , reject ) => {
258+ nodeStream . pipe ( dest ) ;
259+ dest . on ( 'finish' , ( ) => resolve ( ) ) ;
260+ dest . on ( 'error' , ( err ) => reject ( err ) ) ;
261+ nodeStream . on ( 'error' , ( err ) => reject ( err ) ) ;
262+ } ) ;
263+ } ,
240264 async readFile ( filePath ) {
241265 return await fs . promises . readFile ( filePath ) ; // returns Buffer
242266 } ,
0 commit comments