@intlayer/core
Version:
Includes core Intlayer functions like translation, dictionary, and utility functions shared across multiple packages.
222 lines (220 loc) • 8.26 kB
JavaScript
import { getCondition } from "../getCondition.mjs";
import { getEnumeration } from "../getEnumeration.mjs";
import { getGender } from "../getGender.mjs";
import { getInsertion } from "../getInsertion.mjs";
import { getNesting } from "../getNesting.mjs";
import { getPlural } from "../getPlural.mjs";
import { getTranslation } from "../getTranslation.mjs";
import * as NodeTypes from "@intlayer/types/nodeType";
//#region src/interpreter/getContent/plugins.ts
/** ---------------------------------------------
* FALLBACK PLUGIN
*
* Used to fallback a tree-shaken plugin
* --------------------------------------------- */
const fallbackPlugin = {
id: "fallback-plugin",
canHandle: () => false,
transform: (node) => node
};
/** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
const translationPlugin = (locale, fallback) => process.env["INTLAYER_NODE_TYPE_TRANSLATION"] === "false" ? fallbackPlugin : {
id: "translation-plugin",
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.TRANSLATION,
transform: (node, props, deepTransformNode) => {
const original = node[NodeTypes.TRANSLATION] ?? {};
const result = {};
for (const key in original) {
const childProps = {
...props,
children: original[key],
keyPath: [...props.keyPath, {
type: NodeTypes.TRANSLATION,
key
}]
};
result[key] = deepTransformNode(original[key], childProps);
}
return getTranslation(result, locale, fallback);
}
};
/** Enumeration plugin. Replaces node with a function that takes quantity => string. */
const enumerationPlugin = process.env["INTLAYER_NODE_TYPE_ENUMERATION"] === "false" ? fallbackPlugin : {
id: "enumeration-plugin",
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.ENUMERATION,
transform: (node, props, deepTransformNode) => {
const original = node[NodeTypes.ENUMERATION];
const result = {};
for (const key in original) {
const child = original[key];
result[key] = deepTransformNode(child, {
...props,
children: child,
keyPath: [...props.keyPath, {
type: NodeTypes.ENUMERATION,
key
}]
});
}
return (arg) => {
const subResult = getEnumeration(result, typeof arg === "number" ? arg : arg.count);
if (typeof subResult === "function" && typeof arg === "object") return subResult(arg);
return subResult;
};
}
};
/**
* Plural plugin. Replaces node with a function that takes a count (or
* `{ count, ...values }`) => string, picking the matching CLDR plural form
* for the active locale and interpolating `{{count}}` (and other values).
*/
const pluralPlugin = (locale) => process.env["INTLAYER_NODE_TYPE_PLURAL"] === "false" ? fallbackPlugin : {
id: "plural-plugin",
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.PLURAL,
transform: (node, props, deepTransformNode) => {
const original = node[NodeTypes.PLURAL];
const result = {};
/** String plugin for plural. Replaces string node with a component that renders the insertion. */
const pluralStringPlugin = {
id: "plural-string-plugin",
canHandle: (node) => typeof node === "string",
transform: (node, subProps, deepTransformNode) => {
const transformedResult = deepTransformNode(node, {
...subProps,
children: node,
plugins: [...(props.plugins ?? []).filter((plugin) => plugin.id !== "intlayer-node-plugin")]
});
return (values) => {
const children = getInsertion(transformedResult, values);
return deepTransformNode(children, {
...subProps,
plugins: props.plugins,
children
});
};
}
};
for (const key in original) {
const child = original[key];
result[key] = deepTransformNode(child, {
...props,
children: child,
keyPath: [...props.keyPath, {
type: NodeTypes.PLURAL,
key
}],
plugins: [pluralStringPlugin, ...props.plugins ?? []]
});
}
const effectiveLocale = String(locale ?? props.locale ?? "en");
return (arg) => {
const count = typeof arg === "number" ? arg : arg.count;
const values = typeof arg === "number" ? { count: arg } : arg;
const subResult = getPlural(result, count, effectiveLocale);
if (typeof subResult === "function") return subResult(values);
return subResult;
};
}
};
/** Condition plugin. Replaces node with a function that takes boolean => string. */
const conditionPlugin = process.env["INTLAYER_NODE_TYPE_CONDITION"] === "false" ? fallbackPlugin : {
id: "condition-plugin",
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.CONDITION,
transform: (node, props, deepTransformNode) => {
const original = node[NodeTypes.CONDITION];
const result = {};
for (const key in original) {
const child = original[key];
result[key] = deepTransformNode(child, {
...props,
children: child,
keyPath: [...props.keyPath, {
type: NodeTypes.CONDITION,
key
}]
});
}
return (arg) => {
const subResult = getCondition(result, typeof arg === "boolean" ? arg : arg.value);
if (typeof subResult === "function" && typeof arg === "object") return subResult(arg);
return subResult;
};
}
};
/** Insertion plugin. Replaces node with a function that takes quantity => string. */
const insertionPlugin = process.env["INTLAYER_NODE_TYPE_INSERTION"] === "false" ? fallbackPlugin : {
id: "insertion-plugin",
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.INSERTION,
transform: (node, props, deepTransformNode) => {
const newKeyPath = [...props.keyPath, { type: NodeTypes.INSERTION }];
const children = node[NodeTypes.INSERTION];
/** Insertion string plugin. Replaces string node with a component that render the insertion. */
const insertionStringPlugin = {
id: "insertion-string-plugin",
canHandle: (node) => typeof node === "string",
transform: (node, subProps, deepTransformNode) => {
const transformedResult = deepTransformNode(node, {
...subProps,
children: node,
plugins: [...(props.plugins ?? []).filter((plugin) => plugin.id !== "intlayer-node-plugin")]
});
return (values) => {
const children = getInsertion(transformedResult, values);
return deepTransformNode(children, {
...subProps,
plugins: props.plugins,
children
});
};
}
};
return deepTransformNode(children, {
...props,
children,
keyPath: newKeyPath,
plugins: [insertionStringPlugin, ...props.plugins ?? []]
});
}
};
/** Gender plugin. Replaces node with a function that takes gender => string. */
const genderPlugin = process.env["INTLAYER_NODE_TYPE_GENDER"] === "false" ? fallbackPlugin : {
id: "gender-plugin",
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.GENDER,
transform: (node, props, deepTransformNode) => {
const original = node[NodeTypes.GENDER];
const result = {};
for (const key in original) {
const child = original[key];
result[key] = deepTransformNode(child, {
...props,
children: child,
keyPath: [...props.keyPath, {
type: NodeTypes.GENDER,
key
}]
});
}
return (value) => getGender(result, value);
}
};
/** Nested plugin. Replaces node with the result of `getNesting`. */
const nestedPlugin = (locale) => process.env["INTLAYER_NODE_TYPE_NESTED"] === "false" ? fallbackPlugin : {
id: "nested-plugin",
canHandle: (node) => typeof node === "object" && (node?.nodeType === NodeTypes.NESTED || node?.nodeType === "n"),
transform: (node, props) => getNesting(node[NodeTypes.NESTED].dictionaryKey, node[NodeTypes.NESTED].path, {
...props,
locale: locale ?? props.locale
})
};
/** File plugin. Replaces node with the result of `getNesting`. */
const filePlugin = process.env["INTLAYER_NODE_TYPE_FILE"] === "false" ? fallbackPlugin : {
id: "file-plugin",
canHandle: (node) => typeof node === "object" && node?.nodeType === NodeTypes.FILE,
transform: (node, props, deepTransform) => deepTransform(node.content, {
...props,
children: node.content
})
};
//#endregion
export { conditionPlugin, enumerationPlugin, fallbackPlugin, filePlugin, genderPlugin, insertionPlugin, nestedPlugin, pluralPlugin, translationPlugin };
//# sourceMappingURL=plugins.mjs.map