@platform/tmpl
TypeScript icon, indicating that this package has built-in type declarations

0.1.78 • Public • Published

Module License: MIT NPM

Header

Succinct, composable, template stamping pipeline.
Think of it as your scaffolding superpower.

For the out-of-box CLI experience see create-tmpl:

yarn create tmpl

 

Setup

yarn install @platform/tmpl

 

Introduction

Compose directories and files together with glob patterns into a powerful Template that can be copied anywhere...to the file-system, to memory, wherever.

Add simple middleware functions to the pipeline to precisely customize each file as it is written, taking variable arguments (via the API) or values entered by the user (via the command-line).

Interfaces

  • Simple, flexible programmatic control via the API
  • or rich command-line interaction via the CLI.

Philosophy

The best programmers are lazy. If you do anything more than three times, it might be a good idea to automate it 🤖

The create-tmpl module is here to make creating repeatable scaffolding through templates painless, powerful and low-effort. So low effort, in fact, you're more than likely to do it.

Design principles

  • Lean on the file-system.
  • Simple configuration (or "no-configuration").
  • Beautiful command-line that's fast and fun to use.
  • Powerful composability of source files (assemble base template and then make overriding variants).
  • Elegant API for integrating into other modules.
  • Pluggable middleware pipeline for extensibility.

Maxims

 


 

🌳 CLI

Installation

To use the tmpl command-line across your machine install it globally:

yarn global add create-tmpl

then use tmpl from any folder:

$ tmpl <command> [options]
$ tmpl --help

Local Module

To use the tmpl command locally within your scripts, add it to your module:

yarn add create-tmpl

then invoke it from scripts within your package.json like so:

{
  "name": "my-module",
  "scripts": {
    "postinstall": "tmpl ./node_modules/my-module/setup-template"
  },
  "dependencies": {
    "create-tmpl": "latest"
  }
}

Configuration

...TDB


Commands

...TDB

 

Virtues

 

🌳 API

When working with a Template you'll move through three stages:

  1. Template composition
  2. Filters and middleware processors.
  3. Execution

Templates are immutable, meaning any calls to the .add, .filter, .use methods return a new instance of the Template (conceptually similar to rxjs).

 

Composition (add source files)

A template is composed of one or more file locations consisting of a directory and an optional glob pattern (default is **, everything).

import { Template } from 'create-tmpl';

const tmpl = Template.create()
  .add({ dir: './templates/one' })
  .add({ dir: './templates/two', pattern: '**/*.md' });

Template files that are added later which collide will override the earlier paths. Use this capability to create base template folders and then compose together more specialised templates that incrementally expand and alter the base set of files.

To see the resulting files that make up the template:

const files = await tmpl.files();

 

Filtering

Create a subset of the template using filters:

const markdown = tmpl.filter(file => file.path.endsWith('.md'));
const files = await markdown.files(); // Now only markdown files.

 

Middleware

A pipeline of middleware functions provide the mechanism for transforming templates and saving them to the file-system, or wherever you need to send the execution result. Template middleware is conceptually equivalent to express middleware:

import { template, path, fs } from 'create-tmpl';
type IMyVariables = { greeting: string };

const tmpl = template
  .create()
  .add({ dir: './tmpl-1' })
  .add({ dir: './tmpl-2' })

  // Transform the text content of files (naive example 🤭 ).
  .use<IMyVariables>((req, res) => {
    res.replaceText(/__GREETING__/g, req.variables.greeting).next(); // Signal to move to next middleware.
  })

  // Save the file to disk.
  .use(async (req, res) => {
    const dir = path.resolve('./output');
    await fs.ensureDir(dir);
    await fs.writeFile(path.join(dir, req.path), req.buffer);

    // Signal the operation is complete (no more middleware will run).
    res.complete();
  });

Middleware is executed in the order that it is added to the pipeline. Call res.next() to move to the next middleware in the pipeline, or call res.complete() when done, and the execution pipeline finished.

const tmpl = Template.create('./my-tmpl').use(/\.ts$/, (req, res) => {
  // Operate on typescript file only.
  // ...
  res.next();
});

When adding middleware you can optionally apply pathFilter regular-expressions to narrow which file paths the middleware applies to. The example above operates on .ts files only. Passing an array of regular-expressions acts as an OR set.

 

Execution

We now have a configured template that will transform text files and save them to disk when executed.
Let's execute it passing in some variables:

const variables: IMyVariables = { greeting: 'Hello!' };
await tmpl.execute<IMyVariables>({ variables });

 

 

Readme

Keywords

none

Package Sidebar

Install

npm i @platform/tmpl

Weekly Downloads

9

Version

0.1.78

License

MIT

Unpacked Size

56.4 kB

Total Files

22

Last publish

Collaborators

  • philcockfield