Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(atomic): add SVG transformer #4867

Merged
merged 7 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3107,5 +3107,4 @@ export declare interface AtomicTimeframeFacet extends Components.AtomicTimeframe



import type {} from '@coveo/atomic/components';
import type {} from '@coveo/atomic/components';
2 changes: 1 addition & 1 deletion packages/atomic/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"commands": [
"node --max_old_space_size=6144 ../../node_modules/@stencil/core/bin/stencil build",
"node ./scripts/stencil-proxy.mjs",
"tsc -p tsconfig.lit.json",
"node ./scripts/build.mjs --config=tsconfig.lit.json",
"esbuild src/autoloader/index.ts --format=esm --outfile=dist/atomic/autoloader/index.esm.js",
"esbuild src/autoloader/index.ts --format=cjs --outfile=dist/atomic/autoloader/index.cjs.js"
],
Expand Down
87 changes: 87 additions & 0 deletions packages/atomic/scripts/build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {dirname, basename} from 'path';
import {argv} from 'process';
import {
readConfigFile,
getLineAndCharacterOfPosition,
sys,
parseJsonConfigFileContent,
getPreEmitDiagnostics,
createProgram,
flattenDiagnosticMessageText,
} from 'typescript';
import svgTransformer from './svg-transform.mjs';

const args = argv.slice(2);
const configArg = args.find((arg) => arg.startsWith('--config='));
if (configArg === undefined) {
throw new Error('Missing --config=[PATH] argument');
}
const tsConfigPath = configArg.split('=')[1];

function loadTsConfig(configPath) {
const configFile = readConfigFile(configPath, sys.readFile);
if (configFile.error) {
throw new Error(
`Error loading tsconfig file: ${configFile.error.messageText}`
);
}
return parseJsonConfigFileContent(
configFile.config,
sys,
dirname(configPath)
);
}

function emit(program) {
const targetSourceFile = undefined;
const cancellationToken = undefined;
const writeFile = undefined;
const emitOnlyDtsFiles = false;
const customTransformers = {
before: [svgTransformer],
};

return program.emit(
y-lakhdar marked this conversation as resolved.
Show resolved Hide resolved
targetSourceFile,
cancellationToken,
writeFile,
emitOnlyDtsFiles,
customTransformers
);
}

function compileWithTransformer() {
console.log('Using tsconfig:', basename(tsConfigPath));
const {options, fileNames} = loadTsConfig(tsConfigPath);
const program = createProgram(fileNames, options);
const emitResult = emit(program);

const allDiagnostics = getPreEmitDiagnostics(program).concat(
emitResult.diagnostics
);

allDiagnostics.forEach((diagnostic) => {
if (diagnostic.file) {
const {line, character} = getLineAndCharacterOfPosition(
diagnostic.file,
diagnostic.start
);
const message = flattenDiagnosticMessageText(
diagnostic.messageText,
'\n'
);

console.log(
`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`
);
} else {
console.error(flattenDiagnosticMessageText(diagnostic.messageText, '\n'));
}
});

let exitCode = emitResult.emitSkipped ? 1 : 0;
console.log(`Process exiting with code '${exitCode}'.`);
process.exit(exitCode);
}

compileWithTransformer();
66 changes: 66 additions & 0 deletions packages/atomic/scripts/svg-transform.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {readFileSync} from 'fs';
import {basename, dirname, join, resolve} from 'path';
import {
NodeFlags,
isImportDeclaration,
visitEachChild,
visitNode,
} from 'typescript';

function createStatement(factory, svgContent, variableName) {
const bindingName = undefined;
const exclamationToken = undefined;
const modifiers = [];
const {
createVariableStatement,
createVariableDeclarationList,
createVariableDeclaration,
createStringLiteral,
} = factory;

if (variableName === undefined) {
throw new Error(
`Variable name is not defined for the import statement ${node.getText()}`
);
}

return createVariableStatement(
modifiers,
createVariableDeclarationList(
[
createVariableDeclaration(
variableName,
bindingName,
exclamationToken,
createStringLiteral(svgContent)
y-lakhdar marked this conversation as resolved.
Show resolved Hide resolved
),
],
NodeFlags.Const
y-lakhdar marked this conversation as resolved.
Show resolved Hide resolved
)
);
}

/**
* Custom SVG transformer to handle .svg imports.
*/
export default function svgTransformer(context) {
const {factory} = context;

function visit(node) {
y-lakhdar marked this conversation as resolved.
Show resolved Hide resolved
if (isImportDeclaration(node)) {
y-lakhdar marked this conversation as resolved.
Show resolved Hide resolved
const importPath = node.moduleSpecifier.text;
if (importPath.endsWith('.svg')) {
console.log('Replacing SVG import:', basename(importPath));
const dir = dirname(node.getSourceFile().fileName);
const svgPath = resolve(dir, importPath);
const svgContent = readFileSync(svgPath, 'utf8');
const variableName = node.importClause?.name?.escapedText;

return createStatement(factory, svgContent, variableName);
y-lakhdar marked this conversation as resolved.
Show resolved Hide resolved
}
}
return visitEachChild(node, visit, context);
}

return (sourceFile) => visitNode(sourceFile, visit);
}
2 changes: 1 addition & 1 deletion packages/atomic/scripts/watch.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function rebuild() {
const commands = [
'node --max_old_space_size=6144 ../../node_modules/@stencil/core/bin/stencil build',
'node ./scripts/stencil-proxy.mjs',
'tsc -p tsconfig.lit.json',
'node ./scripts/build.mjs --config=tsconfig.lit.json',
'esbuild src/autoloader/index.ts --format=esm --outfile=dist/atomic/autoloader/index.esm.js',
'esbuild src/autoloader/index.ts --format=cjs --outfile=dist/atomic/autoloader/index.cjs.js',
];
Expand Down
Loading