Fast and simple JS/TS code generator.
npm install --save-prod codedegen
🔎 API documentation is available here.
The code is represented via arrays nested at arbitrary depth:
import { assembleJs, Code } from 'codedegen';
const code: Code = ['console.log(', ['"Hello"'], ')'];
assembleJs(code);
// ⮕ 'console.log("Hello")'
You can use primitives as values:
const code = [1, '+', 2];
assembleJs(code);
// ⮕ '1+2'
Symbols represent variables:
const varA = Symbol();
const varB = Symbol();
const code = [
'if(', varA, '!==0){',
'return ', varA, '*', varB,
'}'
];
assembleJs(code);
// ⮕ 'if(a!==0){return a*b}'
Create a named variable:
import { assembleJs, createVar, Code } from 'codedegen';
const varFoo = createVar('foo');
assembleJs([varFoo, '!==0']);
// ⮕ 'foo!==0'
If there are multiple variables with the same name, they would still have different names in the generated code:
const varFoo1 = createVar('foo');
const varFoo2 = createVar('foo');
assembleJs([varFoo1, '!==', varFoo2]);
// ⮕ 'foo!==foo2'
You can pass VarRenamer
callback to assembleJs
to have even more control on how variables are named:
import { assembleJs, createVarRenamer } from 'codedegen';
const varA = Symbol();
const varB = Symbol();
const varRenamer = createVarRenamer([[varA, 'X']]);
assembleJs([varA, '===', varB], varRenamer);
// ⮕ 'X===a'
VarRenamer
instance always return the same name for the same variable:
varRenamer(varA) === varRenamer(varA);
// ⮕ true
You can provide a name encoder to createVarRenamer
that converts variable index into a valid JS identifier.
import { assembleJs, createVarRenamer } from 'codedegen';
const varRenamer = createVarRenamer([], index => '_' + index);
assembleJs([Symbol(), '>', Symbol()], varRenamer);
// ⮕ '_0>_1'
You can compile a function directly from the code template:
import { compileFunction } from 'codedegen';
const arg = Symbol();
const varA = Symbol();
const varB = Symbol();
const fn = compileFunction(
// The list of function arguments
[arg],
// The function body
[
'var ', varA, '=123;',
'return ', varA, '+', arg, '+', varB, '.fooBar',
],
// The optional list of variable bindings
[[varB, { fooBar: 456 }]],
);
fn(789);
// ⮕ '1368'
To ease the codegen there's a set of DSL functions which you can use anywhere in your templates.
propAccess
Returns a prop accessor code:
propAccess('obj', 'foo');
// ⮕ 'obj.foo'
propAccess('obj', 9);
// ⮕ 'obj[9]'
propAccess('obj', 'foo bar', true);
// ⮕ 'obj?.["foo bar"]'
You can generate a nested property access code like this:
import { assembleJs, propAcccess } from 'codedegen';
const varA = Symbol();
const varB = Symbol();
assembleJs([
varA, '=', propAcccess(propAccess(varB, 'fooBar', true), 10)
]);
// ⮕ 'a=b?.fooBar[10]'
objectKey
Returns the code of an object key:
objectKey('foo bar');
// ⮕ '"foo bar"'
objectKey('fooBar');
// ⮕ 'fooBar'
objectKey('0');
// ⮕ '0'
objectKey('0123');
// ⮕ '"0123"'
For example, to create an object you can:
import { assembleJs, Code, objectKey } from 'codedegen';
assembleJs([
'{',
objectKey('fooBar'), ':123,',
objectKey('Yes Sir!'), ':456,',
'}',
]);
// ⮕ '{fooBar:123,"Yes Sir!":456,}'
comment
and docComment
Return a code of a comment block:
import { assembleJs } from 'codedegen';
assembleJs(docComment('Yes Sir,\nI Can Boogie'));
varAssign
Returns a variable assignment code:
const varA = Symbol();
const varB = Symbol();
varAssign(varA, [varB]);
// ⮕ 'a=b;'
varAssign(varA, [propAccess(varB, 'fooBar'), '/2']);
// ⮕ 'a=b.fooBar/2'
varDeclare
Returns a variable declaration code:
const varA = Symbol();
varDeclare(varA);
// ⮕ 'var a;'
varDeclare(varA, [123]);
// ⮕ 'var a=123;'
Generated using TypeDoc