secret-polar-reworks
Version:
Polar is a development environment to compile, deploy, test, run scrt contracts on different networks.
104 lines (91 loc) • 3.07 kB
text/typescript
import deepmerge from "deepmerge";
import * as path from "path";
import type {
Config,
ConfigExtender,
ProjectPathsConfig,
ResolvedConfig,
StrMap,
UserPaths
} from "../../../types";
import { fromEntries } from "../../util/lang";
function mergeUserAndDefaultConfigs (
defaultConfig: Config,
userConfig: Config
): Partial<ResolvedConfig> {
return deepmerge(defaultConfig, userConfig, {
arrayMerge: (destination: any[], source: any[]) => source // eslint-disable-line @typescript-eslint/no-explicit-any
}) as Partial<ResolvedConfig>;
}
/**
* This functions resolves the polar config by merging the user provided config
* and the polar default config.
*
* @param userConfigPath the user config filepath
* @param defaultConfig the polar's default config object
* @param userConfig the user config object
* @param configExtenders An array of ConfigExtenders
*
* @returns the resolved config
*/
export function resolveConfig (
userConfigPath: string | undefined,
defaultConfig: Config,
userConfig: Config,
configExtenders: ConfigExtender[]
): ResolvedConfig {
const config: Partial<ResolvedConfig> = mergeUserAndDefaultConfigs(defaultConfig, userConfig);
const paths = userConfigPath !== undefined
? resolveProjectPaths(userConfigPath, userConfig.paths)
: undefined;
const resolved: ResolvedConfig = {
...config,
paths,
networks: config.networks ?? {}
};
for (const extender of configExtenders) {
extender(resolved, userConfig);
}
return resolved;
}
function resolvePathFrom (
from: string,
defaultPath: string,
relativeOrAbsolutePath: string = defaultPath
): string {
if (path.isAbsolute(relativeOrAbsolutePath)) {
return relativeOrAbsolutePath;
}
return path.join(from, relativeOrAbsolutePath);
}
/**
* This function resolves the ProjectPaths object from the user-provided config
* and its path. The logic of this is not obvious and should well be document.
* The good thing is that most users will never use this.
*
* Explanation:
* - paths.configFile is not overridable
* - If a path is absolute it is used "as is".
* - If the root path is relative, it's resolved from paths.configFile's dir.
* - If any other path is relative, it's resolved from paths.root.
*/
export function resolveProjectPaths (
userConfigPath: string,
userPaths: UserPaths = {}
): ProjectPathsConfig {
const configDir = path.dirname(userConfigPath);
const root = resolvePathFrom(configDir, "", userPaths.root);
const otherPathsEntries = Object.entries<string>(userPaths as StrMap).map<
[string, string]
>(([name, value]) => [name, resolvePathFrom(root, value)]);
const otherPaths = fromEntries(otherPathsEntries);
return {
...otherPaths,
root,
configFile: userConfigPath,
sources: resolvePathFrom(root, "contracts", userPaths.sources),
cache: resolvePathFrom(root, "cache", userPaths.cache),
artifacts: resolvePathFrom(root, "artifacts", userPaths.artifacts),
tests: resolvePathFrom(root, "test", userPaths.tests)
};
}