// Hooks definition file. // Note: this file is transpiled *on the fly* and evaluated within `eval` within transpilation context. // Take care of current working directory if your hooks rely on it. // Type imports from typescript are permitted import { ImportDeclaration, NumericLiteral, StringLiteral, SyntaxKind } from 'typescript'; // Hooks are defined as array of ElephizeNodeHookEntry items. // Type definition of ElephizeNodeHooksEntry is taken from elephize's .d.ts file. const hooks: ElephizeNodeHookEntry[] = [ { // nodeKind value should be one of typescript's SyntaxKind enum values. // It represents kind of node in the AST to apply hook to. nodeKind: SyntaxKind.NumericLiteral, // Here is the hook itself: a function called when typescript parser finds node of this kind. // Note: in general, hook is called TWICE: once for dry run, and once for code generation. hook: ( // First argument of hook function is a node itself. // It's a good idea to cast the argument to type referred by SyntaxKind above. node: NumericLiteral, // Second argument is elephize compilation context. // It contains numerous settings and methods to use, see elephize's renderers code for details. context ) => { // Hook should return object having one of the following shapes: // { preventDefault: false } - to permit elephize make it's own magic on same node // { preventDefault: true, content: <SOME_STRING> } - to prevent elephize handling of the node and // output <SOME_STRING> right in-place. if (context.dryRun) { // Simplest way to prevent executing hook code twice return { preventDefault: false }; } // Simple example of additional code preprocessing if (node.getText().endsWith('.')) { return { preventDefault: true, content: `1 + ${node.getText()}` }; } else { return { preventDefault: false }; } }, }, { // Some node kinds can't be printed with 'content' property. All content will be ignored during code generation. // ImportDeclaration is one of such node kinds, but there are definitely more, especially statement-based kinds // can be affected with this. If your statement-based hook fails to output some code, this might be it. // We still can read and process those nodes though. For imports, we can read module specifiers and process // imported files in some different manner. nodeKind: SyntaxKind.ImportDeclaration, hook: (node: ImportDeclaration) => { if ((node.moduleSpecifier as StringLiteral).text.endsWith('.css')) { // Here we can do something with css import... return { preventDefault: true, content: '' }; } return { preventDefault: false }; }, }, ]; module.exports = hooks;