CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-docusaurus--utils

Node utility functions for Docusaurus packages providing URL handling, file operations, Git integration, i18n, Markdown processing, content visibility, and build utilities.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

core-utilities.mddocs/

Core Utilities

Foundation utilities including hashing, async operations, regular expressions, i18n support, and URL slug generation. These utilities provide essential functionality used throughout the Docusaurus ecosystem.

Types

/**
 * Options for slugger functionality
 */
type SluggerOptions = {
  maintainCase?: boolean;
};

/**
 * Stateful slugger interface for generating unique slugs
 */
type Slugger = {
  slug: (value: string, options?: SluggerOptions) => string;
};

Capabilities

Hashing Utilities

md5Hash

Creates MD5 hash of input string.

/**
 * Creates MD5 hash of input string
 * @param str - String to hash
 * @returns MD5 hash as hexadecimal string
 */
function md5Hash(str: string): string;

simpleHash

Creates truncated MD5 hash of specified length.

/**
 * Creates truncated MD5 hash of specified length
 * @param str - String to hash
 * @param length - Length of hash to return
 * @returns Truncated MD5 hash string
 */
function simpleHash(str: string, length: number): string;

docuHash

Generates kebab-case string with hash suffix, handling filesystem name length limits.

/**
 * Generates kebab-case string with hash suffix
 * @param strInput - Input string to process
 * @param options - Hashing options
 * @param options.hashExtra - Additional string for hash calculation (not in output)
 * @param options.hashLength - Length of hash suffix (default: 3)
 * @returns Kebab-case string with hash suffix
 */
function docuHash(
  strInput: string,
  options?: {
    hashExtra?: string;
    hashLength?: number;
  }
): string;

Usage Examples:

import { md5Hash, simpleHash, docuHash } from "@docusaurus/utils";

// Basic MD5 hashing
const hash = md5Hash("Hello, World!");
console.log(hash); // "65a8e27d8879283831b664bd8b7f0ad4"

// Truncated hash for short identifiers
const shortHash = simpleHash("content-identifier", 8);
console.log(shortHash); // "a1b2c3d4" (first 8 characters of MD5)

// Docusaurus-style hash for file names
const fileName = docuHash("My Very Long Document Title That Might Exceed Limits");
console.log(fileName); // "my-very-long-document-title-that-might-exceed-abc"

// With custom hash length and extra data
const customHash = docuHash("Document Title", {
  hashExtra: "plugin-id-extra-data",
  hashLength: 6
});
console.log(customHash); // "document-title-a1b2c3"

Asynchronous Operations

mapAsyncSequential

Sequential async Array.map where order matters - awaits each action before proceeding.

/**
 * Sequential async Array.map where order matters
 * @param array - Array of items to process sequentially
 * @param action - Async function to apply to each item
 * @returns Promise resolving to array of results in order
 */
function mapAsyncSequential<T, R>(
  array: T[],
  action: (t: T) => Promise<R>
): Promise<R[]>;

findAsyncSequential

Sequential async Array.find where order matters - returns first item matching predicate.

/**
 * Sequential async Array.find where order matters
 * @param array - Array of items to search sequentially
 * @param predicate - Async predicate function
 * @returns Promise resolving to first matching item or undefined
 */
function findAsyncSequential<T>(
  array: T[],
  predicate: (t: T) => Promise<boolean>
): Promise<T | undefined>;

Usage Examples:

import { mapAsyncSequential, findAsyncSequential } from "@docusaurus/utils";

// Process files sequentially (important for rate limiting, file locks, etc.)
const files = ["file1.txt", "file2.txt", "file3.txt"];

const processedFiles = await mapAsyncSequential(files, async (file) => {
  console.log(`Processing ${file}...`);
  await new Promise(resolve => setTimeout(resolve, 1000)); // Simulate work
  return `processed-${file}`;
});
console.log(processedFiles); // ["processed-file1.txt", "processed-file2.txt", ...]

// Find first valid configuration file
const configFiles = ["docusaurus.config.js", "docusaurus.config.ts", "docusaurus.config.mjs"];

const validConfig = await findAsyncSequential(configFiles, async (configFile) => {
  try {
    const exists = await fs.access(configFile);
    return true;
  } catch {
    return false;
  }
});
console.log("Found config:", validConfig); // First existing config file

Regular Expression Utilities

escapeRegexp

Escapes string for safe use in regular expressions.

/**
 * Escapes string for safe use in regular expressions
 * @param string - String to escape
 * @returns Escaped string safe for RegExp constructor
 */
function escapeRegexp(string: string): string;

Usage Example:

import { escapeRegexp } from "@docusaurus/utils";

// Escape special regex characters
const userInput = "How much is $100 + $50?";
const escapedInput = escapeRegexp(userInput);
console.log(escapedInput); // "How much is \\$100 \\+ \\$50\\?"

// Use in regex construction
const searchTerm = "C++";
const escapedTerm = escapeRegexp(searchTerm);
const regex = new RegExp(escapedTerm, "gi");

const text = "I love C++ programming and C++ is great!";
const matches = text.match(regex);
console.log(matches); // ["C++", "C++"]

URL Slug Generation

createSlugger

Factory function creating stateful slugger using github-slugger semantics.

/**
 * Factory function creating stateful slugger using github-slugger semantics
 * @returns Slugger instance with collision avoidance
 */
function createSlugger(): Slugger;

Usage Examples:

import { createSlugger } from "@docusaurus/utils";

// Create slugger instance
const slugger = createSlugger();

// Generate unique slugs
const slug1 = slugger.slug("Getting Started");
console.log(slug1); // "getting-started"

const slug2 = slugger.slug("Getting Started"); // Duplicate!
console.log(slug2); // "getting-started-1" (collision avoided)

const slug3 = slugger.slug("Getting Started Again");
console.log(slug3); // "getting-started-again"

// With case preservation
const slug4 = slugger.slug("API Reference", { maintainCase: true });
console.log(slug4); // "API-Reference" (case maintained)

// Multiple sluggers maintain separate state
const slugger2 = createSlugger();
const freshSlug = slugger2.slug("Getting Started");
console.log(freshSlug); // "getting-started" (fresh instance, no collision)

Internationalization Support

localizePath

Localizes a path by adding current locale (unless it's the default locale).

/**
 * Localizes a path by adding current locale
 * @param params - Localization parameters
 * @param params.pathType - "fs" for filesystem paths, "url" for URL paths
 * @param params.path - Path to be localized
 * @param params.i18n - Current i18n context
 * @param params.options - Localization options
 * @param params.options.localizePath - Override default localization behavior
 * @returns Localized path string
 */
function localizePath(params: {
  pathType: "fs" | "url";
  path: string;
  i18n: I18nContext;
  options?: {
    localizePath?: boolean;
  };
}): string;

mergeTranslations

Shallow-merges multiple translation file contents into one.

/**
 * Shallow-merges multiple translation file contents into one
 * @param contents - Array of translation file contents to merge
 * @returns Merged translation file content
 */
function mergeTranslations(contents: TranslationFileContent[]): TranslationFileContent;

updateTranslationFileMessages

Updates all messages in a translation file using the provided update function.

/**
 * Updates all messages in a translation file using the provided update function
 * @param translationFile - Translation file to update
 * @param updateMessage - Function to transform each message
 * @returns Updated translation file
 */
function updateTranslationFileMessages(
  translationFile: TranslationFile,
  updateMessage: (message: string) => string
): TranslationFile;

getPluginI18nPath

Constructs plugin i18n path from localization directory, plugin name, and optional ID.

/**
 * Constructs plugin i18n path from localization directory, plugin name, and optional ID
 * @param params - Path construction parameters
 * @param params.localizationDir - Base localization directory
 * @param params.pluginName - Plugin name
 * @param params.pluginId - Plugin instance ID (defaults to DEFAULT_PLUGIN_ID)
 * @param params.subPaths - Additional path segments
 * @returns Constructed i18n path
 */
function getPluginI18nPath(params: {
  localizationDir: string;
  pluginName: string;
  pluginId?: string;
  subPaths?: string[];
}): string;

Usage Examples:

import { 
  localizePath,
  mergeTranslations,
  updateTranslationFileMessages,
  getPluginI18nPath 
} from "@docusaurus/utils";

// Localize paths based on current locale
const i18nContext = {
  currentLocale: "fr",
  defaultLocale: "en",
  locales: ["en", "fr", "es"],
};

const localizedUrl = localizePath({
  pathType: "url",
  path: "/docs/intro",
  i18n: i18nContext,
});
console.log(localizedUrl); // "/fr/docs/intro" (for French locale)

const defaultLocaleUrl = localizePath({
  pathType: "url",
  path: "/docs/intro",
  i18n: { ...i18nContext, currentLocale: "en" },
});
console.log(defaultLocaleUrl); // "/docs/intro" (no prefix for default locale)

// Merge translation files
const baseTranslations = {
  "welcome.title": "Welcome",
  "nav.home": "Home",
};

const pluginTranslations = {
  "plugin.title": "My Plugin",
  "nav.home": "Homepage", // Override
};

const merged = mergeTranslations([baseTranslations, pluginTranslations]);
console.log(merged); // { "welcome.title": "Welcome", "nav.home": "Homepage", "plugin.title": "My Plugin" }

// Update translation messages
const translations = {
  message: "Hello {{name}}!",
  description: "A greeting message"
};

const updated = updateTranslationFileMessages(translations, (message) => {
  return message.replace(/{{(\w+)}}/g, "{$1}"); // Convert placeholder format
});
console.log(updated.message); // "Hello {name}!"

// Get plugin i18n path
const pluginPath = getPluginI18nPath({
  localizationDir: "/website/i18n/fr",
  pluginName: "docusaurus-plugin-content-docs",
  pluginId: "default",
  subPaths: ["current"],
});
console.log(pluginPath); // "/website/i18n/fr/docusaurus-plugin-content-docs/default/current"

Install with Tessl CLI

npx tessl i tessl/npm-docusaurus--utils

docs

build-dev.md

config-constants.md

content-management.md

core-utilities.md

data-handling.md

filesystem-paths.md

git.md

index.md

markdown.md

url-web.md

tile.json