TagScript
A sandboxed template language for text your users write.
TagScript is for the case where the person writing the template is not the person who wrote the app. A Discord server admin building a custom command. A user customising their profile. A support team editing an auto-reply.
You cannot hand those people a JavaScript template literal, Handlebars or EJS, because all three assume the template author is trusted. TagScript assumes the opposite.
import { Interpreter, RandomParser } from 'tagscript';
const ts = new Interpreter(new RandomParser());
(await ts.run('{random:heads,tails}')).body; // 'tails'
(await ts.run('{if(1==1):yes|no}')).body; // '{if(1==1):yes|no}', no IfStatementParser registeredThere is no host object to reach, no prototype to walk, no require to find. An unknown tag is not an error and not a crash. It stays in the output as literal text.
What that buys you
A capability allowlist. The interpreter has no built-in tags. new Interpreter() renders plain text and nothing else, so what a template can do is exactly the list of parsers you passed in.
Templates ask, they never do. A template cannot send a message, delete a message or set a cooldown. It records a request on response.actions, and your code reads that object and decides. The Discord plugin is built entirely on this.
Bounded work. charLimit caps how much output one render may produce, so nobody hands you a template that expands forever.
Data you choose to expose. Values reach a template through transformers, which answer with a fixed set of keys and never the object underneath.
Install
npm install tagscriptStart here
Which page you want depends on which side of the template you are on.
| You are | Read |
|---|---|
| Adding TagScript to an app | Getting started, then running templates |
| Writing templates in someone's app | Syntax, then the tag reference |
| Building a Discord bot | Discord plugin |
| Looking for a specific class | API reference |
Every tag page has a section for template authors and a section for developers, so the same page works
whether you are writing {if(...)} or registering IfStatementParser.
Buy me some doughnuts
If you want to support me by donating, you can do so by using any of the following methods. Thank you very much in advance!
Contributors
Thanks goes to these wonderful people:
Last updated on
