@puls-atlas/cli
Version:
The Puls Atlas CLI tool for managing Atlas projects
111 lines • 3.88 kB
JavaScript
import fs from 'fs';
import path from 'path';
import { builtinModules } from 'module';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import nodeResolve from '@rollup/plugin-node-resolve';
import { rollup } from 'rollup';
import ts from 'typescript';
const SOURCE_FILE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'];
const normalizePathSeparators = value => value.replaceAll('\\', '/');
const ensureDirectory = directoryPath => {
if (!fs.existsSync(directoryPath)) {
fs.mkdirSync(directoryPath, {
recursive: true
});
}
};
const stripKnownExtension = filePath => {
for (const extension of SOURCE_FILE_EXTENSIONS) {
if (filePath.endsWith(extension)) {
return filePath.slice(0, -extension.length);
}
}
return filePath;
};
const isTypeScriptSourceFile = filePath => /\.(ts|tsx)$/iu.test(filePath);
const formatTypeScriptDiagnostics = diagnostics => diagnostics.map(diagnostic => ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')).join('\n');
const createSearchMapperTypeScriptPlugin = () => ({
name: 'atlas-search-typescript-transpiler',
transform(sourceCode, id) {
if (!isTypeScriptSourceFile(id)) {
return null;
}
const result = ts.transpileModule(sourceCode, {
compilerOptions: {
module: ts.ModuleKind.ESNext,
sourceMap: false,
target: ts.ScriptTarget.ES2020,
verbatimModuleSyntax: true
},
fileName: id,
reportDiagnostics: true
});
if ((result.diagnostics ?? []).length > 0) {
throw new Error(formatTypeScriptDiagnostics(result.diagnostics));
}
return {
code: result.outputText,
map: null
};
}
});
export const toSearchMapperModulePath = relativeSourcePath => normalizePathSeparators(path.join('files', `${stripKnownExtension(relativeSourcePath)}.js`));
const getSearchMapperBuiltinModules = () => new Set(builtinModules.flatMap(moduleName => {
if (moduleName.startsWith('node:')) {
return [moduleName, moduleName.slice('node:'.length)];
}
return [moduleName, `node:${moduleName}`];
}));
export const createSearchMapperRollupExternal = () => {
const builtinModuleSet = getSearchMapperBuiltinModules();
return source => builtinModuleSet.has(source);
};
export const createSearchMapperRollupPlugins = () => [nodeResolve({
exportConditions: ['node', 'import', 'default'],
extensions: SOURCE_FILE_EXTENSIONS,
preferBuiltins: true
}), createSearchMapperTypeScriptPlugin(), commonjs(), json()];
export const bundleSearchMapperEntry = async input => {
const cwd = input.cwd ?? process.cwd();
const relativeSourcePath = normalizePathSeparators(path.relative(cwd, input.sourceFilePath));
const modulePath = toSearchMapperModulePath(relativeSourcePath);
const localModulePath = path.join(input.artifactRoot, modulePath);
let bundle = null;
ensureDirectory(path.dirname(localModulePath));
try {
bundle = await rollup({
input: input.sourceFilePath,
external: createSearchMapperRollupExternal(),
onwarn(warning, defaultHandler) {
if (warning.code === 'UNRESOLVED_IMPORT') {
throw new Error(warning.message);
}
defaultHandler(warning);
},
plugins: createSearchMapperRollupPlugins()
});
await bundle.write({
exports: 'named',
file: localModulePath,
format: 'esm',
inlineDynamicImports: true,
sourcemap: false
});
return {
localModulePath,
modulePath,
relativeSourcePath
};
} catch (error) {
throw new Error(`Could not bundle Atlas search mapper ${input.mapperName ?? relativeSourcePath}. ${error.message}`);
} finally {
await bundle?.close();
}
};
export default {
bundleSearchMapperEntry,
createSearchMapperRollupExternal,
createSearchMapperRollupPlugins,
toSearchMapperModulePath
};