this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

TypeScript 100.0%
7 1 2

Clone this repository

https://tangled.org/tbeseda.com/tagged-string https://tangled.org/did:plc:hhpir4z3l4fwmotc2cvka6ln/tagged-string
git@tangled.org:tbeseda.com/tagged-string git@tangled.org:did:plc:hhpir4z3l4fwmotc2cvka6ln/tagged-string

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

Tagged String#

Extract structured data from strings using tag-based syntax. Zero dependencies, runs natively on Node.js v24+.

import { TaggedStringParser } from 'tagged-string';

const parser = new TaggedStringParser();
const result = parser.parse('[operation:deploy] started with [changes:5] to [stack:prod-stack]');

console.log(result.entities);
// [
//   { type: 'operation', value: 'deploy', parsedValue: 'deploy', inferredType: 'string', ... },
//   { type: 'changes', value: '5', parsedValue: 5, inferredType: 'number', ... },
//   { type: 'stack', value: 'prod-stack', parsedValue: 'prod-stack', inferredType: 'string', ... }
// ]

Installation#

npm install tagged-string

Requires Node.js v24 or later for native TypeScript support.

Usage#

Basic Parsing#

The parser extracts [type:value] tags from strings and automatically infers types:

const parser = new TaggedStringParser();
const result = parser.parse('[count:42] items processed, [enabled:true] flag set');

result.entities.forEach(entity => {
  console.log(entity.type, entity.parsedValue, entity.inferredType);
});
// count 42 number
// enabled true boolean

Schema-Based Parsing#

Define a schema to enforce types and add formatters:

const parser = new TaggedStringParser({
  schema: {
    operation: { type: 'string', format: (v) => v.toUpperCase() },
    changes: { type: 'number', format: (n) => `${n} changes` },
    stack: 'string', // shorthand without formatter
  }
});

const result = parser.parse('[operation:deploy] started with [changes:5] to [stack:prod-stack]');
console.log(result.format());
// "DEPLOY started with 5 changes to prod-stack"

Filtering Entities#

const result = parser.parse('[action:create] [resource:function] with [count:3] instances');

result.getEntitiesByType('action');  // [{ type: 'action', parsedValue: 'create', ... }]
result.getAllTypes();                // ['action', 'resource', 'count']

Custom Delimiters#

const parser = new TaggedStringParser({
  openDelimiter: '{{',
  closeDelimiter: '}}',
  typeSeparator: '=',
  schema: {
    user: { type: 'string', format: (v) => `@${v}` }
  }
});

const result = parser.parse('User {{user=john}} performed {{count=10}} actions');
console.log(result.format());
// "User @john performed 10 actions"

API#

TaggedStringParser#

constructor(config?: ParserConfig)

Config options:

  • openDelimiter (default: '[') - Opening tag delimiter
  • closeDelimiter (default: ']') - Closing tag delimiter
  • typeSeparator (default: ':') - Separator between type and value
  • schema - Entity type definitions with optional formatters
parse(message: string): ParseResult

Extracts all tagged entities from the message.

ParseResult#

Properties:

  • originalMessage: string - The input message
  • entities: Entity[] - Extracted entities in order

Methods:

  • getEntitiesByType(type: string): Entity[] - Filter entities by type
  • getAllTypes(): string[] - Get unique entity types
  • format(): string - Reconstruct message with formatted values

Entity#

interface Entity {
  type: string;                           // Entity type name
  value: string;                          // Raw string value
  parsedValue: string | number | boolean; // Typed value
  formattedValue: string;                 // Formatted display value
  inferredType: 'string' | 'number' | 'boolean';
  position: number;                       // Start position in message
  endPosition: number;                    // End position in message
}

EntitySchema#

type EntitySchema = Record<string, PrimitiveType | EntityDefinition>;

interface EntityDefinition {
  type: 'string' | 'number' | 'boolean';
  format?: (value: any) => string;
}

Type Inference#

Without a schema, the parser infers types automatically:

  • number: Matches /^-?\d+(\.\d+)?$/ (integers and decimals)
  • boolean: 'true' or 'false' (case-insensitive)
  • string: Everything else

Error Handling#

The parser is lenient by design:

  • Malformed tags are skipped
  • Unclosed tags at end of string are ignored
  • Empty tag content is skipped
  • Invalid config throws on construction

Examples#

Run the included examples:

node src/examples.ts

Development#

npm test                    # Run tests
node src/examples.ts        # Run examples

License#

MIT