New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

intl-schematic

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

intl-schematic - npm Package Compare versions

Comparing version 0.0.0 to 0.0.1

dist/es/plugins/array-record.d.ts

12

dist/es/index.d.ts
import type { Translation, TranslationProxy } from './ts.schema';
import type { Processors, defaultProcessors } from './processors';
import type { Plugin } from './plugins';
import type { Plugin } from './plugins/core';
export * from './ts.schema.d';
interface Options<P extends Processors, Locale extends Translation> {
processors?: P;
plugins?: Plugin<Locale>[];
plugins?: Plugin<Locale, P>[];
}
/**
* Creates a translation function (commonly known as `t()` or `$t()`)
*
* @param getLocaleDocument should return a translation document
* @param currentLocaleId should return a current Intl.Locale
* @param options
* @returns a tranlation function that accepts a key to look up in the translation document
*/
export declare const createTranslator: {

@@ -10,0 +18,0 @@ <Locale extends Translation>(getLocaleDocument: () => Locale | undefined, currentLocaleId: () => Intl.Locale | undefined, options?: Omit<Options<typeof defaultProcessors, Locale>, 'processors'>): TranslationProxy<Locale, typeof defaultProcessors>;

119

dist/es/index.js

@@ -1,58 +0,26 @@

import { ResolveMissingKeyPlugin, callPlugins } from './plugins';
import { callPlugins } from './plugins/core';
export * from './ts.schema.d';
const isProcessedKey = (k) => 'processor' in k && typeof k['processor'] === 'object';
/**
* Creates a translation function (commonly known as `t()` or `$t()`)
*
* @param getLocaleDocument should return a translation document
* @param currentLocaleId should return a current Intl.Locale
* @param options
* @returns a tranlation function that accepts a key to look up in the translation document
*/
export const createTranslator = (getLocaleDocument, currentLocaleId, options = {}) => {
const { processors = {}, plugins = [ResolveMissingKeyPlugin], } = options;
const plugin = callPlugins(plugins);
const localizedProcessorsByLocale = {};
function getLocalizedProcessors() {
const localeId = currentLocaleId();
if (!localeId) {
return {};
}
return Object.keys(processors).reduce((obj, key) => ({
...obj,
[key]: processors[key](localeId),
}), {});
}
return function translate(key, input, parameter) {
var _a;
const { processors = {}, plugins = [], } = options;
const translate = function (key, input, parameter) {
const doc = getLocaleDocument();
const call = (hook, value, processor, _input = input) => plugin(hook, key, _input, value, processor, doc) ?? key;
const callHook = (hook, value, processor, _input = input) => callPluginsHook(hook, value, _input, parameter, currentLocaleId, key, doc, processor) ?? key;
if (!doc) {
return call('docNotFound');
return callHook('docNotFound');
}
const localizedProcessors = (localizedProcessorsByLocale[_a = String(currentLocaleId()?.baseName)] ?? (localizedProcessorsByLocale[_a] = getLocalizedProcessors()));
const currentKey = doc[key];
if (typeof currentKey === 'undefined') {
return call('keyNotFound');
return callHook('keyNotFound');
}
// Process an array record (["Some text", "translation-key"])
// TODO: move into a plugin
if (Array.isArray(currentKey)) {
const result = currentKey.reduce((arr, refK) => {
if (typeof refK !== 'string') {
const refParamK = Object.keys(refK)[0];
if (refParamK.startsWith('input:')) {
const key = refParamK.replace('input:', '');
const value = input?.[key];
return [
...arr,
// TOOD: add a way to get a stringifier for a processors input
String(value)
];
}
if (refK.__ignore) {
return arr;
}
return [...arr, translate(refParamK, input?.[refParamK], parameter?.[refParamK])];
}
if (!refK.startsWith('input:')) {
return [...arr, translate(refK, input?.[refK], parameter?.[refK])];
}
const _input = input;
const inputKey = refK.replace('input:', '');
return [...arr, _input[inputKey]];
}, []).join(' ');
return call('keyProcessed', result);
// Process a plain-string
if (typeof currentKey !== 'object' && typeof currentKey !== 'function') {
return currentKey ? callHook('keyProcessed', currentKey) : callHook('keyNotFound');
}

@@ -62,51 +30,10 @@ // Process a function record

if (typeof currentKey === 'function') {
const inputContainsArgs = typeof input === 'object' && input && 'args' in input && Array.isArray(input.args);
return call('keyProcessed', currentKey(...(inputContainsArgs ? input.args : [])));
return callHook('keyProcessed', currentKey(...(Array.isArray(input) ? input : [])));
}
// Process a plain-string
if (typeof currentKey !== 'object') {
return currentKey ? call('keyFound', currentKey) : call('keyNotFound');
}
// Process an object record that doesn't specify a processor
// TODO: move into a plugin
if (!isProcessedKey(currentKey)) {
return call('keyProcessed', Object.keys(currentKey).map((refKey) => {
const inputForKey = typeof input === 'object' && input ? input[refKey] : {};
const translated = translate(refKey, (typeof input === 'object' && input
? mergeInputs(currentKey[refKey], inputForKey ?? null)
: currentKey[refKey]));
return translated;
}).join(' ').replace(/\s+/, ' '));
}
// Process a parametrized record using a processor:
// TODO: move into a plugin
const processorName = Object.keys(currentKey.processor)[0];
const processor = localizedProcessors[processorName];
if (!processor) {
return call('processorNotFound', key, processorName);
}
// Delete undefined keys to make defaults bypass them in the spread later
const mergedInput = mergeInputs(currentKey.input, input);
const mergedParameter = {
...currentKey.parameter,
...parameter,
};
const getProcessedResult = processor(mergedParameter, key, doc);
const result = getProcessedResult(mergedInput, mergedParameter);
return result
? call('keyProcessed', result, processorName)
: (call('keyNotProcessed', result, processorName) ?? call('keyNotFound', result, processorName));
return callHook('keyFound', currentKey);
};
const callPluginsHook = callPlugins(translate, plugins);
// Initialize plugins
callPluginsHook('initPlugin', processors, undefined, undefined, currentLocaleId, '', undefined, undefined);
return translate;
};
function mergeInputs(baseInput, input) {
if (typeof input === 'object' && input != null) {
for (const prop in input)
if (input[prop] == null) {
delete input[prop];
}
}
const mergedInput = typeof baseInput === 'object' && typeof input === 'object'
? { ...baseInput, ...input }
: (input ?? baseInput);
return mergedInput;
}

@@ -5,4 +5,4 @@ import { writeFile } from 'fs/promises';

const schema = await compileFromFile('./src/translation.schema.json');
const schema = await compileFromFile('./translation.schema.json');
await writeFile('./src/translation.schema.d.ts', schema);
{
"name": "intl-schematic",
"version": "0.0.0",
"version": "0.0.1",
"license": "MIT",

@@ -11,4 +11,4 @@ "repository": {

".": "./src/index",
"./processors": "./src/processors",
"./plugins": "./src/plugins",
"./processors": "./src/processors/index",
"./plugins": "./src/plugins/index",
"./translation.schema": "./src/translation.schema",

@@ -23,6 +23,6 @@ "./ts.schema": "./src/ts.schema"

"processors": [
"./src/processors.ts"
"./src/processors/index.ts"
],
"plugins": [
"./src/plugins.ts"
"./src/plugins/index.ts"
],

@@ -35,3 +35,3 @@ "translation.schema": [

"types": "src/index",
"main": "dist/es/index",
"main": "src/index",
"type": "module",

@@ -42,5 +42,6 @@ "scripts": {

"build:next": "tsc --outDir dist/esnext --module esnext",
"build": "npm run build:es && npm run build:next",
"dev": "tsc --noEmit -w",
"commit-build": "(git diff --quiet && git diff --staged --quiet) || (git commit -am \"Update dist\")",
"preversion": "npm t && npm run build && npm run commit-build",
"preversion": "npm run build && npm run commit-build",
"prerelease": "npm version prerelease --preid=rc",

@@ -47,0 +48,0 @@ "pre-patch": "npm version prerelease --preid=rc",

@@ -36,8 +36,36 @@ # intl-schematic (WIP)

Comprehensive documentation is in progress.
See a simplified example below and don't be afraid to take a look into the sources to find out more.
### Define a translation document
### Define a function that returns a translation document
```js
const en = {
"hello": "Hello, World!",
"hello-name": name => `Hello, ${name}!`
};
```
### Define functions that return a translation document and a locale
```js
const getDocument = () => en;
const getLocale = () => new Intl.Locale('en')
```
### Create a translator function (`t()`)
```js
import { createTranslator } from 'intl-schematic';
const t = createTranslator(getDocument, getLocale);
```
### Use a translator function
```js
console.log(t('hello')); // `Hello, World!`
console.log(t('hello-name', ['Bob'])); // `Hello, Bob!`
```
import type { LocaleInputParameter, LocaleKey, LocaleOptionsParameter, Translation, TranslationProxy } from './ts.schema';
import type { InputObject, ParameterObject, ParametrizedTranslationRecord } from './translation.schema';
import type { Processor, Processors, defaultProcessors } from './processors';
import { ResolveMissingKeyPlugin, callPlugins } from './plugins';
import type { Plugin } from './plugins';
import type { Processors, defaultProcessors } from './processors';
import { callPlugins } from './plugins/core';
import type { Plugin } from './plugins/core';
export * from './ts.schema.d';
const isProcessedKey = (k: object): k is ParametrizedTranslationRecord => 'processor' in k && typeof k['processor'] === 'object';
// TODO: decouple processor architecture from plugins
interface Options<P extends Processors, Locale extends Translation> {
processors?: P;
plugins?: Plugin<Locale>[];
plugins?: Plugin<Locale, P>[];
}
/**
* Creates a translation function (commonly known as `t()` or `$t()`)
*
* @param getLocaleDocument should return a translation document
* @param currentLocaleId should return a current Intl.Locale
* @param options
* @returns a tranlation function that accepts a key to look up in the translation document
*/
export const createTranslator: {

@@ -28,3 +34,2 @@ <Locale extends Translation>(

): TranslationProxy<Locale, P>;
} = <Locale extends Translation>(

@@ -37,23 +42,6 @@ getLocaleDocument: () => Locale | undefined,

processors = {} as Processors,
plugins = [ResolveMissingKeyPlugin],
plugins = [],
} = options;
const plugin = callPlugins(plugins);
const localizedProcessorsByLocale: Record<string, Record<string, ReturnType<Processor>>> = {};
function getLocalizedProcessors() {
const localeId = currentLocaleId();
if (!localeId) {
return {};
}
return Object.keys(processors).reduce((obj, key) => ({
...obj,
[key]: processors[key as keyof Processors](localeId),
}), {} as Record<string, ReturnType<Processor>>);
}
return function translate<K extends LocaleKey<Locale>>(
const translate = function <K extends LocaleKey<Locale>>(
key: K,

@@ -65,67 +53,22 @@ input?: LocaleInputParameter<Locale, LocaleKey<Locale>, Processors>,

const call = (
hook: keyof Omit<Plugin<Locale>, 'name'>,
value?: string,
const callHook = (
hook: keyof Omit<Plugin<Locale, Processors>, 'name'>,
value?: unknown,
processor?: string,
_input: typeof input = input,
) => plugin(hook, key, _input, value, processor, doc) ?? key;
) => callPluginsHook(hook, value, _input, parameter, currentLocaleId, key, doc, processor) ?? key;
if (!doc) {
return call('docNotFound');
return callHook('docNotFound');
}
const localizedProcessors = (
localizedProcessorsByLocale[String(currentLocaleId()?.baseName)] ??= getLocalizedProcessors()
);
const currentKey = doc[key];
if (typeof currentKey === 'undefined') {
return call('keyNotFound');
return callHook('keyNotFound');
}
// Process an array record (["Some text", "translation-key"])
// TODO: move into a plugin
if (Array.isArray(currentKey)) {
const result = currentKey.reduce((arr, refK) => {
if (typeof refK !== 'string') {
const refParamK = Object.keys(refK)[0] as K;
if (refParamK.startsWith('input:')) {
const key = refParamK.replace('input:', '');
const value = (input as Record<string, typeof input>)?.[key];
return [
...arr,
// TOOD: add a way to get a stringifier for a processors input
String(value)
];
}
if (refK.__ignore) {
return arr;
}
return [...arr, translate(
refParamK,
(input as Record<string, typeof input>)?.[refParamK],
(parameter as Record<string, typeof parameter>)?.[refParamK]
)];
}
if (!refK.startsWith('input:')) {
return [...arr, translate(
refK as K,
(input as Record<string, typeof input>)?.[refK],
(parameter as Record<string, typeof parameter>)?.[refK]
)];
}
const _input = input as Record<string, typeof input>;
const inputKey = refK.replace('input:', '');
return [...arr, _input[inputKey] as string];
}, [] as string[]).join(' ');
return call('keyProcessed', result);
// Process a plain-string
if (typeof currentKey !== 'object' && typeof currentKey !== 'function') {
return currentKey ? callHook('keyProcessed', currentKey) : callHook('keyNotFound');
}

@@ -136,83 +79,14 @@

if (typeof currentKey === 'function') {
const inputContainsArgs = typeof input === 'object' && input && 'args' in input && Array.isArray(input.args);
return call('keyProcessed', currentKey(...(inputContainsArgs ? input.args as [] : [])));
return callHook('keyProcessed', currentKey(...(Array.isArray(input) ? input : [])));
}
// Process a plain-string
if (typeof currentKey !== 'object') {
return currentKey ? call('keyFound', currentKey) : call('keyNotFound');
}
return callHook('keyFound', currentKey);
} as TranslationProxy<Locale, Processors>;
// Process an object record that doesn't specify a processor
// TODO: move into a plugin
if (!isProcessedKey(currentKey)) {
return call(
'keyProcessed',
Object.keys(currentKey).map((refKey) => {
const inputForKey = typeof input === 'object' && input ? input[refKey as keyof typeof input] : {};
const translated = translate(
refKey as LocaleKey<Locale>,
(
typeof input === 'object' && input
? mergeInputs(
currentKey[refKey],
inputForKey ?? null
)
: currentKey[refKey]
) as LocaleInputParameter<Locale, LocaleKey<Locale>, Processors>
);
const callPluginsHook = callPlugins(translate, plugins);
return translated;
}).join(' ').replace(/\s+/, ' ')
);
}
// Initialize plugins
callPluginsHook('initPlugin', processors, undefined, undefined, currentLocaleId, '', undefined, undefined);
// Process a parametrized record using a processor:
// TODO: move into a plugin
const processorName = Object.keys(currentKey.processor)[0];
const processor = localizedProcessors[processorName];
if (!processor) {
return call('processorNotFound', key, processorName);
}
// Delete undefined keys to make defaults bypass them in the spread later
const mergedInput = mergeInputs(
currentKey.input,
input as InputObject
);
const mergedParameter = {
...currentKey.parameter,
...parameter as ParameterObject,
};
const getProcessedResult = processor(mergedParameter, key, doc);
const result = getProcessedResult(mergedInput, mergedParameter);
return result
? call('keyProcessed', result, processorName)
: (call('keyNotProcessed', result, processorName) ?? call('keyNotFound', result, processorName));
} as TranslationProxy<Locale, Processors>;
return translate;
};
function mergeInputs(
baseInput: InputObject,
input: InputObject,
) {
if (typeof input === 'object' && input != null) {
for (const prop in input)
if (input[prop] == null) {
delete input[prop];
}
}
const mergedInput = typeof baseInput === 'object' && typeof input === 'object'
? { ...baseInput, ...input }
: (input ?? baseInput);
return mergedInput;
}
{
"extends": "tsconfig/base"
"extends": "tsconfig/base",
"include": ["./src"]
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc