npm.io
1.0.0 • Published 8 months ago

@pfeiferio/string-interpolate

Licence
MIT
Version
1.0.0
Deps
0
Size
46 kB
Vulns
0
Weekly
0

@pfeiferio/string-interpolate

Lightweight string interpolation with named placeholders and filter pipelines.

  • No dependencies
  • No template engine
  • No expressions, no loops
  • Built-in and custom filters
  • Safe, test-driven parser

Installation

npm install @pfeiferio/string-interpolate

Basic Usage

import { interpolate } from '@pfeiferio/string-interpolate'

interpolate(
  'Hello {{ user.name }}',
  { user: { name: 'Pascal' } }
)
// → "Hello Pascal"

Nested Placeholders (Dot Notation)

interpolate(
  'ID: {{ order.customer.id }}',
  {
    order: {
      customer: { id: 42 }
    }
  }
)
// → "ID: 42"

Selective Removal of Missing Placeholders

By default, unresolved placeholders are kept when keep=true.

With the remove option, you can explicitly remove selected placeholders when their value is missing, while keeping all others unchanged.

interpolate(
  'Hello {{ user.name }} {{ user.email }}',
  {
    user: { name: 'Pascal' }
  },
  {
    keep: true,
    remove: ['user.email']
  }
)
// → "Hello Pascal "
Behavior
  • remove entries act as prefix paths
  • All placeholders under the given pathare removed if their value is undefined
  • Existing values are never removed
  • remove overrides keep for the specified paths
interpolate(
  'Hello {{ user.email }}',
  {},
  {
    keep: true,
    remove: ['user.email']
  }
)
// → "Hello "

Partial matches do apply:

interpolate(
  'Hello {{ user.email }}',
  {},
  {
    keep: true,
    remove: ['user']
  }
)
// → "Hello "
Options Reference
interpolate(
  template: string,
  replacements: Record<string, unknown>,
  options?: {
    keep?: boolean
    remove?: string[]
    customFilters?: Record<string, FilterFunction>
  }
): string

Filters

Filters are applied using a pipe syntax.

interpolate(
  '{{ name | uppercase }}',
  { name: 'pascal' }
)
// → "PASCAL"

Multiple filters are applied left to right:

interpolate(
  '{{ name | uppercase | truncate length=3 }}',
  { name: 'pascal' }
)
// → "PAS..."

Filter Arguments

Filters receive named arguments using key=value syntax.

interpolate(
  '{{ text | truncate length=4 ending="..." }}',
  { text: 'abcdef' }
)
// → "abcd..."
Argument Rules
  • Arguments are key-value based

  • Values may be:

    • numbers (length=10)
    • booleans (pretty=true)
    • strings (suffix=!!!)
    • quoted strings with spaces (ending="...")
  • No escaping inside quoted strings

  • Whitespace is used as argument separator


Filter Composition

Interpolation is single-pass. If a placeholder resolves to another placeholder expression, filters are not executed immediately. Instead, they are appended to the resulting placeholder expression.


Built-in Filters

Filter Description
uppercase Convert string to upper case
lowercase Convert string to lower case
capitalize Capitalize first character
append Append a suffix
concat Concatenate text
replace Replace all occurrences
ltrim Trim characters from start
rtrim Trim characters from end
trim Trim characters from both sides
truncate Shorten string
default Fallback for undefined
padStart Left-pad string
padEnd Right-pad string
json JSON stringify

Example:

interpolate(
  '{{ value | replace search=" " replace="_" }}',
  { value: 'hello world' }
)
// → "hello_world"

Custom Filters

You can provide custom filters via the options object.

interpolate(
  '{{ name | reverse }}',
  { name: 'abc' },
  {
    customFilters: {
      reverse: (value) =>
        typeof value === 'string'
          ? value.split('').reverse().join('')
          : value
    }
  }
)
// → "cba"

Custom filters override built-in filters with the same name.


Function Values

If a replacement value is a function, it will be executed:

interpolate(
  'Now: {{ now }}',
  {
    now: () => new Date().toISOString()
  }
)

API

interpolate(template, replacements, options?)
interpolate(
  template: string,
  replacements: Record<string, unknown>,
  options?: {
    keep?: boolean,
    customFilters?: Record<string, FilterFunction>
  }
): string

Design Goals

  • Explicit syntax
  • Predictable behavior
  • No hidden magic
  • Easy to extend
  • Safe defaults

This package is not intended to be a full template engine.


License

MIT


Keywords