diff options
Diffstat (limited to 'packages/sol-resolver/src')
-rw-r--r-- | packages/sol-resolver/src/index.ts | 8 | ||||
-rw-r--r-- | packages/sol-resolver/src/resolvers/enumerable_resolver.ts | 7 | ||||
-rw-r--r-- | packages/sol-resolver/src/resolvers/fallthrough_resolver.ts | 21 | ||||
-rw-r--r-- | packages/sol-resolver/src/resolvers/fs_resolver.ts | 19 | ||||
-rw-r--r-- | packages/sol-resolver/src/resolvers/name_resolver.ts | 66 | ||||
-rw-r--r-- | packages/sol-resolver/src/resolvers/npm_resolver.ts | 34 | ||||
-rw-r--r-- | packages/sol-resolver/src/resolvers/resolver.ts | 14 | ||||
-rw-r--r-- | packages/sol-resolver/src/resolvers/url_resolver.ts | 21 | ||||
-rw-r--r-- | packages/sol-resolver/src/types.ts | 8 |
9 files changed, 198 insertions, 0 deletions
diff --git a/packages/sol-resolver/src/index.ts b/packages/sol-resolver/src/index.ts new file mode 100644 index 000000000..cd6ec42ec --- /dev/null +++ b/packages/sol-resolver/src/index.ts @@ -0,0 +1,8 @@ +export { ContractSource, ContractSources } from './types'; +export { FallthroughResolver } from './resolvers/fallthrough_resolver'; +export { URLResolver } from './resolvers/url_resolver'; +export { NPMResolver } from './resolvers/npm_resolver'; +export { FSResolver } from './resolvers/fs_resolver'; +export { NameResolver } from './resolvers/name_resolver'; +export { EnumerableResolver } from './resolvers/enumerable_resolver'; +export { Resolver } from './resolvers/resolver'; diff --git a/packages/sol-resolver/src/resolvers/enumerable_resolver.ts b/packages/sol-resolver/src/resolvers/enumerable_resolver.ts new file mode 100644 index 000000000..0efa43e7c --- /dev/null +++ b/packages/sol-resolver/src/resolvers/enumerable_resolver.ts @@ -0,0 +1,7 @@ +import { ContractSource } from '../types'; + +import { Resolver } from './resolver'; + +export abstract class EnumerableResolver extends Resolver { + public abstract getAll(): ContractSource[]; +} diff --git a/packages/sol-resolver/src/resolvers/fallthrough_resolver.ts b/packages/sol-resolver/src/resolvers/fallthrough_resolver.ts new file mode 100644 index 000000000..8f6af9be0 --- /dev/null +++ b/packages/sol-resolver/src/resolvers/fallthrough_resolver.ts @@ -0,0 +1,21 @@ +import * as _ from 'lodash'; + +import { ContractSource } from '../types'; + +import { Resolver } from './resolver'; + +export class FallthroughResolver extends Resolver { + private _resolvers: Resolver[] = []; + public appendResolver(resolver: Resolver): void { + this._resolvers.push(resolver); + } + public resolveIfExists(importPath: string): ContractSource | undefined { + for (const resolver of this._resolvers) { + const contractSourceIfExists = resolver.resolveIfExists(importPath); + if (!_.isUndefined(contractSourceIfExists)) { + return contractSourceIfExists; + } + } + return undefined; + } +} diff --git a/packages/sol-resolver/src/resolvers/fs_resolver.ts b/packages/sol-resolver/src/resolvers/fs_resolver.ts new file mode 100644 index 000000000..4f05fba88 --- /dev/null +++ b/packages/sol-resolver/src/resolvers/fs_resolver.ts @@ -0,0 +1,19 @@ +import * as fs from 'fs'; + +import { ContractSource } from '../types'; + +import { Resolver } from './resolver'; + +export class FSResolver extends Resolver { + // tslint:disable-next-line:prefer-function-over-method + public resolveIfExists(importPath: string): ContractSource | undefined { + if (fs.existsSync(importPath)) { + const fileContent = fs.readFileSync(importPath).toString(); + return { + source: fileContent, + path: importPath, + }; + } + return undefined; + } +} diff --git a/packages/sol-resolver/src/resolvers/name_resolver.ts b/packages/sol-resolver/src/resolvers/name_resolver.ts new file mode 100644 index 000000000..6849b7610 --- /dev/null +++ b/packages/sol-resolver/src/resolvers/name_resolver.ts @@ -0,0 +1,66 @@ +import * as fs from 'fs'; +import * as _ from 'lodash'; +import * as path from 'path'; + +import { ContractSource } from '../types'; + +import { EnumerableResolver } from './enumerable_resolver'; + +export class NameResolver extends EnumerableResolver { + private _contractsDir: string; + constructor(contractsDir: string) { + super(); + this._contractsDir = contractsDir; + } + public resolveIfExists(lookupContractName: string): ContractSource | undefined { + const SOLIDITY_FILE_EXTENSION = '.sol'; + let contractSource: ContractSource | undefined; + const onFile = (filePath: string) => { + const contractName = path.basename(filePath, SOLIDITY_FILE_EXTENSION); + if (contractName === lookupContractName) { + const source = fs.readFileSync(filePath).toString(); + contractSource = { + source, + path: filePath, + }; + return true; + } + return undefined; + }; + this._traverseContractsDir(this._contractsDir, onFile); + return contractSource; + } + public getAll(): ContractSource[] { + const SOLIDITY_FILE_EXTENSION = '.sol'; + const contractSources: ContractSource[] = []; + const onFile = (filePath: string) => { + const contractName = path.basename(filePath, SOLIDITY_FILE_EXTENSION); + const source = fs.readFileSync(filePath).toString(); + const contractSource = { + source, + path: filePath, + }; + contractSources.push(contractSource); + }; + this._traverseContractsDir(this._contractsDir, onFile); + return contractSources; + } + // tslint:disable-next-line:prefer-function-over-method + private _traverseContractsDir(dirPath: string, onFile: (filePath: string) => true | void): boolean { + let dirContents: string[] = []; + try { + dirContents = fs.readdirSync(dirPath); + } catch (err) { + throw new Error(`No directory found at ${dirPath}`); + } + for (const fileName of dirContents) { + const entryPath = path.join(dirPath, fileName); + const isDirectory = fs.lstatSync(entryPath).isDirectory(); + const isComplete = isDirectory ? this._traverseContractsDir(entryPath, onFile) : onFile(entryPath); + if (isComplete) { + return isComplete; + } + } + return false; + } +} diff --git a/packages/sol-resolver/src/resolvers/npm_resolver.ts b/packages/sol-resolver/src/resolvers/npm_resolver.ts new file mode 100644 index 000000000..2c0a44aad --- /dev/null +++ b/packages/sol-resolver/src/resolvers/npm_resolver.ts @@ -0,0 +1,34 @@ +import * as fs from 'fs'; +import * as path from 'path'; + +import { ContractSource } from '../types'; + +import { Resolver } from './resolver'; + +export class NPMResolver extends Resolver { + private _packagePath: string; + constructor(packagePath: string) { + super(); + this._packagePath = packagePath; + } + public resolveIfExists(importPath: string): ContractSource | undefined { + if (!importPath.startsWith('/')) { + const [packageName, ...other] = importPath.split('/'); + const pathWithinPackage = path.join(...other); + let currentPath = this._packagePath; + const ROOT_PATH = '/'; + while (currentPath !== ROOT_PATH) { + const lookupPath = path.join(currentPath, 'node_modules', packageName, pathWithinPackage); + if (fs.existsSync(lookupPath)) { + const fileContent = fs.readFileSync(lookupPath).toString(); + return { + source: fileContent, + path: lookupPath, + }; + } + currentPath = path.dirname(currentPath); + } + } + return undefined; + } +} diff --git a/packages/sol-resolver/src/resolvers/resolver.ts b/packages/sol-resolver/src/resolvers/resolver.ts new file mode 100644 index 000000000..7edc9a85d --- /dev/null +++ b/packages/sol-resolver/src/resolvers/resolver.ts @@ -0,0 +1,14 @@ +import * as _ from 'lodash'; + +import { ContractSource } from '../types'; + +export abstract class Resolver { + public abstract resolveIfExists(importPath: string): ContractSource | undefined; + public resolve(importPath: string): ContractSource { + const contractSourceIfExists = this.resolveIfExists(importPath); + if (_.isUndefined(contractSourceIfExists)) { + throw new Error(`Failed to resolve ${importPath}`); + } + return contractSourceIfExists; + } +} diff --git a/packages/sol-resolver/src/resolvers/url_resolver.ts b/packages/sol-resolver/src/resolvers/url_resolver.ts new file mode 100644 index 000000000..180b0c9f6 --- /dev/null +++ b/packages/sol-resolver/src/resolvers/url_resolver.ts @@ -0,0 +1,21 @@ +import * as fs from 'fs'; + +import { ContractSource } from '../types'; + +import { Resolver } from './resolver'; + +export class URLResolver extends Resolver { + // tslint:disable-next-line:prefer-function-over-method + public resolveIfExists(importPath: string): ContractSource | undefined { + const FILE_URL_PREXIF = 'file://'; + if (importPath.startsWith(FILE_URL_PREXIF)) { + const filePath = importPath.substr(FILE_URL_PREXIF.length); + const fileContent = fs.readFileSync(filePath).toString(); + return { + source: fileContent, + path: importPath, + }; + } + return undefined; + } +} diff --git a/packages/sol-resolver/src/types.ts b/packages/sol-resolver/src/types.ts new file mode 100644 index 000000000..41492622d --- /dev/null +++ b/packages/sol-resolver/src/types.ts @@ -0,0 +1,8 @@ +export interface ContractSource { + source: string; + path: string; +} + +export interface ContractSources { + [key: string]: ContractSource; +} |