import { createHash } from 'crypto' ; import fs from 'fs-extra' ; import { Sema } from 'async-sema' ; import { join , dirname } from 'path' ; export interface DeploymentFile { names : string [ ] ; data : Buffer ; mode : number ; } param { Buffer } file return { String } function hash ( buf ) { return createHash ( 'sha1' ) . update ( buf ) . digest ( 'hex' ) ; } param map return { object } export const mapToObject = ( map ) : { [ key ] : DeploymentFile ; } => { const obj = { } ; for ( const [ key , value ] of map ) { obj [ key ] = value ; } return obj ; } ; param files param map return export async function hashes ( files , map = new Map < string , DeploymentFile > ( ) ) { const semaphore = new Sema ( 100 ) ; await Promise . all ( files . map ( async ( name ) : Promise < void > => { await semaphore . acquire ( ) ; const data = await fs . readFile ( name ) ; const { mode } = await fs . stat ( name ) ; const h = hash ( data ) ; const entry = map . get ( h ) ; if ( entry ) { const names = new Set ( entry . names ) ; names . add ( name ) ; entry . names = [ ... names ] ; } else { map . set ( h , { names : [ name ] , data , mode } ) ; } semaphore . release ( ) ; } ) ) ; return map ; } export async function resolveNftJsonFiles ( hashedFiles ) { const semaphore = new Sema ( 100 ) ; const existingFiles = Array . from ( hashedFiles . values ( ) ) ; const resolvedFiles = new Set < string > ( ) ; await Promise . all ( existingFiles . map ( async ( file ) => { await semaphore . acquire ( ) ; const fsPath = file . names [ 0 ] ; if ( fsPath . endsWith ( '.nft.json' ) ) { const json = file . data . toString ( 'utf8' ) ; const { version , files } = JSON . parse ( json ) as { version : number ; files : string [ ] | { input : string ; output : string ; } [ ] ; } ; if ( version === 1 || version === 2 ) { for ( let f of files ) { const relPath = typeof f === 'string' ? f : f . input ; resolvedFiles . add ( join ( dirname ( fsPath ) , relPath ) ) ; } } else { console . error ( `Invalid nft.json version: ${ version }` ) ; } } semaphore . release ( ) ; } ) ) ; return Array . from ( resolvedFiles ) ; }