@moonwall/cli
Version:
Testing framework for the Moon family of projects
173 lines (170 loc) • 5.76 kB
JavaScript
// src/internal/effect/chopsticksConfigParser.ts
import { Effect as Effect2 } from "effect";
import * as fs from "fs";
import * as yaml from "yaml";
// src/internal/effect/ChopsticksService.ts
import { Context, Data } from "effect";
var ChopsticksSetupError = class extends Data.TaggedError("ChopsticksSetupError") {
};
var ChopsticksBlockError = class extends Data.TaggedError("ChopsticksBlockError") {
};
var ChopsticksStorageError = class extends Data.TaggedError("ChopsticksStorageError") {
};
var ChopsticksExtrinsicError = class extends Data.TaggedError("ChopsticksExtrinsicError") {
};
var ChopsticksXcmError = class extends Data.TaggedError("ChopsticksXcmError") {
};
var ChopsticksCleanupError = class extends Data.TaggedError("ChopsticksCleanupError") {
};
var ChopsticksService = class extends Context.Tag("ChopsticksService")() {
};
var ChopsticksConfigTag = class extends Context.Tag("ChopsticksConfig")() {
};
// src/internal/effect/chopsticksConfigParser.ts
import { createLogger } from "@moonwall/util";
var BuildBlockModeValues = {
Batch: "Batch",
Manual: "Manual",
Instant: "Instant"
};
var logger = createLogger({ name: "chopsticksConfigParser" });
var resolveEnvVars = (value) => {
return value.replace(/\$\{env\.([^}]+)\}/g, (_, varName) => {
const envValue = process.env[varName];
if (envValue === void 0) {
logger.warn(`Environment variable ${varName} is not set`);
return "";
}
return envValue;
});
};
var resolveEnvVarsDeep = (value) => {
if (typeof value === "string") {
return resolveEnvVars(value);
}
if (Array.isArray(value)) {
return value.map(resolveEnvVarsDeep);
}
if (value !== null && typeof value === "object") {
const result = {};
for (const [key, val] of Object.entries(value)) {
result[key] = resolveEnvVarsDeep(val);
}
return result;
}
return value;
};
var parseBuildBlockMode = (mode) => {
switch (mode?.toLowerCase()) {
case "batch":
return BuildBlockModeValues.Batch;
case "instant":
return BuildBlockModeValues.Instant;
case "manual":
default:
return BuildBlockModeValues.Manual;
}
};
var parseBlockField = (block) => {
if (block === void 0 || block === null) {
return block;
}
if (typeof block === "number") {
return block;
}
if (block === "") {
return void 0;
}
const blockNum = Number(block);
if (!Number.isNaN(blockNum)) {
return blockNum;
}
return block;
};
var parseChopsticksConfigFile = (configPath, overrides) => Effect2.gen(function* () {
const fileContent = yield* Effect2.tryPromise({
try: async () => {
const content = await fs.promises.readFile(configPath, "utf-8");
return content;
},
catch: (cause) => new ChopsticksSetupError({
cause,
endpoint: `file://${configPath}`
})
});
const rawConfigUnresolved = yield* Effect2.try({
try: () => yaml.parse(fileContent),
catch: (cause) => new ChopsticksSetupError({
cause: new Error(`Failed to parse YAML config: ${cause}`),
endpoint: `file://${configPath}`
})
});
const rawConfig = resolveEnvVarsDeep(rawConfigUnresolved);
const rawEndpoint = rawConfig.endpoint;
const endpoint = typeof rawEndpoint === "string" ? rawEndpoint : Array.isArray(rawEndpoint) ? rawEndpoint[0] : "";
if (!endpoint) {
return yield* Effect2.fail(
new ChopsticksSetupError({
cause: new Error(
`Endpoint is required but not configured. Check that the environment variable in your chopsticks config is set. Raw value: "${rawConfigUnresolved.endpoint ?? ""}"`
),
endpoint: String(rawConfigUnresolved.endpoint) || "undefined"
})
);
}
if (!endpoint.startsWith("ws://") && !endpoint.startsWith("wss://")) {
return yield* Effect2.fail(
new ChopsticksSetupError({
cause: new Error(
`Invalid endpoint format: "${endpoint}" - must start with ws:// or wss://`
),
endpoint
})
);
}
const block = parseBlockField(rawConfig.block);
const rawBuildBlockMode = rawConfig["build-block-mode"];
const buildBlockMode = overrides?.buildBlockMode !== void 0 ? parseBuildBlockMode(overrides.buildBlockMode) : rawBuildBlockMode !== void 0 ? parseBuildBlockMode(rawBuildBlockMode) : BuildBlockModeValues.Manual;
const finalPort = overrides?.port ?? rawConfig.port ?? 8e3;
logger.debug(`Parsed chopsticks config from ${configPath}`);
logger.debug(` endpoint: ${endpoint}`);
logger.debug(` port: ${finalPort}`);
const config = {
...rawConfig,
block,
"build-block-mode": buildBlockMode,
port: finalPort,
...overrides?.host !== void 0 && { host: overrides.host },
...overrides?.wasmOverride !== void 0 && { "wasm-override": overrides.wasmOverride },
...overrides?.allowUnresolvedImports !== void 0 && {
"allow-unresolved-imports": overrides.allowUnresolvedImports
}
};
return config;
});
var validateChopsticksConfig = (config) => Effect2.gen(function* () {
const endpoint = typeof config.endpoint === "string" ? config.endpoint : Array.isArray(config.endpoint) ? config.endpoint[0] : void 0;
if (!endpoint) {
return yield* Effect2.fail(
new ChopsticksSetupError({
cause: new Error("Endpoint is required - check your environment variables"),
endpoint: "undefined"
})
);
}
if (!endpoint.startsWith("ws://") && !endpoint.startsWith("wss://")) {
return yield* Effect2.fail(
new ChopsticksSetupError({
cause: new Error(
`Invalid endpoint format: "${endpoint}" - must start with ws:// or wss://`
),
endpoint
})
);
}
return config;
});
export {
parseChopsticksConfigFile,
validateChopsticksConfig
};