@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
Maintainers
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-resourcesQuick 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:
- Exact match: specified language + specified role
- Language fallback: specified language + default role
- Role fallback: default language + specified role
- Full fallback: default language + default role
- 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 cacheResource 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 | ResourceDataoptions: LoadOptions (optional)
Returns: Promise<ResourceData>
getItem(options?)
Retrieves a Proxy object for accessing resources with dynamic property access.
Parameters:
options: GetOptions (optional)language: stringrole: stringdefaultValue: 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: LanguageCoderole: 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:uiBuilding
# Build TypeScript to JavaScript
npx tsc
# Generate documentation
npm run doc # JSDoc
npm run doc:typedoc # TypeDoc
npm run doc:all # BothLinting
# Run ESLint
npm run lint
# Fix auto-fixable issues
npm run lint:fixLicense
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.
