{"version":3,"sources":["../../src/installer/truffle/index.ts"],"names":[],"mappings":"AAAA;;GAEG;;AAMH,OAAO,EAAE,QAAQ,EAAE,+BAA8B;AACjD,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,KAAK,SAAS,aAAuB;AAC5C,OAAO,KAAK,MAAM,qBAAoB;AACtC,OAAO,KAAK,CAAC,MAAM,OAAO,CAAA;AAO1B,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,gBAAgB;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,qBAAa,cAAe,YAAW,SAAS,CAAC,OAAO;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,GAAG,CAAC;gBAEZ,OAAO,EAAE,gBAAgB;IAc/B,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA+EvF;AAGD,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC;IAC/E,WAAW;;;;;;;OAOR;IAEG,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;CAIlE","file":"index.d.ts","sourcesContent":["/**\n * @module \"ethpm/installer/truffle\"\n */\n\nconst fs = require('fs-extra')\nconst tmp = require('tmp')\nconst path = require('path')\nimport { IpfsService } from \"ethpm/storage/ipfs\";\nimport { Resolver } from \"ethpm/package/resolver\"\nimport { URL } from \"url\";\nimport * as installer from \"ethpm/installer\"\nimport * as config from \"ethpm/config\"\nimport * as t from 'io-ts'\n\n\ninterface ObjectLiteral {\n  [key: string]: string;\n}\n\ninterface IpfsOptions {\n  host: string;\n  port: number | string;\n  protocol: string;\n}\n\ninterface InstallerOptions {\n  workingDirectory: string;\n  ipfs: IpfsOptions;\n}\n\nexport class TruffleService implements installer.Service {\n  public workingDir: string;\n  public ethpmDir: string;\n  public lockfilePath: string;\n  public resolver: Resolver;\n  public ipfsOptions: any;\n\n  constructor(options: InstallerOptions) {\n    this.workingDir = options.workingDirectory;\n    this.ethpmDir = path.join(this.workingDir, \"_ethpm_packages\")\n    this.lockfilePath = path.join(this.ethpmDir, \"ethpm.lock\")\n    this.ipfsOptions = options.ipfs\n    this.resolver =  new Resolver(new IpfsService(this.ipfsOptions))\n\n    // assumes if ethpmDir exists - it is correctly formatted\n    if (!fs.existsSync(this.ethpmDir)) {\n      fs.mkdirSync(this.ethpmDir)\n      fs.writeFileSync(this.lockfilePath, \"{}\")\n    }\n  }\n\n  async install(contentURI: URL, registryAddress: string, alias?: string): Promise<void> {\n    // create temporary _ethpm_packages/\n    const tmpEthpmDir = tmp.dirSync({unsafeCleanup: true});\n    fs.copySync(this.ethpmDir, tmpEthpmDir.name)\n    const tmpLockfilePath = path.join(tmpEthpmDir.name, \"ethpm.lock\")\n    const pkg = await this.resolver.resolve(contentURI)\n\n    //\n    // check for conflicts\n    //\n    const packageAlias = (typeof alias != \"undefined\") ? alias : pkg.originalPackage.packageName;\n    const newPackageDir = path.join(tmpEthpmDir.name, packageAlias)\n    if (fs.existsSync(newPackageDir)) {\n      throw new Error(\"Package: \" + packageAlias + \" already installed. Try using an alias.\")\n    } else {\n      fs.mkdirSync(newPackageDir)\n    }\n    const manifestPath = path.join(newPackageDir, \"manifest.json\")\n    fs.writeFileSync(manifestPath, pkg.rawManifest)\n\n    //\n    // update ethpm.lock\n    //\n    const lockfileData = {\n      [packageAlias as string]: {\n        alias: packageAlias,\n        install_uri: contentURI.href,\n        registry_address: registryAddress,\n        resolved_content_hash: contentURI.host,\n        resolved_package_name: pkg.originalPackage.packageName,\n        resolved_uri: contentURI.href,\n        resolved_version: pkg.originalPackage.version\n      }\n    }\n    if(!fs.existsSync(tmpLockfilePath)){\n      fs.writeFileSync(tmpLockfilePath, JSON.stringify(lockfileData, null, 4) + \"\\n\")\n    } else {\n      const existingLockfileData = JSON.parse(fs.readFileSync(tmpLockfilePath))\n      const updatedLockfileData = Object.assign(existingLockfileData, lockfileData)\n      const ordered: ObjectLiteral = {}\n      Object.keys(updatedLockfileData).sort().forEach((key) => {\n        ordered[key] = updatedLockfileData[key]\n      })\n      fs.writeFileSync(tmpLockfilePath, JSON.stringify(ordered, null, 4) + \"\\n\")\n    }\n\n\n    //\n    // write sources to tmpEthpmDir\n    //\n    if (Object.entries(pkg.sources).length !== 0) {\n      const sourcesDir = path.join(newPackageDir, \"_src\")\n      fs.mkdirSync(sourcesDir)\n      Object.entries(pkg.sources).forEach(([pth, sourceObject], idx) => {\n        const targetPath = path.join(sourcesDir, path.normalize(pth))\n        const targetDir = path.parse(targetPath).dir\n        if (!fs.existsSync(targetDir)) {\n          fs.mkdirSync(targetDir, {recursive: true})\n        }\n        fs.writeFileSync(targetPath, sourceObject['content'])\n      })\n    }\n\n    //\n    // write build dependencies to tmpEthpmDir\n    //\n    if (Object.entries(pkg.buildDependencies).length !== 0) {\n      const buildDependenciesInstaller = new TruffleService({workingDirectory: newPackageDir, ipfs: this.ipfsOptions})\n      for (const [name, dependencyURI] of Object.entries(pkg.originalPackage.buildDependencies)) {\n        await buildDependenciesInstaller.install(dependencyURI, registryAddress)\n      }\n    }\n\n    //\n    // copy tmpEthpmDir to disk\n    //\n    fs.copySync(tmpEthpmDir.name, this.ethpmDir)\n    tmpEthpmDir.removeCallback()\n  }\n}\n\n\nexport default class TruffleConnector extends config.Connector<installer.Service> {\n  optionsType = t.interface({\n    workingDirectory: t.string,\n    ipfs: t.interface({\n      host: t.string,\n      port: t.union([t.number, t.string]),\n      protocol: t.string,\n    })\n  });\n  \n  async init(options: InstallerOptions): Promise<installer.Service> {\n    const service = new TruffleService(options);\n    return service;\n  }\n}\n"]}