@yiiamee/multilinguist 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/module.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@yiiamee/multilinguist",
3
3
  "configKey": "multilinguist",
4
- "version": "1.4.1",
4
+ "version": "1.5.0",
5
5
  "compatibility": {
6
- "nuxt": "^3.0.0"
6
+ "nuxt": "^3.0.0 || ^4.0.0"
7
7
  },
8
8
  "defaults": {
9
9
  "logging": true,
10
10
  "defaultLocale": "",
11
11
  "supportedLanguages": [],
12
- "setBrowserLanguage": true
12
+ "setBrowserLanguage": true,
13
+ "localesPath": "./public/locales"
13
14
  },
14
15
  "builder": {
15
16
  "@nuxt/module-builder": "1.0.1",
package/dist/module.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defineNuxtModule, createResolver, addPlugin, addImportsDir } from '@nuxt/kit';
2
2
  import fs from 'fs';
3
- import path from 'path';
3
+ import path, { resolve } from 'path';
4
4
 
5
5
  function flattenKeys(obj, prefix = "") {
6
6
  return Object.entries(obj).flatMap(([key, value]) => {
@@ -49,9 +49,26 @@ declare module 'vue' {
49
49
  }
50
50
  `;
51
51
  };
52
- function GenerateLocaleKeysPlugin(defaultLocaleFromConfig, localesPath, outPath, logging = true) {
52
+ const generateLocaleImports = (absoluteLocalesPath, relativeLocalesPath, supportedLanguages, generatedFilePath, projectRoot) => {
53
+ const generatedFileDir = path.dirname(generatedFilePath);
54
+ const relativeTo = path.relative(generatedFileDir, projectRoot);
55
+ const cleanLocalesPath = relativeLocalesPath.startsWith("./") ? relativeLocalesPath.slice(2) : relativeLocalesPath.startsWith("/") ? relativeLocalesPath.slice(1) : relativeLocalesPath;
56
+ const importBasePath = path.join(relativeTo, cleanLocalesPath).replace(/\\/g, "/");
57
+ const normalizedKeyPath = relativeLocalesPath.startsWith("./") ? relativeLocalesPath.slice(1) : relativeLocalesPath.startsWith("/") ? relativeLocalesPath : `/${relativeLocalesPath}`;
58
+ const imports = supportedLanguages.map((lang, index) => `import locale_${index} from "${importBasePath}/${lang}.json";`).join("\n");
59
+ const localeMap = supportedLanguages.map((lang, index) => ` "${normalizedKeyPath}/${lang}.json": { default: locale_${index} }`).join(",\n");
60
+ return `
61
+ // AUTO-GENERATED LOCALE IMPORTS
62
+ ${imports}
63
+
64
+ export const localeFiles = {
65
+ ${localeMap}
66
+ };
67
+ `;
68
+ };
69
+ function GenerateLocaleKeysPlugin(defaultLocaleFromConfig, absoluteLocalesPath, outPath, logging = true, relativeLocalesPath = "./public/locales", supportedLanguages = [], projectRoot = process.cwd()) {
53
70
  async function generateTypes() {
54
- const defaultLocalePath = path.join(localesPath, `${defaultLocaleFromConfig}.json`);
71
+ const defaultLocalePath = path.join(absoluteLocalesPath, `${defaultLocaleFromConfig}.json`);
55
72
  if (!fs.existsSync(defaultLocalePath)) {
56
73
  console?.error(`\u274C Default locale file not found: ${defaultLocalePath}`);
57
74
  return;
@@ -65,14 +82,40 @@ function GenerateLocaleKeysPlugin(defaultLocaleFromConfig, localesPath, outPath,
65
82
  console?.warn(`\u2705 Generated types to ${outPath} from ${defaultLocalePath}`);
66
83
  }
67
84
  }
85
+ async function generateLocaleImportsFile() {
86
+ const importsPath = path.dirname(outPath) + "/locale-imports.ts";
87
+ const imports = generateLocaleImports(
88
+ absoluteLocalesPath,
89
+ relativeLocalesPath,
90
+ supportedLanguages,
91
+ importsPath,
92
+ projectRoot
93
+ );
94
+ fs.mkdirSync(path.dirname(importsPath), { recursive: true });
95
+ fs.writeFileSync(importsPath, imports, "utf-8");
96
+ if (logging) {
97
+ console?.warn(`\u2705 Generated locale imports to ${importsPath}`);
98
+ const generatedFileDir = path.dirname(importsPath);
99
+ const relativeTo = path.relative(generatedFileDir, projectRoot);
100
+ const cleanLocalesPath = relativeLocalesPath.startsWith("./") ? relativeLocalesPath.slice(2) : relativeLocalesPath.startsWith("/") ? relativeLocalesPath.slice(1) : relativeLocalesPath;
101
+ const finalPath = path.join(relativeTo, cleanLocalesPath).replace(/\\/g, "/");
102
+ console?.warn(`\u2705 Import path calculated: ${finalPath}`);
103
+ }
104
+ }
68
105
  return {
69
106
  name: "vite-plugin-generate-locales-types",
70
107
  async buildStart() {
71
108
  await generateTypes();
109
+ if (supportedLanguages.length > 0) {
110
+ await generateLocaleImportsFile();
111
+ }
72
112
  },
73
113
  async handleHotUpdate(ctx) {
74
- if (ctx.file.endsWith(".json") && ctx.file.includes(localesPath)) {
114
+ if (ctx.file.endsWith(".json") && ctx.file.includes(absoluteLocalesPath)) {
75
115
  await generateTypes();
116
+ if (supportedLanguages.length > 0) {
117
+ await generateLocaleImportsFile();
118
+ }
76
119
  }
77
120
  }
78
121
  };
@@ -82,35 +125,43 @@ const module = defineNuxtModule({
82
125
  meta: {
83
126
  name: "@yiiamee/multilinguist",
84
127
  configKey: "multilinguist",
85
- version: "1.4.1",
128
+ version: "1.5.0",
86
129
  compatibility: {
87
- nuxt: "^3.0.0"
130
+ nuxt: "^3.0.0 || ^4.0.0"
88
131
  },
89
132
  defaults: {
90
133
  logging: true,
91
134
  defaultLocale: "",
92
135
  supportedLanguages: [],
93
- setBrowserLanguage: true
136
+ setBrowserLanguage: true,
137
+ localesPath: "./public/locales"
94
138
  }
95
139
  },
96
140
  setup(moduleOptions, nuxtApp) {
97
141
  const resolver = createResolver(import.meta.url);
142
+ const localesPath = moduleOptions.localesPath || "./public/locales";
143
+ const resolvedLocalesPath = resolve(nuxtApp.options.rootDir, localesPath);
98
144
  addPlugin(resolver.resolve("runtime/plugin"));
99
145
  addImportsDir(resolver.resolve("runtime/composables"));
100
146
  nuxtApp.options.runtimeConfig.public.multilinguist = {
101
147
  defaultLocale: moduleOptions.defaultLocale,
102
148
  supportedLanguages: moduleOptions.supportedLanguages,
103
149
  logging: typeof moduleOptions.logging === "boolean" ? moduleOptions.logging : true,
104
- setBrowserLanguage: typeof moduleOptions.setBrowserLanguage === "boolean" ? moduleOptions.setBrowserLanguage : true
150
+ setBrowserLanguage: typeof moduleOptions.setBrowserLanguage === "boolean" ? moduleOptions.setBrowserLanguage : true,
151
+ localesPath
105
152
  };
106
153
  nuxtApp.hook("vite:extendConfig", (viteConfig) => {
107
154
  viteConfig.plugins = viteConfig.plugins || [];
108
155
  viteConfig.plugins.push(
109
156
  GenerateLocaleKeysPlugin(
110
157
  moduleOptions.defaultLocale,
111
- `${nuxtApp.options.rootDir}/public/locales`,
158
+ resolvedLocalesPath,
112
159
  resolver.resolve("./runtime/types/generated-locales.d.ts"),
113
- moduleOptions.logging
160
+ moduleOptions.logging,
161
+ localesPath,
162
+ moduleOptions.supportedLanguages,
163
+ nuxtApp.options.rootDir
164
+ // Pass the project root
114
165
  )
115
166
  );
116
167
  });
@@ -118,6 +169,9 @@ const module = defineNuxtModule({
118
169
  references.push({
119
170
  path: resolver.resolve("./runtime/types/generated-locales.d.ts")
120
171
  });
172
+ references.push({
173
+ path: resolver.resolve("./runtime/types/locale-imports.ts")
174
+ });
121
175
  });
122
176
  }
123
177
  });
@@ -1,20 +1,24 @@
1
1
  import useLocale from "../composables/useLocale.js";
2
- import { useCookie, useState } from "nuxt/app";
2
+ import { useCookie, useState, useRuntimeConfig } from "nuxt/app";
3
3
  import { computed, watch } from "vue";
4
+ import { localeFiles } from "../types/locale-imports.js";
4
5
  export default function useLocalization(supportedLanguages, defaultLocale, setBrowserLanguage = true) {
5
6
  const { locale: userBrowserLocale } = useLocale(supportedLanguages, defaultLocale);
7
+ const config = useRuntimeConfig();
6
8
  const userSelectedLocale = useCookie("multilinguist-locale", {
7
9
  default: () => supportedLanguages.includes(userBrowserLocale.value) && setBrowserLanguage ? userBrowserLocale.value : defaultLocale
8
10
  });
9
- const localeFiles = import.meta.glob("@/public/locales/*.json", { eager: true });
10
11
  const loadedLanguages = useState("loaded-languages", () => ({}));
11
12
  const loadLocaleMessages = async (locale2) => {
12
13
  if (!loadedLanguages.value[locale2]) {
13
- const fileKey = `/public/locales/${locale2}.json`;
14
+ const localesPath = config.public.multilinguist.localesPath || "./public/locales";
15
+ const normalizedPath = localesPath.startsWith("./") ? localesPath.slice(1) : localesPath.startsWith("/") ? localesPath : `/${localesPath}`;
16
+ const fileKey = `${normalizedPath}/${locale2}.json`;
14
17
  const messages = localeFiles[fileKey];
15
18
  if (messages) {
16
- loadedLanguages.value[locale2] = messages?.default;
19
+ loadedLanguages.value[locale2] = messages.default;
17
20
  } else {
21
+ console.error(`Available locale files:`, Object.keys(localeFiles));
18
22
  throw new Error(`Locale file ${fileKey} not found`);
19
23
  }
20
24
  }
@@ -0,0 +1,30 @@
1
+ export declare const localeFiles: {
2
+ "/locales/en.json": {
3
+ default: {
4
+ "Hello, World": string;
5
+ "Switch Locale": string;
6
+ "Paste your variable here": string;
7
+ nested: {
8
+ "Nested key": string;
9
+ Language: string;
10
+ "nested second level": {
11
+ "nested second level language": string;
12
+ };
13
+ };
14
+ };
15
+ };
16
+ "/locales/es.json": {
17
+ default: {
18
+ "Hello, World": string;
19
+ "Switch Locale": string;
20
+ "Paste your variable here": string;
21
+ nested: {
22
+ "Nested key": string;
23
+ Language: string;
24
+ "nested second level": {
25
+ "nested second level language": string;
26
+ };
27
+ };
28
+ };
29
+ };
30
+ };
@@ -0,0 +1,6 @@
1
+ import locale_0 from "../../../playground/locales/en.json";
2
+ import locale_1 from "../../../playground/locales/es.json";
3
+ export const localeFiles = {
4
+ "/locales/en.json": { default: locale_0 },
5
+ "/locales/es.json": { default: locale_1 }
6
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yiiamee/multilinguist",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "Nuxt Multilinguist module for localizations",
5
5
  "repository": "yiiameeMich/multilinguist",
6
6
  "license": "MIT",