@xxanderwp/translate-module 1.0.0 → 1.0.1

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/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export declare class LanguageCore<T extends Record<string, Record<string, string
2
2
  private readonly _languages_data;
3
3
  private _currentLanguage;
4
4
  constructor(data: T, defaultLanguage?: keyof T);
5
+ private validateLanguageData;
5
6
  get languagesData(): T;
6
7
  get currentLanguage(): LangKey | null;
7
8
  set currentLanguage(lang: LangKey);
package/dist/index.js CHANGED
@@ -4,9 +4,7 @@ exports.LanguageCore = void 0;
4
4
  class LanguageCore {
5
5
  constructor(data, defaultLanguage) {
6
6
  this._currentLanguage = null;
7
- if (Object.keys(data).length === 0) {
8
- throw new Error("Languages data cannot be empty.");
9
- }
7
+ this.validateLanguageData(data);
10
8
  this._languages_data = data;
11
9
  if (defaultLanguage) {
12
10
  if (!this.langKeys.includes(defaultLanguage)) {
@@ -18,6 +16,27 @@ class LanguageCore {
18
16
  this._currentLanguage = Object.keys(data)[0];
19
17
  }
20
18
  }
19
+ validateLanguageData(data) {
20
+ if (Object.keys(data).length === 0) {
21
+ throw new Error("Languages data cannot be empty.");
22
+ }
23
+ const firstLangData = data[Object.keys(data)[0]];
24
+ if (typeof firstLangData !== "object" || Array.isArray(firstLangData)) {
25
+ throw new Error("Each language data must be an object.");
26
+ }
27
+ const firstLangKeys = Object.keys(firstLangData);
28
+ for (const langKey in data) {
29
+ const langData = data[langKey];
30
+ if (typeof langData !== "object" || Array.isArray(langData)) {
31
+ throw new Error(`Language data for ${langKey} must be an object.`);
32
+ }
33
+ const langKeys = Object.keys(langData);
34
+ if (langKeys.length !== firstLangKeys.length ||
35
+ !langKeys.every((key) => firstLangKeys.includes(key))) {
36
+ throw new Error(`All languages must have the same keys. Mismatch found in ${langKey}.`);
37
+ }
38
+ }
39
+ }
21
40
  get languagesData() {
22
41
  return this._languages_data;
23
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xxanderwp/translate-module",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "directories": {
@@ -1,64 +0,0 @@
1
- name: Publish npm Package
2
-
3
- on:
4
- push:
5
- branches: [main, beta]
6
-
7
- jobs:
8
- publish:
9
- runs-on: ubuntu-latest
10
- steps:
11
- - name: Checkout repository
12
- uses: actions/checkout@v3
13
-
14
- - name: Setup Node.js
15
- uses: actions/setup-node@v3
16
- with:
17
- node-version: 20
18
- registry-url: https://registry.npmjs.org/
19
-
20
- - name: Install dependencies
21
- run: npm ci
22
-
23
- - name: Build package
24
- run: npm run build
25
-
26
- - name: Check if version exists on npm
27
- id: check_version
28
- run: |
29
- PACKAGE_NAME=$(node -p "require('./package.json').name")
30
- PACKAGE_VERSION=$(node -p "require('./package.json').version")
31
- echo "Package: $PACKAGE_NAME"
32
- echo "Version: $PACKAGE_VERSION"
33
-
34
- # Проверяем, есть ли уже такая версия на npm
35
- if npm view "$PACKAGE_NAME@$PACKAGE_VERSION" >/dev/null 2>&1; then
36
- echo "Version $PACKAGE_VERSION already exists on npm"
37
- echo "exists=true" >> $GITHUB_OUTPUT
38
- else
39
- echo "Version $PACKAGE_VERSION is new"
40
- echo "exists=false" >> $GITHUB_OUTPUT
41
- fi
42
-
43
- - name: Publish to npm (latest)
44
- if: steps.check_version.outputs.exists == 'false' && github.ref == 'refs/heads/main'
45
- env:
46
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
47
- run: |
48
- npm publish --access=public
49
-
50
- - name: Mark existing version as latest
51
- if: steps.check_version.outputs.exists == 'true' && github.ref == 'refs/heads/main'
52
- env:
53
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
54
- run: |
55
- PACKAGE_NAME=$(node -p "require('./package.json').name")
56
- PACKAGE_VERSION=$(node -p "require('./package.json').version")
57
- npm dist-tag add "$PACKAGE_NAME@$PACKAGE_VERSION" latest
58
-
59
- - name: Publish to npm (beta)
60
- if: steps.check_version.outputs.exists == 'false' && github.ref == 'refs/heads/beta'
61
- env:
62
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
63
- run: |
64
- npm publish --tag beta --access=public
@@ -1,46 +0,0 @@
1
- name: Tests
2
-
3
- on:
4
- push:
5
- branches: [develop]
6
- pull_request:
7
- branches: [main, beta, develop]
8
-
9
- jobs:
10
- test:
11
- runs-on: ubuntu-latest
12
-
13
- strategy:
14
- matrix:
15
- node-version: [16.x, 18.x, 20.x, 22.x]
16
-
17
- steps:
18
- - uses: actions/checkout@v3
19
-
20
- - name: Use Node.js ${{ matrix.node-version }}
21
- uses: actions/setup-node@v3
22
- with:
23
- node-version: ${{ matrix.node-version }}
24
-
25
- - name: Install dependencies
26
- run: npm ci
27
-
28
- - name: Run linter
29
- run: npm run lint
30
-
31
- - name: Run tests
32
- run: npm test
33
-
34
- - name: Run coverage
35
- run: npm run test:coverage
36
-
37
- - name: Upload coverage to Codecov
38
- uses: codecov/codecov-action@v3
39
- if: matrix.node-version == '22.x'
40
- with:
41
- file: ./coverage/lcov.info
42
- flags: unittests
43
- name: codecov-umbrella
44
-
45
- - name: Build
46
- run: npm run build
package/jest.config.js DELETED
@@ -1,30 +0,0 @@
1
- module.exports = {
2
- preset: 'ts-jest',
3
- testEnvironment: 'node',
4
- roots: ['<rootDir>/src', '<rootDir>/tests'],
5
- testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
6
- testTimeout: 10000,
7
- collectCoverageFrom: [
8
- 'src/**/*.ts',
9
- '!src/**/*.d.ts',
10
- '!src/**/*.test.ts',
11
- '!src/**/*.spec.ts',
12
- ],
13
- coverageThreshold: {
14
- global: {
15
- branches: 50,
16
- functions: 50,
17
- lines: 50,
18
- statements: 50,
19
- },
20
- },
21
- moduleFileExtensions: ['ts', 'js', 'json'],
22
- transform: {
23
- '^.+\\.ts$': [
24
- 'ts-jest',
25
- {
26
- tsconfig: 'tsconfig.test.json',
27
- },
28
- ],
29
- },
30
- };
package/src/index.ts DELETED
@@ -1,64 +0,0 @@
1
- export class LanguageCore<
2
- T extends Record<string, Record<string, string>>,
3
- LangKey extends keyof T = keyof T
4
- > {
5
- private readonly _languages_data: T;
6
- private _currentLanguage: LangKey | null = null;
7
-
8
- constructor(data: T, defaultLanguage?: keyof T) {
9
- if (Object.keys(data).length === 0) {
10
- throw new Error("Languages data cannot be empty.");
11
- }
12
-
13
- this._languages_data = data;
14
- if(defaultLanguage) {
15
- if (!this.langKeys.includes(defaultLanguage as LangKey)) {
16
- throw new Error(`Default language ${String(defaultLanguage)} is not supported.`);
17
- }
18
- this._currentLanguage = defaultLanguage as LangKey;
19
- } else {
20
- this._currentLanguage = Object.keys(data)[0] as LangKey;
21
- }
22
- }
23
-
24
- get languagesData(): T {
25
- return this._languages_data;
26
- }
27
-
28
- get currentLanguage(): LangKey | null {
29
- return this._currentLanguage;
30
- }
31
-
32
- set currentLanguage(lang: LangKey) {
33
- if (!this.langKeys.includes(lang)) {
34
- throw new Error(`Language ${String(lang)} is not supported.`);
35
- }
36
- this._currentLanguage = lang;
37
- }
38
-
39
- get langKeys(): LangKey[] {
40
- return Object.keys(this._languages_data) as LangKey[];
41
- }
42
-
43
- get currentLanguageData(): T[LangKey] | null {
44
- if (!this._currentLanguage) return null;
45
- return this._languages_data[this._currentLanguage];
46
- }
47
-
48
- translate<K extends keyof T[LangKey]>(
49
- key: K,
50
- ...args: (string | number)[]
51
- ): string | null {
52
- if (!this._currentLanguage) return null;
53
-
54
- const langData = this._languages_data[this._currentLanguage];
55
- let res = langData[key] as string;
56
-
57
- args.forEach((arg, index) => {
58
- res = res.replace(new RegExp(`\\{${index}\\}`, "g"), String(arg));
59
- });
60
-
61
- return res || null;
62
- }
63
- }
64
-
@@ -1,79 +0,0 @@
1
- import { describe, it, expect } from "@jest/globals";
2
- import { LanguageCore } from "../src/index";
3
-
4
- describe("LangModule", () => {
5
- it("should initialize with valid data and default language", () => {
6
- const data = {
7
- en: { greeting: "Hello" },
8
- es: { greeting: "Hola" },
9
- };
10
- const langModule = new LanguageCore(data, "es");
11
- expect(langModule.languagesData).toEqual(data);
12
- expect(langModule.currentLanguage).toBe("es");
13
- });
14
-
15
- it("should throw an error if initialized with empty data", () => {
16
- expect(() => new LanguageCore({})).toThrow("Languages data cannot be empty.");
17
- });
18
-
19
- it("should throw an error if default language is not supported", () => {
20
- const data = {
21
- en: { greeting: "Hello" },
22
- es: { greeting: "Hola" },
23
- };
24
- // @ts-ignore
25
- expect(() => new LanguageCore(data, "fr")).toThrow("Default language fr is not supported.");
26
- });
27
-
28
- it("should return the correct translation for the current language", () => {
29
- const data = {
30
- en: { greeting: "Hello, {0}!" },
31
- es: { greeting: "¡Hola, {0}!" },
32
- };
33
- const langModule = new LanguageCore(data, "en");
34
- expect(langModule.translate("greeting", "John")).toBe("Hello, John!");
35
- langModule.currentLanguage = "es";
36
- expect(langModule.translate("greeting", "John")).toBe("¡Hola, John!");
37
- });
38
-
39
- it("should throw an error when setting an unsupported language", () => {
40
- const data = {
41
- en: { greeting: "Hello" },
42
- es: { greeting: "Hola" },
43
- };
44
- const langModule = new LanguageCore(data);
45
- // @ts-ignore
46
- expect(() => (langModule.currentLanguage = "fr")).toThrow("Language fr is not supported.");
47
- });
48
-
49
- it("should return null for translation if current language is not set", () => {
50
- const data = {
51
- en: { greeting: "Hello" },
52
- es: { greeting: "Hola" },
53
- };
54
- const langModule = new LanguageCore(data);
55
- // @ts-ignore
56
- expect(() => (langModule.currentLanguage = null)).toThrow("Language null is not supported.");
57
- });
58
-
59
- it("should return null for translation if key does not exist", () => {
60
- const data = {
61
- en: { greeting: "Hello" },
62
- es: { greeting: "Hola" },
63
- };
64
- const langModule = new LanguageCore(data);
65
- // @ts-ignore
66
- expect(langModule.translate("farewell")).toBeNull();
67
- });
68
-
69
- it("should return the correct language keys", () => {
70
- const data = {
71
- en: { greeting: "Hello" },
72
- es: { greeting: "Hola" },
73
- };
74
- const langModule = new LanguageCore(data);
75
- expect(langModule.langKeys).toEqual(["en", "es"]);
76
- });
77
-
78
-
79
- });
package/tsconfig.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "declaration": true,
4
- "target": "ES2020",
5
- "module": "CommonJS",
6
- "lib": ["ES2020", "DOM"],
7
- "strict": true,
8
- "esModuleInterop": true,
9
- "skipLibCheck": true,
10
- "resolveJsonModule": true,
11
- "outDir": "./dist",
12
- "rootDir": "./src",
13
- "types": ["node"]
14
- },
15
- "include": ["src/**/*"],
16
- "exclude": ["node_modules", "dist"]
17
- }
@@ -1,11 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "./dist-tests",
5
- "rootDir": ".",
6
- "noEmit": true,
7
- "types": ["node", "jest"]
8
- },
9
- "include": ["src/**/*", "tests/**/*"],
10
- "exclude": ["node_modules", "dist"]
11
- }