2.0.0 ā€¢ Published 1 year ago

codedegen v2.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

codedegen šŸ—” build

Fast and simple JS/TS code generator.

npm install --save-prod codedegen

Overview

šŸ”Ž 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}'

Naming variables

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'

Variable renamer

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'

Compiling a function

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'

DSL

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;'
2.0.0

1 year ago

1.1.0

2 years ago

1.0.0

2 years ago