@open-xchange/vite-plugin-i18next-gettext 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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## `1.5.0` – 2026-Apr-09
4
+
5
+ - chore: switch to `tsdown` for building packages
6
+
7
+ ## `1.4.2` – 2026-Mar-27
8
+
9
+ - fixed: bump `@open-xchange/i18next-po-parser` with fix for [i18next-cli#223](https://github.com/i18next/i18next-cli/issues/223)
10
+
3
11
  ## `1.4.1` – 2026-Mar-26
4
12
 
5
13
  - fixed: bump `@open-xchange/i18next-po-parser` with workaround for [i18next-cli#227](https://github.com/i18next/i18next-cli/issues/227)
@@ -0,0 +1,59 @@
1
+ import { Plugin } from "vite";
2
+
3
+ //#region src/index.d.ts
4
+ /**
5
+ * Configuration options for the plugin '@open-xchange/vite-plugin-i18next-gettext'.
6
+ */
7
+ interface VitePluginI18nextGettextOptions {
8
+ /**
9
+ * Glob pattern(s) for all PO files containing the translations.
10
+ *
11
+ * @example
12
+ * {
13
+ * poFiles: 'i18n/*.po',
14
+ * // ...
15
+ * }
16
+ */
17
+ poFiles: string | string[];
18
+ /**
19
+ * Glob pattern(s) for all source files to be scanned for UI strings.
20
+ *
21
+ * @example
22
+ * {
23
+ * srcFiles: 'src/*.{js,ts}',
24
+ * // ...
25
+ * }
26
+ */
27
+ srcFiles: string | string[];
28
+ /**
29
+ * Path to the POT files generated when building the project, relative to the
30
+ * build output directory. Should contain the placeholder `[NAMESPACE]` if
31
+ * the project contains translation strings in different i18next namespaces.
32
+ *
33
+ * @example
34
+ * {
35
+ * potFile: 'i18n/[NAMESPACE].pot',
36
+ * // ...
37
+ * }
38
+ */
39
+ potFile: string;
40
+ /**
41
+ * The project name to be inserted into the POT files under the key
42
+ * 'Project-Id-Version'. May contain the placeholder `[NAMESPACE]`.
43
+ */
44
+ projectName: string;
45
+ }
46
+ declare const PROJECT_NAME = "@open-xchange/vite-plugin-i18next-gettext";
47
+ /**
48
+ * Vite plugin for using i18next with gettext `.po` files under the hood.
49
+ *
50
+ * @param options
51
+ * Plugin configuration.
52
+ *
53
+ * @returns
54
+ * The Vite plugin object.
55
+ */
56
+ declare function vitePluginI18nextGettext(options: VitePluginI18nextGettextOptions): Plugin;
57
+ //#endregion
58
+ export { PROJECT_NAME, VitePluginI18nextGettextOptions, vitePluginI18nextGettext as default };
59
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;AAeA;UAAiB,+BAAA;;;;;;;;;AA8CjB;EAnCE,OAAA;;;;AAmCqE;;;;;;EAxBrE,QAAA;EAuCgG;;;;;;;;;;;EA1BhG,OAAA;;;;;EAMA,WAAA;AAAA;AAAA,cAKW,YAAA;;;;;;;;;;iBAeW,wBAAA,CAAyB,OAAA,EAAS,+BAAA,GAAkC,MAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,53 @@
1
+ import { posix, relative, sep } from "node:path";
2
+ import { readFile } from "node:fs/promises";
3
+ import { version } from "vite";
4
+ import pm from "picomatch";
5
+ import converter from "gettext-converter";
6
+ import { parseSourceFiles } from "@open-xchange/i18next-po-parser";
7
+ //#region src/index.ts
8
+ const PROJECT_NAME = "@open-xchange/vite-plugin-i18next-gettext";
9
+ const VITE_VERSION = parseInt(version.split(".")[0], 10);
10
+ /**
11
+ * Vite plugin for using i18next with gettext `.po` files under the hood.
12
+ *
13
+ * @param options
14
+ * Plugin configuration.
15
+ *
16
+ * @returns
17
+ * The Vite plugin object.
18
+ */
19
+ function vitePluginI18nextGettext(options) {
20
+ return {
21
+ name: PROJECT_NAME,
22
+ config: () => ({ optimizeDeps: VITE_VERSION >= 8 ? { rolldownOptions: { moduleTypes: { ".po": "text" } } } : { esbuildOptions: { loader: { ".po": "text" } } } }),
23
+ async load(id) {
24
+ const relPath = relative(process.cwd(), id).replaceAll(sep, posix.sep);
25
+ if (!pm.isMatch(relPath, options.poFiles)) return;
26
+ const data = await readFile(id, { encoding: "utf8" });
27
+ const json = converter.po2i18next(data, { compatibilityJSON: "v4" });
28
+ return {
29
+ code: `export default ${JSON.stringify(json)}`,
30
+ map: { mappings: "" }
31
+ };
32
+ },
33
+ async generateBundle() {
34
+ const catalogs = await parseSourceFiles({
35
+ project: options.projectName,
36
+ files: options.srcFiles
37
+ });
38
+ if (catalogs.size > 1 && !options.potFile.includes("[NAMESPACE]")) this.error("multiple POT files written to same file location (missing placeholder `[NAMESPACE]` in option potFile)");
39
+ for (const [namespace, source] of catalogs) {
40
+ const fileName = options.potFile.replaceAll("[NAMESPACE]", namespace);
41
+ this.emitFile({
42
+ type: "asset",
43
+ fileName,
44
+ source
45
+ });
46
+ }
47
+ }
48
+ };
49
+ }
50
+ //#endregion
51
+ export { PROJECT_NAME, vitePluginI18nextGettext as default };
52
+
53
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["\nimport { sep, relative, posix } from 'node:path'\nimport { readFile } from 'node:fs/promises'\n\nimport { type Plugin, version } from 'vite'\nimport pm from 'picomatch'\n\nimport converter from 'gettext-converter'\nimport { parseSourceFiles } from '@open-xchange/i18next-po-parser'\n\n// types ======================================================================\n\n/**\n * Configuration options for the plugin '@open-xchange/vite-plugin-i18next-gettext'.\n */\nexport interface VitePluginI18nextGettextOptions {\n\n /**\n * Glob pattern(s) for all PO files containing the translations.\n *\n * @example\n * {\n * poFiles: 'i18n/*.po',\n * // ...\n * }\n */\n poFiles: string | string[]\n\n /**\n * Glob pattern(s) for all source files to be scanned for UI strings.\n *\n * @example\n * {\n * srcFiles: 'src/*.{js,ts}',\n * // ...\n * }\n */\n srcFiles: string | string[]\n\n /**\n * Path to the POT files generated when building the project, relative to the\n * build output directory. Should contain the placeholder `[NAMESPACE]` if\n * the project contains translation strings in different i18next namespaces.\n *\n * @example\n * {\n * potFile: 'i18n/[NAMESPACE].pot',\n * // ...\n * }\n */\n potFile: string\n\n /**\n * The project name to be inserted into the POT files under the key\n * 'Project-Id-Version'. May contain the placeholder `[NAMESPACE]`.\n */\n projectName: string\n}\n\n// constants ==================================================================\n\nexport const PROJECT_NAME = '@open-xchange/vite-plugin-i18next-gettext'\n\nconst VITE_VERSION = parseInt(version.split('.')[0], 10)\n\n// plugin =====================================================================\n\n/**\n * Vite plugin for using i18next with gettext `.po` files under the hood.\n *\n * @param options\n * Plugin configuration.\n *\n * @returns\n * The Vite plugin object.\n */\nexport default function vitePluginI18nextGettext(options: VitePluginI18nextGettextOptions): Plugin {\n\n return {\n name: PROJECT_NAME,\n\n // register esbuild loader for PO files (load as plain text)\n config: () => ({\n optimizeDeps: (VITE_VERSION >= 8) ?\n { rolldownOptions: { moduleTypes: { '.po': 'text' } } } :\n { esbuildOptions: { loader: { '.po': 'text' } } },\n }),\n\n // convert PO files to i18next JSON v4\n async load(id) {\n const relPath = relative(process.cwd(), id).replaceAll(sep, posix.sep)\n if (!pm.isMatch(relPath, options.poFiles)) { return }\n\n // read the PO file and convert it to i18next JSON\n const data = await readFile(id, { encoding: 'utf8' })\n const json = converter.po2i18next(data, { compatibilityJSON: 'v4' })\n\n // generate a module that exports a _stringified_ JSON object\n const code = `export default ${JSON.stringify(json)}`\n return { code, map: { mappings: '' } }\n },\n\n // parse source files and create POT files per namespace\n async generateBundle() {\n\n // parse all source files, extract translations, collect into POT catalogs\n const catalogs = await parseSourceFiles({ project: options.projectName, files: options.srcFiles })\n\n // warn when writing multiple POT files to same file location\n if ((catalogs.size > 1) && !options.potFile.includes('[NAMESPACE]')) {\n this.error('multiple POT files written to same file location (missing placeholder `[NAMESPACE]` in option potFile)')\n }\n\n // add all POT files as assets to the bundle\n for (const [namespace, source] of catalogs) {\n const fileName = options.potFile.replaceAll('[NAMESPACE]', namespace)\n this.emitFile({ type: 'asset', fileName, source })\n }\n },\n }\n}\n"],"mappings":";;;;;;;AA6DA,MAAa,eAAe;AAE5B,MAAM,eAAe,SAAS,QAAQ,MAAM,IAAI,CAAC,IAAI,GAAG;;;;;;;;;;AAaxD,SAAwB,yBAAyB,SAAkD;AAEjG,QAAO;EACL,MAAM;EAGN,eAAe,EACb,cAAe,gBAAgB,IAC7B,EAAE,iBAAiB,EAAE,aAAa,EAAE,OAAO,QAAQ,EAAE,EAAE,GACvD,EAAE,gBAAgB,EAAE,QAAQ,EAAE,OAAO,QAAQ,EAAE,EAAE,EACpD;EAGD,MAAM,KAAK,IAAI;GACb,MAAM,UAAU,SAAS,QAAQ,KAAK,EAAE,GAAG,CAAC,WAAW,KAAK,MAAM,IAAI;AACtE,OAAI,CAAC,GAAG,QAAQ,SAAS,QAAQ,QAAQ,CAAI;GAG7C,MAAM,OAAO,MAAM,SAAS,IAAI,EAAE,UAAU,QAAQ,CAAC;GACrD,MAAM,OAAO,UAAU,WAAW,MAAM,EAAE,mBAAmB,MAAM,CAAC;AAIpE,UAAO;IAAE,MADI,kBAAkB,KAAK,UAAU,KAAK;IACpC,KAAK,EAAE,UAAU,IAAI;IAAE;;EAIxC,MAAM,iBAAiB;GAGrB,MAAM,WAAW,MAAM,iBAAiB;IAAE,SAAS,QAAQ;IAAa,OAAO,QAAQ;IAAU,CAAC;AAGlG,OAAK,SAAS,OAAO,KAAM,CAAC,QAAQ,QAAQ,SAAS,cAAc,CACjE,MAAK,MAAM,yGAAyG;AAItH,QAAK,MAAM,CAAC,WAAW,WAAW,UAAU;IAC1C,MAAM,WAAW,QAAQ,QAAQ,WAAW,eAAe,UAAU;AACrE,SAAK,SAAS;KAAE,MAAM;KAAS;KAAU;KAAQ,CAAC;;;EAGvD"}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@open-xchange/vite-plugin-i18next-gettext",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "Vite integration of i18next using gettext",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "https://gitlab.open-xchange.com/fspd/commons/plugins",
7
+ "url": "git+https://gitlab.open-xchange.com/fspd/commons/plugins.git",
8
8
  "directory": "packages/vite-plugin-i18next-gettext"
9
9
  },
10
10
  "license": "MIT",
@@ -12,35 +12,41 @@
12
12
  "node": ">=20.18"
13
13
  },
14
14
  "type": "module",
15
- "exports": "./dist/index.js",
15
+ "exports": {
16
+ ".": "./dist/index.mjs",
17
+ "./package.json": "./package.json"
18
+ },
16
19
  "files": [
17
20
  "dist",
18
21
  "CHANGELOG.*"
19
22
  ],
20
23
  "dependencies": {
21
- "@open-xchange/i18next-po-parser": "^1.2.4",
24
+ "@open-xchange/i18next-po-parser": "^1.2.5",
22
25
  "gettext-converter": "^1.3.1",
23
26
  "picomatch": "^4.0.4"
24
27
  },
25
28
  "devDependencies": {
26
- "@types/picomatch": "^4.0.2",
27
- "@vitest/coverage-v8": "^4.1.1",
28
- "vite": "^8.0.2",
29
- "vite-v6": "npm:vite@^6.4.1",
30
- "vite-v7": "npm:vite@^7.3.1",
31
- "vite-v8": "npm:vite@^8.0.2",
32
- "vitest": "^4.1.1",
33
- "@open-xchange/vitest-vite-plugin-utils": "^0.0.1",
34
- "@open-xchange/linter-presets": "^1.18.7"
29
+ "@types/picomatch": "^4.0.3",
30
+ "@vitest/coverage-v8": "^4.1.3",
31
+ "i18next": "^26.0.4",
32
+ "vite": "^8.0.8",
33
+ "vite-v6": "npm:vite@^8.0.8",
34
+ "vite-v7": "npm:vite@^8.0.8",
35
+ "vite-v8": "npm:vite@^8.0.8",
36
+ "vitest": "^4.1.3",
37
+ "@open-xchange/linter-presets": "^1.22.0",
38
+ "@open-xchange/tsconfig": "^0.0.2",
39
+ "@open-xchange/vitest-plugin-extended": "^1.6.0",
40
+ "@open-xchange/vitest-vite-plugin-utils": "^0.0.2"
35
41
  },
36
42
  "peerDependencies": {
37
43
  "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
38
44
  },
39
45
  "scripts": {
40
- "build": "pnpm clean && tsc --project src/tsconfig.json",
41
- "clean": "premove dist",
46
+ "build": "tsdown",
42
47
  "coverage": "vitest run --coverage",
43
- "lint": "tsc && tsc --project src/tsconfig.json --noEmit && eslint .",
44
- "test": "vitest run"
48
+ "lint": "tsc && tsc --project src && tsc --project test && eslint .",
49
+ "test": "vitest run",
50
+ "verify": "pnpm build && pnpm lint && pnpm test"
45
51
  }
46
52
  }
package/dist/index.d.ts DELETED
@@ -1,54 +0,0 @@
1
- import { type Plugin } from 'vite';
2
- /**
3
- * Configuration options for the plugin '@open-xchange/vite-plugin-i18next-gettext'.
4
- */
5
- export interface VitePluginI18nextGettextOptions {
6
- /**
7
- * Glob pattern(s) for all PO files containing the translations.
8
- *
9
- * @example
10
- * {
11
- * poFiles: 'i18n/*.po',
12
- * // ...
13
- * }
14
- */
15
- poFiles: string | string[];
16
- /**
17
- * Glob pattern(s) for all source files to be scanned for UI strings.
18
- *
19
- * @example
20
- * {
21
- * srcFiles: 'src/*.{js,ts}',
22
- * // ...
23
- * }
24
- */
25
- srcFiles: string | string[];
26
- /**
27
- * Path to the POT files generated when building the project, relative to the
28
- * build output directory. Should contain the placeholder `[NAMESPACE]` if
29
- * the project contains translation strings in different i18next namespaces.
30
- *
31
- * @example
32
- * {
33
- * potFile: 'i18n/[NAMESPACE].pot',
34
- * // ...
35
- * }
36
- */
37
- potFile: string;
38
- /**
39
- * The project name to be inserted into the POT files under the key
40
- * 'Project-Id-Version'. May contain the placeholder `[NAMESPACE]`.
41
- */
42
- projectName: string;
43
- }
44
- export declare const PROJECT_NAME = "@open-xchange/vite-plugin-i18next-gettext";
45
- /**
46
- * Vite plugin for using i18next with gettext `.po` files under the hood.
47
- *
48
- * @param options
49
- * Plugin configuration.
50
- *
51
- * @returns
52
- * The Vite plugin object.
53
- */
54
- export default function vitePluginI18nextGettext(options: VitePluginI18nextGettextOptions): Plugin;
package/dist/index.js DELETED
@@ -1,57 +0,0 @@
1
- import { sep, relative, posix } from 'node:path';
2
- import { readFile } from 'node:fs/promises';
3
- import { version } from 'vite';
4
- import pm from 'picomatch';
5
- import converter from 'gettext-converter';
6
- import { parseSourceFiles } from '@open-xchange/i18next-po-parser';
7
- // constants ==================================================================
8
- export const PROJECT_NAME = '@open-xchange/vite-plugin-i18next-gettext';
9
- const VITE_VERSION = parseInt(version.split('.')[0], 10);
10
- // plugin =====================================================================
11
- /**
12
- * Vite plugin for using i18next with gettext `.po` files under the hood.
13
- *
14
- * @param options
15
- * Plugin configuration.
16
- *
17
- * @returns
18
- * The Vite plugin object.
19
- */
20
- export default function vitePluginI18nextGettext(options) {
21
- return {
22
- name: PROJECT_NAME,
23
- // register esbuild loader for PO files (load as plain text)
24
- config: () => ({
25
- optimizeDeps: (VITE_VERSION >= 8) ?
26
- { rolldownOptions: { moduleTypes: { '.po': 'text' } } } :
27
- { esbuildOptions: { loader: { '.po': 'text' } } },
28
- }),
29
- // convert PO files to i18next JSON v4
30
- async load(id) {
31
- const relPath = relative(process.cwd(), id).replaceAll(sep, posix.sep);
32
- if (!pm.isMatch(relPath, options.poFiles)) {
33
- return;
34
- }
35
- // read the PO file and convert it to i18next JSON
36
- const data = await readFile(id, { encoding: 'utf8' });
37
- const json = converter.po2i18next(data, { compatibilityJSON: 'v4' });
38
- // generate a module that exports a _stringified_ JSON object
39
- const code = `export default ${JSON.stringify(json)}`;
40
- return { code, map: { mappings: '' } };
41
- },
42
- // parse source files and create POT files per namespace
43
- async generateBundle() {
44
- // parse all source files, extract translations, collect into POT catalogs
45
- const catalogs = await parseSourceFiles({ project: options.projectName, files: options.srcFiles });
46
- // warn when writing multiple POT files to same file location
47
- if ((catalogs.size > 1) && !options.potFile.includes('[NAMESPACE]')) {
48
- this.error('multiple POT files written to same file location (missing placeholder `[NAMESPACE]` in option potFile)');
49
- }
50
- // add all POT files as assets to the bundle
51
- for (const [namespace, source] of catalogs) {
52
- const fileName = options.potFile.replaceAll('[NAMESPACE]', namespace);
53
- this.emitFile({ type: 'asset', fileName, source });
54
- }
55
- },
56
- };
57
- }