Collection of utility functions for string processing, templating, data structures, and object manipulation, including case conversion, template parsing, priority queues, and deep copying capabilities.
Deep copying and object manipulation utilities.
/**
* Deep copy utility that handles circular references and toJSON methods
* Creates a complete deep copy of the input value, handling:
* - Circular references (throws error to prevent infinite recursion)
* - Objects with toJSON methods (calls toJSON for serialization)
* - Arrays, nested objects, and primitive values
* - Date objects, RegExp, and other built-in types
*
* @param value - Value to deep copy
* @returns Deep copy of the input value
* @throws Error if circular reference is detected
*/
function deepCopy<T>(value: T): T;EJS-like template engine with TypeScript support and source map generation.
/**
* Template compilation options
*/
interface TemplateOptions {
/** Module name for source maps */
module?: boolean;
/** File name for source maps and error reporting */
filename?: string;
/** Generate source maps for debugging */
sourceMap?: boolean;
/** Custom variable name for template context (default: 'it') */
variable?: string;
}
/**
* EJS-like template engine with optional source map support
* Compiles template strings into functions that can be executed with context data
* Supports JavaScript expressions, HTML escaping, and raw output
*
* @param content - Template string with embedded expressions
* @param options - Template compilation options
* @returns Function that takes context and returns rendered string
*/
function template<T = {}>(content: string, options?: TemplateOptions): (context: T) => string;
/**
* Parser for template AST (Abstract Syntax Tree)
* Parses template strings into structured AST nodes for analysis
*
* @param content - Template string to parse
* @param options - Parsing options
* @returns Template AST representing the parsed structure
*/
function templateParser(content: string, options?: TemplateOptions): TemplateAst;Types for representing parsed template structure.
/**
* Root template AST node containing all parsed elements
*/
interface TemplateAst {
/** Array of AST nodes representing template content */
content: TemplateAstNode[];
/** Source information for debugging */
source: {
start: number;
end: number;
};
}
/**
* Union type of all possible AST node types
*/
type TemplateAstNode =
| TemplateAstContent
| TemplateAstComment
| TemplateAstEvaluate
| TemplateAstEscape
| TemplateAstInterpolate;
/**
* Static content node (literal text)
*/
interface TemplateAstContent {
kind: 'content';
value: string;
source: { start: number; end: number };
}
/**
* Comment node (<%# comment %>)
*/
interface TemplateAstComment {
kind: 'comment';
value: string;
source: { start: number; end: number };
}
/**
* Evaluation node (<% code %>) - executes JavaScript without output
*/
interface TemplateAstEvaluate {
kind: 'evaluate';
value: string;
source: { start: number; end: number };
}
/**
* HTML escape node (<%- expression %>) - outputs HTML-escaped result
*/
interface TemplateAstEscape {
kind: 'escape';
value: string;
source: { start: number; end: number };
}
/**
* Interpolation node (<%= expression %>) - outputs raw result
*/
interface TemplateAstInterpolate {
kind: 'interpolate';
value: string;
source: { start: number; end: number };
}Comprehensive string manipulation functions for case conversion and text processing.
namespace strings {
/**
* Convert camelCase to snake_case
* @param str - String to convert
* @returns snake_case version of input
*/
function decamelize(str: string): string;
/**
* Convert to kebab-case (dash-separated)
* @param str - String to convert
* @returns kebab-case version of input
*/
function dasherize(str: string): string;
/**
* Convert to camelCase
* @param str - String to convert
* @returns camelCase version of input
*/
function camelize(str: string): string;
/**
* Convert to PascalCase/UpperCamelCase
* @param str - String to convert
* @returns PascalCase version of input
*/
function classify(str: string): string;
/**
* Convert to snake_case
* @param str - String to convert
* @returns snake_case version of input
*/
function underscore(str: string): string;
/**
* Capitalize first letter, leave rest unchanged
* @param str - String to capitalize
* @returns String with first letter capitalized
*/
function capitalize(str: string): string;
/**
* Calculate Levenshtein distance (edit distance) between two strings
* Returns minimum number of single-character edits needed to transform one string into another
* @param a - First string
* @param b - Second string
* @returns Edit distance between the strings
*/
function levenshtein(a: string, b: string): number;
}Tagged template literal functions for string formatting and manipulation.
namespace tags {
/**
* Template literal tag function interface
*/
interface TemplateTag {
(strings: TemplateStringsArray, ...values: any[]): string;
}
/**
* Template tag to join lines into a single line, collapsing whitespace
* Removes line breaks and normalizes spacing
* @param strings - Template string parts
* @param values - Template expression values
* @returns Single-line string
*/
function oneLine(strings: TemplateStringsArray, ...values: any[]): string;
/**
* Template tag factory for consistent indentation
* Creates a template tag that indents all lines by specified amount
* @param spaces - Number of spaces to indent each line
* @returns Template tag function for indenting
*/
function indentBy(spaces: number): TemplateTag;
/**
* Template tag to remove common leading indentation from all lines
* Preserves relative indentation between lines
* @param strings - Template string parts
* @param values - Template expression values
* @returns String with common indentation removed
*/
function stripIndent(strings: TemplateStringsArray, ...values: any[]): string;
/**
* Template tag to remove all leading indentation from all lines
* Makes all lines start at column 0
* @param strings - Template string parts
* @param values - Template expression values
* @returns String with all indentation removed
*/
function stripIndents(strings: TemplateStringsArray, ...values: any[]): string;
/**
* Template tag to remove leading and trailing newlines
* Preserves internal line structure
* @param strings - Template string parts
* @param values - Template expression values
* @returns String with outer newlines trimmed
*/
function trimNewlines(strings: TemplateStringsArray, ...values: any[]): string;
}Advanced data structures for specialized use cases.
/**
* Set with dependency ordering support
* Maintains items in topological order based on dependencies
* Throws errors on circular dependencies or missing dependencies
*/
class PartiallyOrderedSet<T> implements Iterable<T> {
/** Number of items in the set */
readonly size: number;
constructor();
/**
* Add an item with optional dependencies
* @param item - Item to add
* @param deps - Items this item depends on (must be added first)
*/
add(item: T, deps?: Set<T>): this;
/**
* Remove an item from the set
* @param item - Item to remove
* @returns True if item was removed, false if not found
*/
delete(item: T): boolean;
/**
* Check if item exists in the set
* @param item - Item to check
* @returns True if item exists
*/
has(item: T): boolean;
/**
* Clear all items from the set
*/
clear(): void;
/**
* Iterate over items in dependency order
*/
[Symbol.iterator](): Iterator<T>;
/**
* Get items as array in dependency order
* @returns Array of items in topological order
*/
toArray(): T[];
}
/**
* Exception thrown when a required dependency is not found in the set
*/
class DependencyNotFoundException extends BaseException {
constructor(missing: string);
}
/**
* Exception thrown when a circular dependency is detected
*/
class CircularDependencyFoundException extends BaseException {
constructor(cycle: string[]);
}
/**
* Basic priority queue implementation
* Items are ordered by priority value (lower numbers = higher priority)
*/
class PriorityQueue<T> {
/** Number of items in the queue */
readonly size: number;
constructor();
/**
* Add item to queue with specified priority
* @param item - Item to add
* @param priority - Priority value (lower = higher priority)
*/
push(item: T, priority: number): void;
/**
* Remove and return highest priority item
* @returns Highest priority item, or undefined if queue is empty
*/
pop(): T | undefined;
/**
* View highest priority item without removing it
* @returns Highest priority item, or undefined if queue is empty
*/
peek(): T | undefined;
/**
* Check if queue is empty
* @returns True if queue has no items
*/
isEmpty(): boolean;
/**
* Remove all items from the queue
*/
clear(): void;
}Utility functions for working with JavaScript language features.
/**
* Type guard to check if object is Promise-like
* Checks for presence of 'then' method to identify thenable objects
* @param obj - Object to check
* @returns True if object appears to be a Promise
*/
function isPromise(obj: any): obj is Promise<any>;import { strings } from "@angular-devkit/core";
// Case conversions
const camelCase = strings.camelize('hello-world-example'); // 'helloWorldExample'
const pascalCase = strings.classify('hello-world-example'); // 'HelloWorldExample'
const kebabCase = strings.dasherize('HelloWorldExample'); // 'hello-world-example'
const snakeCase = strings.underscore('HelloWorldExample'); // 'hello_world_example'
const decamelized = strings.decamelize('helloWorldExample'); // 'hello_world_example'
const capitalized = strings.capitalize('hello world'); // 'Hello world'
// Edit distance calculation
const distance = strings.levenshtein('kitten', 'sitting'); // 3
console.log(`Edit distance: ${distance}`);import { template } from "@angular-devkit/core";
// Basic template compilation
const tmpl = template(`
Hello <%= name %>!
<% if (showAge) { %>
You are <%= age %> years old.
<% } %>
`);
const result = tmpl({
name: 'Alice',
age: 25,
showAge: true
});
console.log(result);
// Output: "Hello Alice!\n You are 25 years old."
// Template with HTML escaping
const safeTmpl = template(`
<p>Message: <%- userInput %></p>
<p>Raw: <%= userInput %></p>
`);
const safeResult = safeTmpl({
userInput: '<script>alert("xss")</script>'
});
// HTML in userInput is escaped in <%- %> but not in <%= %>import { tags } from "@angular-devkit/core";
// Remove line breaks and normalize spacing
const singleLine = tags.oneLine`
This is a very long
message that spans
multiple lines
`;
console.log(singleLine); // "This is a very long message that spans multiple lines"
// Remove common indentation
const code = tags.stripIndent`
function example() {
console.log('Hello');
return true;
}
`;
console.log(code);
// Output has leading spaces removed but relative indentation preserved
// Add consistent indentation
const indent4 = tags.indentBy(4);
const indented = indent4`
Line 1
Line 2
`;
// Each line is indented by 4 additional spaces
// Remove all indentation
const noIndent = tags.stripIndents`
First line
Second line
Third line
`;
console.log(noIndent);
// Output: "First line\nSecond line\nThird line"import { PartiallyOrderedSet, PriorityQueue } from "@angular-devkit/core";
// Partially ordered set with dependencies
const buildOrder = new PartiallyOrderedSet<string>();
// Add items with dependencies
buildOrder.add('app');
buildOrder.add('utils');
buildOrder.add('components', new Set(['utils']));
buildOrder.add('pages', new Set(['components', 'utils']));
buildOrder.add('main', new Set(['app', 'pages']));
// Iterate in dependency order
for (const item of buildOrder) {
console.log(`Building: ${item}`);
}
// Output: utils, app, components, pages, main
// Priority queue
const tasks = new PriorityQueue<string>();
tasks.push('Low priority task', 10);
tasks.push('High priority task', 1);
tasks.push('Medium priority task', 5);
while (!tasks.isEmpty()) {
const task = tasks.pop();
console.log(`Processing: ${task}`);
}
// Output: High priority task, Medium priority task, Low priority taskimport { deepCopy, isPromise } from "@angular-devkit/core";
// Deep copy complex objects
const original = {
name: 'Test',
config: {
enabled: true,
options: ['a', 'b', 'c']
},
created: new Date()
};
const copy = deepCopy(original);
copy.config.enabled = false;
console.log(original.config.enabled); // true (original unchanged)
console.log(copy.config.enabled); // false
// Promise detection
const maybePromise = someAsyncFunction();
if (isPromise(maybePromise)) {
const result = await maybePromise;
console.log('Got async result:', result);
} else {
console.log('Got sync result:', maybePromise);
}import { templateParser } from "@angular-devkit/core";
const template = `
<h1><%= title %></h1>
<% if (showContent) { %>
<p><%- content %></p>
<% } %>
<%# This is a comment %>
`;
const ast = templateParser(template);
// Analyze AST nodes
for (const node of ast.content) {
switch (node.kind) {
case 'content':
console.log('Static content:', node.value.trim());
break;
case 'interpolate':
console.log('Expression (raw):', node.value);
break;
case 'escape':
console.log('Expression (escaped):', node.value);
break;
case 'evaluate':
console.log('Code block:', node.value);
break;
case 'comment':
console.log('Comment:', node.value);
break;
}
}