npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vvlad1973/strings-resources

v1.3.1

Published

A TypeScript library for managing multilingual string resources with support for language and role-based categorization

Downloads

147

Readme

@vvlad1973/strings-resources

A TypeScript library for managing multilingual string resources with support for language and role-based categorization. This package provides internationalization (i18n) capabilities for applications with flexible resource loading and fallback mechanisms.

Features

  • Multiple input data formats support (arrays, objects, nested structures)
  • Language and role-based resource categorization
  • Intelligent fallback chain for missing translations
  • Caching mechanism for optimized performance
  • JSON Schema validation
  • Support for legacy data formats
  • Include/file directives for modular resource loading
  • Full TypeScript support with strict typing
  • Comprehensive logging capabilities

Installation

You can install the package via npm:

npm install @vvlad1973/strings-resources

Quick Start

import Strings from '@vvlad1973/strings-resources';

// Create instance with default language and role
const strings = new Strings({
  defaultLanguage: 'en',
  defaultRole: 'guest',
  defaultValue: 'N/A'
});

// Load resources
await strings.loadResources([
  { language: 'en', role: 'guest', key: 'HELLO', value: 'Hello' },
  { language: 'en', role: 'admin', key: 'HELLO', value: 'Welcome, Admin' },
  { language: 'fr', role: 'guest', key: 'HELLO', value: 'Bonjour' },
]);

// Access strings using direct property access
console.log(strings.HELLO); // Output: 'Hello'

Usage

Creating an Instance

import Strings from '@vvlad1973/strings-resources';

const strings = new Strings({
  defaultLanguage: 'en',      // Default language code (ISO 639-1)
  defaultRole: 'guest',       // Default role code
  defaultValue: '<missing>',  // Fallback value for missing keys
  basePath: process.cwd(),    // Base path for file loading
  logLevel: 'info'            // Logging level: 'trace' | 'debug' | 'info' | 'warn' | 'error'
});

Loading Resources

1. Array Format

Simple array of objects with explicit language, role, key, and value:

const resources = [
  { language: 'en', role: 'admin', key: 'HELLO', value: 'Hello admin' },
  { language: 'en', role: 'admin', key: 'GOODBYE', value: 'Goodbye admin' },
  { language: 'en', role: 'guest', key: 'HELLO', value: 'Hello guest' },
  { language: 'en', role: 'guest', key: 'GOODBYE', value: 'Goodbye guest' },
  { language: 'fr', role: 'admin', key: 'HELLO', value: 'Bonjour admin' },
  { language: 'fr', role: 'admin', key: 'GOODBYE', value: 'Au revoir admin' },
  { language: 'fr', role: 'guest', key: 'HELLO', value: 'Bonjour guest' },
  { language: 'fr', role: 'guest', key: 'GOODBYE', value: 'Au revoir guest' },
];

await strings.loadResources(resources);

2. Structured Object Format

Organized by language with role blocks:

const resources = {
  en: [
    {
      role: 'admin',
      strings: {
        HELLO: 'Hello admin',
        GOODBYE: 'Goodbye admin',
      },
    },
    {
      role: 'guest',
      strings: {
        HELLO: 'Hello guest',
        GOODBYE: 'Goodbye guest',
      },
    },
  ],
  fr: [
    {
      role: 'guest',
      strings: {
        HELLO: 'Bonjour',
        GOODBYE: 'Au revoir',
      },
    },
  ],
};

await strings.loadResources(resources);

3. Loading from File

// Load from JSON file
await strings.loadResources('./resources/strings.json');

// With options
await strings.loadResources('./resources/strings.json', {
  clearResources: true,      // Clear existing resources before loading
  needValidation: true,      // Validate against JSON schema
  basePath: './resources'    // Base path for file resolution
});

4. Multi-Role Resources

Assign the same string to multiple roles:

const resources = [
  {
    language: 'en',
    role: ['admin', 'guest', 'moderator'],  // Multiple roles
    key: 'WELCOME',
    value: 'Welcome to our application!'
  }
];

await strings.loadResources(resources);

5. Legacy Data Format

Support for custom field names:

const legacyData = [
  { _id: 'HELLO', Text: 'Hello' },
  { _id: 'GOODBYE', Text: 'Goodbye' },
];

await strings.loadResources(legacyData, {
  keyFieldName: '_id',      // Custom key field name
  valueFieldName: 'Text'    // Custom value field name
});

Retrieving Resources

1. Direct Property Access

When default language and role are set:

const strings = new Strings({
  defaultLanguage: 'en',
  defaultRole: 'guest'
});

await strings.loadResources(resources);

console.log(strings.HELLO);    // 'Hello guest'
console.log(strings.GOODBYE);  // 'Goodbye guest'

2. Using getItem() Method

For specific language/role combinations:

const item = strings.getItem({
  language: 'fr',
  role: 'admin'
});

console.log(item.HELLO);    // 'Bonjour admin'
console.log(item.GOODBYE);  // 'Au revoir admin'

3. Using getResources() Method

Get all resources for a language/role:

const resources = strings.getResources({
  language: 'en',
  role: 'guest'
});

console.log(resources);
// { HELLO: 'Hello guest', GOODBYE: 'Goodbye guest' }

4. Using withDefaults() Method

Create a new context with different defaults:

const strings = new Strings({
  defaultLanguage: 'en',
  defaultRole: 'admin'
});

await strings.loadResources(resources);

const frenchGuest = strings.withDefaults('fr', 'guest');

console.log(strings.HELLO);        // 'Hello admin'
console.log(frenchGuest.HELLO);    // 'Bonjour guest'

Fallback Mechanism

The library uses an intelligent fallback chain when a resource is not found:

  1. Exact match: specified language + specified role
  2. Language fallback: specified language + default role
  3. Role fallback: default language + specified role
  4. Full fallback: default language + default role
  5. Default value: configured defaultValue

Example:

const strings = new Strings({
  defaultLanguage: 'en',
  defaultRole: 'guest',
  defaultValue: '<not found>'
});

await strings.loadResources([
  { language: 'en', role: 'guest', key: 'HELLO', value: 'Hello' },
  { language: '', role: '', key: 'HELLO', value: 'Hi everyone' },
]);

const item = strings.getItem({ language: 'de', role: 'admin' });

// Fallback chain:
// 1. de:admin - not found
// 2. de:guest - not found
// 3. en:admin - not found
// 4. en:guest - found! Returns 'Hello'
console.log(item.HELLO); // 'Hello'

Advanced Features

Caching

The library automatically caches resource lookups for improved performance:

const item = strings.getItem({ language: 'en', role: 'guest' });
const value1 = item.HELLO; // Performs lookup
const value2 = item.HELLO; // Retrieved from cache

Resource Merging

By default, loadResources() merges new resources with existing ones:

await strings.loadResources({ en: { guest: { HELLO: 'Hello' } } });
await strings.loadResources({ en: { guest: { GOODBYE: 'Bye' } } });

// Both HELLO and GOODBYE are available
console.log(strings.HELLO);    // 'Hello'
console.log(strings.GOODBYE);  // 'Bye'

To clear existing resources before loading:

await strings.loadResources(newResources, { clearResources: true });

Validation

Enable JSON Schema validation for data integrity:

await strings.loadResources(resources, {
  needValidation: true  // Validates data against built-in schemas
});

Validation uses JSON schemas located in the package's schemas/ directory. You can customize validation in several ways:

// Use custom schema location
await strings.loadResources(resources, {
  needValidation: true,
  schemasPath: './my-schemas'
});

// Use external DataValidator with custom schemas
import { DataValidator } from '@vvlad1973/data-validator';

const validator = new DataValidator({ schemasDir: './shared-schemas' });
await validator.isReady();

await strings.loadResources(resources, {
  dataValidator: validator
});

// Use external StringsResourcesProcessor with custom logic
import { StringsResourcesProcessor } from '@vvlad1973/strings-resources';

const processor = new StringsResourcesProcessor({
  logger: customLogger,
  keyFieldName: '_id',
  valueFieldName: 'Text'
});

await strings.loadResources(resources, {
  dataProcessor: processor
});

For detailed schema format documentation, see SCHEMAS.md.

Logging

Configure logging for debugging:

const strings = new Strings({
  logLevel: 'debug'  // 'trace' | 'debug' | 'info' | 'warn' | 'error'
});

// Or provide external logger
import SimpleLogger from '@vvlad1973/simple-logger';

const logger = new SimpleLogger();
const strings = new Strings({
  externalLogger: logger
});

TypeScript Support

The library is written in TypeScript and provides full type definitions:

import Strings, {
  ResourceData,
  ResourcesDataBulk,
  LanguageCode,
  RoleCode,
  GetOptions,
  LoadOptions
} from '@vvlad1973/strings-resources';

// Full type safety
const data: ResourceData = {
  en: {
    guest: {
      HELLO: 'Hello'
    }
  }
};

const options: LoadOptions = {
  clearResources: false,
  needValidation: true
};

await strings.loadResources(data, options);

Supported Language Codes

The library supports all ISO 639-1 language codes, including:

af, sq, ar, hy, az, eu, be, bn, bs, bg, ca, zh, hr, cs, da, nl, en, eo, et, fi, fr, ka, de, el, gu, ht, he, hi, hu, is, id, ga, it, ja, kn, kk, km, ko, ku, ky, lo, lv, lt, mk, mg, ms, ml, mt, mi, mr, mn, ne, no, or, ps, fa, pl, pt, pa, ro, ru, sa, gd, sr, si, sk, sl, es, sw, sv, tl, ta, te, th, tr, uk, ur, uz, vi, cy, xh, yi, yo, zu

Additionally, empty string ('') is supported as a default/fallback language.

API Reference

Constructor

new Strings(options?: StringsConstructorParams)

Methods

loadResources(resources, options?)

Loads string resources from various sources.

Parameters:

  • resources: string | ResourcesDataBulk | ResourceData
  • options: LoadOptions (optional)

Returns: Promise<ResourceData>

getItem(options?)

Retrieves a Proxy object for accessing resources with dynamic property access.

Parameters:

  • options: GetOptions (optional)
    • language: string
    • role: string
    • defaultValue: string

Returns: Proxy object with string resources

getResources(options?)

Retrieves resources for a specific language and role combination.

Parameters:

  • options: GetOptions (optional)

Returns: Record<string, string> | undefined

withDefaults(language, role)

Returns a new Proxy instance with specified default language and role.

Parameters:

  • language: LanguageCode
  • role: RoleCode

Returns: Strings (Proxy)

Documentation

Full API documentation is available in the docs directory.

TypeDoc documentation is available in the docs/typedoc directory.

Testing

# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

# Run tests with UI
npm run test:ui

Building

# Build TypeScript to JavaScript
npx tsc

# Generate documentation
npm run doc          # JSDoc
npm run doc:typedoc  # TypeDoc
npm run doc:all      # Both

Linting

# Run ESLint
npm run lint

# Fix auto-fixable issues
npm run lint:fix

License

This project is licensed under the MIT License with Commercial Use.

Author

Vladislav Vnukovskiy [email protected]

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Changelog

See CHANGELOG.md for release history.