i18n-dev.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import type { DevLocale, MessageKey } from './type';
  2. import { defaultLocale, getMessageFromLocale } from './getMessageFromLocale';
  3. type I18nValue = {
  4. message: string;
  5. placeholders?: Record<string, { content?: string; example?: string }>;
  6. };
  7. function translate(key: MessageKey, substitutions?: string | string[]) {
  8. const value = getMessageFromLocale(t.devLocale)[key] as I18nValue;
  9. let message = value.message;
  10. /**
  11. * This is a placeholder replacement logic. But it's not perfect.
  12. * It just imitates the behavior of the Chrome extension i18n API.
  13. * Please check the official document for more information And double-check the behavior on production build.
  14. *
  15. * @url https://developer.chrome.com/docs/extensions/how-to/ui/localization-message-formats#placeholders
  16. */
  17. if (value.placeholders) {
  18. Object.entries(value.placeholders).forEach(([key, { content }]) => {
  19. if (!content) {
  20. return;
  21. }
  22. message = message.replace(new RegExp(`\\$${key}\\$`, 'gi'), content);
  23. });
  24. }
  25. if (!substitutions) {
  26. return message;
  27. }
  28. if (Array.isArray(substitutions)) {
  29. return substitutions.reduce((acc, cur, idx) => acc.replace(`$${idx + 1}`, cur), message);
  30. }
  31. return message.replace(/\$(\d+)/, substitutions);
  32. }
  33. function removePlaceholder(message: string) {
  34. return message.replace(/\$\d+/g, '');
  35. }
  36. export const t = (...args: Parameters<typeof translate>) => {
  37. return removePlaceholder(translate(...args));
  38. };
  39. t.devLocale = defaultLocale as DevLocale;