@storm-stack/core
Version:
A build toolkit and runtime used by Storm Software in TypeScript applications
249 lines (245 loc) • 9.32 kB
JavaScript
import { init_esm_shims, __name } from './chunk-QH7NXH7H.js';
import { existsSync } from '@stryke/fs/exists';
import { readJsonFileSync } from '@stryke/fs/json';
import { joinPaths } from '@stryke/path/join-paths';
import { replacePath } from '@stryke/path/replace';
import defu2 from 'defu';
import ts from 'typescript';
import { getWorkspaceConfig } from '@storm-software/config-tools/get-config';
import { getProjectRoot, getWorkspaceRoot } from '@stryke/fs/get-workspace-root';
import { isFunction } from '@stryke/type-checks/is-function';
import { isSetObject } from '@stryke/type-checks/is-set-object';
import { loadConfig } from 'c12';
// src/lib/typescript/tsconfig.ts
init_esm_shims();
function getTsconfigFilePath(projectRoot, tsconfig = "tsconfig.json") {
let tsconfigFilePath = tsconfig;
if (!existsSync(tsconfigFilePath)) {
tsconfigFilePath = joinPaths(projectRoot, replacePath(tsconfig, projectRoot));
if (!existsSync(tsconfigFilePath)) {
throw new Error(`Cannot find the \`tsconfig.json\` configuration file at ${joinPaths(projectRoot, replacePath(tsconfig, projectRoot))} or ${tsconfigFilePath}`);
}
}
return tsconfigFilePath;
}
__name(getTsconfigFilePath, "getTsconfigFilePath");
function findMatch(tsconfigType, types, extensions = [
".ts",
".tsx",
".d.ts"
]) {
return types.find((type) => tsconfigType?.toString().toLowerCase() === type?.toString().toLowerCase() || tsconfigType?.toString().toLowerCase() === `./${type?.toString().toLowerCase()}` || `./${tsconfigType?.toString().toLowerCase()}` === type?.toString().toLowerCase() || extensions.some((ext) => `${tsconfigType?.toString().toLowerCase()}${ext}` === type?.toString().toLowerCase() || `${tsconfigType?.toString().toLowerCase()}${ext}` === `./${type?.toString().toLowerCase()}` || `${type?.toString().toLowerCase()}${ext}` === `./${tsconfigType?.toString().toLowerCase()}` || tsconfigType?.toString().toLowerCase() === `${type?.toString().toLowerCase()}${ext}` || tsconfigType?.toString().toLowerCase() === `./${type?.toString().toLowerCase()}${ext}` || type?.toString().toLowerCase() === `./${tsconfigType?.toString().toLowerCase()}${ext}`));
}
__name(findMatch, "findMatch");
function findIncludeMatch(tsconfigType, types) {
return findMatch(tsconfigType, types, [
".ts",
".tsx",
".d.ts",
".js",
".jsx",
".mjs",
".cjs",
".mts",
".cts",
"/*.ts",
"/*.tsx",
"/*.d.ts",
"/*.js",
"/*.jsx",
"/*.mjs",
"/*.cjs",
"/*.mts",
"/*.cts",
"/**/*.ts",
"/**/*.tsx",
"/**/*.d.ts",
"/**/*.js",
"/**/*.jsx",
"/**/*.mjs",
"/**/*.cjs",
"/**/*.mts",
"/**/*.cts"
]);
}
__name(findIncludeMatch, "findIncludeMatch");
function isIncludeMatchFound(tsconfigType, types) {
return findIncludeMatch(tsconfigType, types) !== void 0;
}
__name(isIncludeMatchFound, "isIncludeMatchFound");
function getParsedTypeScriptConfig(workspaceRoot, projectRoot, tsconfig, tsconfigRaw = {}, host = ts.sys) {
const tsconfigFilePath = getTsconfigFilePath(projectRoot, tsconfig);
const tsconfigJson = readJsonFileSync(tsconfigFilePath);
if (!tsconfigJson) {
throw new Error(`Cannot find the \`tsconfig.json\` configuration file at ${joinPaths(projectRoot, tsconfig ?? "tsconfig.json")}`);
}
const parsedCommandLine = ts.parseJsonConfigFileContent(defu2(tsconfigRaw ?? {}, tsconfigJson), host, joinPaths(workspaceRoot, projectRoot));
if (parsedCommandLine.errors.length > 0) {
const errorMessage = `Cannot parse the TypeScript compiler options. Please investigate the following issues:
${parsedCommandLine.errors.map((error) => `- ${(error.category !== void 0 && error.code ? `[${error.category}-${error.code}]: ` : "") + error.messageText.toString()}`).join("\n")}
`;
throw new Error(errorMessage);
}
return {
...parsedCommandLine,
tsconfigJson,
tsconfigFilePath
};
}
__name(getParsedTypeScriptConfig, "getParsedTypeScriptConfig");
// src/lib/config.ts
init_esm_shims();
async function loadUserConfigFile(projectRoot, jiti, command, mode) {
let resolvedUserConfig = {};
const resolvedUserConfigFile = existsSync(joinPaths(projectRoot, "storm.config.ts")) ? joinPaths(projectRoot, "storm.config.ts") : existsSync(joinPaths(projectRoot, "storm.config.js")) ? joinPaths(projectRoot, "storm.config.js") : existsSync(joinPaths(projectRoot, "storm.config.mts")) ? joinPaths(projectRoot, "storm.config.mts") : existsSync(joinPaths(projectRoot, "storm.config.mjs")) ? joinPaths(projectRoot, "storm.config.mjs") : void 0;
if (resolvedUserConfigFile) {
const resolved = await jiti.import(jiti.esmResolve(resolvedUserConfigFile));
if (resolved) {
let config = {};
if (isFunction(resolved)) {
config = await Promise.resolve(resolved({
command,
mode: mode || "production",
isSsrBuild: false,
isPreview: false
}));
}
if (isSetObject(config)) {
resolvedUserConfig = {
...config,
config,
configFile: resolvedUserConfigFile
};
}
}
}
const result = await Promise.all([
loadConfig({
cwd: projectRoot,
name: "storm",
envName: mode,
globalRc: true,
packageJson: true,
dotenv: true,
jiti
}),
loadConfig({
cwd: projectRoot,
name: "storm.config",
rcFile: false,
globalRc: false,
packageJson: false,
dotenv: false,
jiti
}),
loadConfig({
cwd: projectRoot,
name: "storm-stack",
envName: mode,
globalRc: true,
packageJson: "stormStack",
jiti
})
]);
return defu2(resolvedUserConfig, isSetObject(result[0]?.config) ? {
...result[0].config,
...result[0]
} : {}, isSetObject(result[1]?.config) ? {
...result[1].config,
...result[1]
} : {}, isSetObject(result[2]?.config) ? {
...result[2].config,
...result[2]
} : {});
}
__name(loadUserConfigFile, "loadUserConfigFile");
async function resolveConfig(context, inlineConfig, userConfig, projectRoot) {
const resolvedProjectRoot = projectRoot || inlineConfig.root || userConfig?.root || getProjectRoot() || process.cwd();
const workspaceConfig = defu2(await getWorkspaceConfig(), {
workspaceRoot: context.options.workspaceConfig?.workspaceRoot ?? getWorkspaceRoot()
});
if (!workspaceConfig) {
throw new Error("The workspace root could not be determined. Please ensure you are in a Storm Stack project.");
}
const mergedUserConfig = defu2({
config: userConfig ?? {}
}, await loadUserConfigFile(resolvedProjectRoot, context.resolver, context.options.command, inlineConfig.mode || userConfig?.mode || context.options.workspaceConfig?.mode || "production"));
const resolvedOptions = defu2({
inlineConfig,
userConfig: mergedUserConfig,
workspaceConfig,
projectRoot: resolvedProjectRoot,
workspaceRoot: workspaceConfig.workspaceRoot
}, inlineConfig, mergedUserConfig.config ?? {}, {
...context.options,
tsconfig: getTsconfigFilePath(resolvedProjectRoot, context.options.tsconfig ?? "tsconfig.json")
}, {
platform: "neutral",
mode: "production",
projectType: "application",
logLevel: "info",
isSsrBuild: false,
isPreview: false,
babel: {
plugins: [],
presets: []
},
build: {},
override: {}
});
resolvedOptions.output = defu2(resolvedOptions.output ?? {}, {
outputPath: resolvedOptions.tsconfigRaw?.compilerOptions?.outDir,
outputMode: resolvedOptions.output?.outputMode
}, {
outputPath: resolvedProjectRoot === workspaceConfig.workspaceRoot ? "dist" : joinPaths("dist", resolvedProjectRoot),
outputMode: "virtual",
assets: [
{
input: resolvedProjectRoot,
glob: "README.md",
output: "/"
},
{
input: resolvedProjectRoot,
glob: "CHANGELOG.md",
output: "/"
},
{
input: "",
glob: "LICENSE",
output: "/"
}
]
});
resolvedOptions.environment ??= defaultEnvironmentName(resolvedOptions);
resolvedOptions.sourceRoot ??= joinPaths(resolvedOptions.projectRoot, "src");
resolvedOptions.tsconfig ??= getTsconfigFilePath(resolvedOptions.projectRoot, resolvedOptions.tsconfig);
context.options = resolvedOptions;
context.options.logLevel = context.options.logLevel === "silent" ? null : context.options.logLevel === "success" ? "info" : context.options.logLevel === "trace" || context.options.logLevel === "all" ? "debug" : context.options.logLevel;
context.options.userConfig ??= {};
context.options.userConfig.plugins = mergedUserConfig.plugins ?? [];
context.options.plugins = {
config: {
additionalFiles: []
}
};
return resolvedOptions;
}
__name(resolveConfig, "resolveConfig");
function defaultEnvironmentName(options) {
if (options.isSsrBuild) {
return "ssr";
}
if (options.isPreview) {
return "preview";
}
if (options.platform === "node" || options.isSsrBuild) {
return "server";
}
if (options.platform === "browser") {
return "client";
}
return "shared";
}
__name(defaultEnvironmentName, "defaultEnvironmentName");
export { defaultEnvironmentName, getParsedTypeScriptConfig, getTsconfigFilePath, isIncludeMatchFound, resolveConfig };