
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
A stream-friendly Node.js template system using functions, promises and template literals.
Auto-calling render functions.
const myTemplate = require('..') `You can put anything here now.
Raw HTML, anything.
Including a stream can be done too: ${(env, {file}) => file('file.txt')}.
Note that this is an effective shortcut for \`require('fs').createReadStream('file.txt')\`.
A stream in a promise from a different source is fine too: ${(env, {net}) => net('https://example.com')}.
Note that this is an effective shortcut for
\`\`\`javascript
(opts) => new Promise(r => {
let {URL} = require('url')
let o = 'string' === typeof opts ? new URL(opts) : opts
require(o.protocol.slice(0,-1)).request(o, r)
})
\`\`\`
. See func-y/writer.js#writeFromNet (34:1) for more details.
Promises work too: ${() => new Promise(r => setTimeout(r, 3e3, 'Resolved after 3 seconds'))}.
There's other stuff: ${(env, write) => write.all(123, 'Mix and match', Infinity, String.fromCodePoint(0x2026), new Promise(r => setTimeout(r, 2e3, 'with random timing')), () => 'and subfunctions if memory is an issue?')}`
module.exports = myTemplate
The above will result in the following array:
[ 'You can put anything here now.\n\nRaw HTML, anything.\n\nIncluding a stream can be done too: ',
[Function],
'.\n\nNote that this is an effective shortcut for `require(\'fs\').createReadStream(\'file.txt\')`.\n\nA stream in a promise from a different source is fine too: ',
[Function],
'.\n\nNote that this is an effective shortcut for\n\n```javascript\n(opts) => new Promise(r => {\n let {URL} = require(\'url\')\n let o = \'string\' === typeof opts ? new URL(opts) : opts\n require(o.protocol.slice(0,-1)).request(o, r)\n})\n```\n\n. See func-y/writer.js#writeFromNet (34:1) for more details.\n\nPromises work too: ',
[Function],
'.\n\nThere\'s other stuff: ',
[Function] ]
For named templates (like this README.md from test/README.js), there are several options:
const README = require('../named')('README.md', 'text/markdown') `# Func - y (funk-ee)
Auto-calling render functions.
## Features
* Streams (see below)
* Promises (see below)
* HTML safe: ${(e, {text}) => text('Ohoh <sript src="//example.com/script"></script>')} is all escaped by the write.text() function.
* Streams can be throw through there too if you don't trust a file.
## Usage
### Unnamed templates
\`\`\`javascript
${(env, { file }) => file([__dirname, './template.js'])}
\`\`\`
The above will result in the following array:
\`\`\`javascript
${({ util }) => util.inspect(require('./template.js'), false, 3, false)}
\`\`\`
### Named templates
For named templates (like this README.md from [\`test/README.js\`](./test/README.js)), there are several options:
\`\`\`javascript
${(env, write) => write.file([__dirname, './README.js'])}
\`\`\`
Results in a data like this:
\`\`\`javascript
${({ util }) => util.inspect(README, false, 4, false)}
\`\`\`
${
(env, write) => write.all(
write.file([__dirname, 'api.md']),
'\n\n',
write.file([__dirname, 'alts.md'])
)
}`
const env = { util: require('util') }
README.writeToFile(require('path').join(__dirname, '../README.md'), {
overwrite: true, env
}).then(console.log, console.error)
README.writeTo(process.stdout, env, false).catch(console.error)
module.exports = README
Results in a data like this:
{ name: 'README.md',
type: 'text/markdown',
template:
[ '# Func - y (funk-ee)\n\nAuto-calling render functions.\n\n## Features\n\n* Streams (see below)\n* Promises (see below)\n* HTML safe: ',
[Function],
' is all escaped by the write.text() function.\n * Streams can be throw through there too if you don\'t trust a file.\n\n## Usage\n\n### Unnamed templates\n\n```javascript\n',
[Function],
'\n```\n\nThe above will result in the following array:\n\n```javascript\n',
[Function],
'\n```\n\n### Named templates\n\nFor named templates (like this README.md from [`test/README.js`](./test/README.js)), there are several options:\n\n```javascript\n',
[Function],
'\n```\n\nResults in a data like this:\n\n```javascript\n',
[Function],
'\n```\n\n',
[Function] ],
middleware: [Function: middleware],
createMiddleWare: [Function: createMiddleWare],
writeTo: [Function: writeTo],
writeToFile: [Function: writeToFile] }
const {template, named, namedMiddleware} = require('func-y')
// require('func-y') === require('func-y').template
let arr = template`
* Text string
* ${'other data'}
* ${1234e6}
* ${() => 'a function'}
* ${env => env.data}
* ${({data}) => data}
* ${(env, write) => write('text and ').then(() => env.aPromise = new Promise(r => setTimeout(r,32, 'a promise')))}
* ${async env => await env.aPromise}
* ${(env, write) => write.next(/* err */ /*, data */)}
* ${
// etc
''
}`
let keyed = named('key', 'application/mimetype') `Roughly the same as above.
${() => new Promise(r => setTimeout(r, 1e3, 'Really.'))}
${() => new Promise(r => setTimeout(r, 1e3, 'Seriously.'))}`
keyed.writeTo(process.stdout, {/* ...env */}, false)
// (writable, env, autoclose)
keyed.writeToFile('test.txt', {overwrite: false, encoding: 'utf8'})
// (filename, {...options})
// Express ready:
const app = require('express')()
app.use(keyed.createMiddleWare())
// can use in different part of the app
const sub = require('express')
sub.use(namedMiddleware('key'))
and so-on and so-fourth.
See the documents internals in named.js, template.js, writer.js and write-file.js.
Meanwhile, index.js just holds everything together. I think.
func-y will render on-the-fly as an alternative to the collect-and-display of similar systems, such as HyperHTML/ViperHTML and lit-html styles.
First-render is exceedingly fast if the main styles are available.
A simple for await or for (const thing of source) await write(stuff(thing))
It is a streaming based parser/builder, and capable of all of the same things as the Hyper and lit server side renderers are.
It has a set of built in write functions (sequential write.all(data, data, data, ...datas), write.next(err, data), write.text(unsafe_string) and plain write(data)).
It's capable of writing/caching files (less useful with the exception of heavy stuff like markdown/markdown-it).
It handles streams, promises and delays consistently.
Can puke in data from anywhere (including different sites)
It handles all data types (except symbol) in a consistent fashion.
It's fast and (primarily) in-memory.
It's lightweight, and capable of all of the above out-of-the-box (in node).
If looking for a highly interactive DOM, use hyperhtml/viperhtml.
If looking for a simple streaming HTML (or just anything text based) output, use this.
TL;DR it's function based sequential data collection/export with enough extras to be used... basically anywhere.
FAQs
A stream-friendly Node.js template system using functions, promises and template literals.
We found that func-y demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.