aboutsummaryrefslogtreecommitdiffstats
path: root/packages/resolver/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/resolver/src')
-rw-r--r--packages/resolver/src/index.ts8
-rw-r--r--packages/resolver/src/resolvers/enumerable_resolver.ts7
-rw-r--r--packages/resolver/src/resolvers/fallthrough_resolver.ts21
-rw-r--r--packages/resolver/src/resolvers/fs_resolver.ts19
-rw-r--r--packages/resolver/src/resolvers/name_resolver.ts66
-rw-r--r--packages/resolver/src/resolvers/npm_resolver.ts34
-rw-r--r--packages/resolver/src/resolvers/resolver.ts14
-rw-r--r--packages/resolver/src/resolvers/url_resolver.ts21
-rw-r--r--packages/resolver/src/types.ts8
9 files changed, 198 insertions, 0 deletions
diff --git a/packages/resolver/src/index.ts b/packages/resolver/src/index.ts
new file mode 100644
index 000000000..cd6ec42ec
--- /dev/null
+++ b/packages/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/resolver/src/resolvers/enumerable_resolver.ts b/packages/resolver/src/resolvers/enumerable_resolver.ts
new file mode 100644
index 000000000..bb578bb86
--- /dev/null
+++ b/packages/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 getAllContracts(): ContractSource[];
+}
diff --git a/packages/resolver/src/resolvers/fallthrough_resolver.ts b/packages/resolver/src/resolvers/fallthrough_resolver.ts
new file mode 100644
index 000000000..8f6af9be0
--- /dev/null
+++ b/packages/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/resolver/src/resolvers/fs_resolver.ts b/packages/resolver/src/resolvers/fs_resolver.ts
new file mode 100644
index 000000000..4f05fba88
--- /dev/null
+++ b/packages/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/resolver/src/resolvers/name_resolver.ts b/packages/resolver/src/resolvers/name_resolver.ts
new file mode 100644
index 000000000..522e10142
--- /dev/null
+++ b/packages/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 getAllContracts(): 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/resolver/src/resolvers/npm_resolver.ts b/packages/resolver/src/resolvers/npm_resolver.ts
new file mode 100644
index 000000000..2c0a44aad
--- /dev/null
+++ b/packages/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/resolver/src/resolvers/resolver.ts b/packages/resolver/src/resolvers/resolver.ts
new file mode 100644
index 000000000..7edc9a85d
--- /dev/null
+++ b/packages/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/resolver/src/resolvers/url_resolver.ts b/packages/resolver/src/resolvers/url_resolver.ts
new file mode 100644
index 000000000..180b0c9f6
--- /dev/null
+++ b/packages/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/resolver/src/types.ts b/packages/resolver/src/types.ts
new file mode 100644
index 000000000..41492622d
--- /dev/null
+++ b/packages/resolver/src/types.ts
@@ -0,0 +1,8 @@
+export interface ContractSource {
+ source: string;
+ path: string;
+}
+
+export interface ContractSources {
+ [key: string]: ContractSource;
+}