diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 78c9f1d..d0ffac8 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @xml-locales/cli +## 1.0.0 + +### Major Changes + +- Add multiple changes, update tests + +### Patch Changes + +- Updated dependencies + - xml-locales@1.0.0 + ## 0.0.8 ### Patch Changes diff --git a/packages/cli/README.md b/packages/cli/README.md index a82929d..065fd96 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -38,45 +38,45 @@ npx @xml-locales/cli [...args] ### Add Command -The `add` command is used to add a new key-value pair to the XML localization file or files from directory. +The `add` command is used to add a new key(s)-value(s) pair to the XML localization file or files from directory. ```sh -xml-locales add --path path/to/file_or_directory --key newKey --value newValue +xml-locales add --path path/to/file_or_directory --keys newKey --values newValue ``` | Flag | Alias | Default | Description | |---------|-------|---------|-----------------------------------------------------------------------------| | `--path`| `-p` | `process.cwd()` | The path to the XML localization file or directory where the key-value pair will be added. | -| `--key` | `-k` | None | The new key to be added. | -| `--value`| `-v` | None | The value to be associated with the new key. | +| `--keys` | `-k` | None | The new key(s) to be added. | +| `--values`| `-v` | None | The value(s) to be associated with the new key. | ### Remove Command -The `remove` command is used to remove a key-value pair from the XML localization file or files from directory. +The `remove` command is used to remove a key(s)-value(s) pair from the XML localization file or files from directory. ```sh -xml-locales remove --path path/to/file_or_directory --key keyToRemove --value valueToRemove +xml-locales remove --path path/to/file_or_directory --keys keyToRemove --values valueToRemove ``` | Flag | Alias | Default | Description | |---------|-------|---------|-----------------------------------------------------------------------------| | `--path`| `-p` | `process.cwd()` | The path to the XML localization file or directory where the key-value pair will be removed. | -| `--key` | `-k` | None | Removed string by the key. | -| `--value`| `-v` | None | Or removed string by the value. | +| `--keys` | `-k` | None | Removed string by the key(s). | +| `--values`| `-v` | None | Or removed string by the value(s). | ### Update Command -The `update` command is used to update a key-value pair in the XML localization file or files from directory. +The `update` command is used to update a key(s)-value(s) pair in the XML localization file or files from directory. ```sh -xml-locales update --path path/to/file_or_directory --oldValue oldValue --newValue newValue +xml-locales update --path path/to/file_or_directory --old oldValue --new newValue ``` | Flag | Alias | Default | Description | |------------|-------|---------|-----------------------------------------------------------------------------| | `--path` | `-p` | `process.cwd()` | The path to the XML localization file or directory where the key-value pair will be updated. | -| `--oldValue` | `-o` | None | The old key or value to be updated. | -| `--newValue`| `-n` | None | The new key or value to replace the old one. | +| `--old` | `-o` | None | The old key(s) or value(s) to be updated. | +| `--new`| `-n` | None | The new key(s) or value(s) to replace the old one. | ### Sort Command diff --git a/packages/cli/package.json b/packages/cli/package.json index f1f95d6..6300277 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@xml-locales/cli", - "version": "0.0.8", + "version": "1.0.0", "type": "module", "bin": { "xml-locales": "./dist/bin.js" @@ -27,7 +27,7 @@ }, "dependencies": { "diff": "5.1.0", - "xml-locales": "workspace:0.0.5", + "xml-locales": "workspace:1.0.0", "yargs": "17.7.2" }, "devDependencies": { diff --git a/packages/cli/src/commands/add.ts b/packages/cli/src/commands/add.ts index ae779d4..845457c 100644 --- a/packages/cli/src/commands/add.ts +++ b/packages/cli/src/commands/add.ts @@ -10,23 +10,28 @@ export const description = 'Add one localization string in files'; export function builder(argv: Argv) { return keyValueOptions(pathOption(argv), 'add').usage( - `\nExample:\n $0 ${command} --path "path/to/file/or/directory" --key "some_key" --value "some_value"` + `\nExample:\n $0 ${command} --path "path/to/file/or/directory" --keys "some_key" --values "some_value"` ); } export async function handler({ - key, - value, + keys, + values, path }: ArgumentsCamelCase<{ - key: string; - value: string; + keys: string[]; + values: string[]; path: string; }>) { const files = await readFiles(path); for (const [path, file] of files) { const diff = new Diff(path, file); - const xml = file.add({ key, value }).toXML(); + + if (keys.length !== values.length) { + throw new Error('The number of keys and values must be the same'); + } + + const xml = file.add({ keys, values }).toXML(); await writeFile(path, xml); diff.print(xml); } diff --git a/packages/cli/src/commands/remove.ts b/packages/cli/src/commands/remove.ts index 9f67615..359c149 100644 --- a/packages/cli/src/commands/remove.ts +++ b/packages/cli/src/commands/remove.ts @@ -10,29 +10,29 @@ export const description = 'Remove one localization string in files'; export function builder(yargs: Argv) { return keyValueOptions(pathOption(yargs), 'remove').usage( - `\nExample:\n ${command} --path "path/to/file/or/directory" --key "some_key" --value "or_some_value"` + `\nExample:\n ${command} --path "path/to/file/or/directory" --keys "some_key" --values "or_some_value"` ); } export async function handler({ - key, - value, + keys, + values, path }: ArgumentsCamelCase<{ - key: string; - value: string; + keys: string[]; + values: string[]; path: string; }>) { const files = await readFiles(path); for (let [path, file] of files) { const diff = new Diff(path, file); - if (key) { - file = file.deleteByKey(key); + if (keys) { + file = file.deleteByKey(keys); } - if (value) { - file = file.deleteByValue(value); + if (values) { + file = file.deleteByValue(values); } const xml = file.toXML(); diff --git a/packages/cli/src/commands/update.ts b/packages/cli/src/commands/update.ts index fc95a52..72ffe4e 100644 --- a/packages/cli/src/commands/update.ts +++ b/packages/cli/src/commands/update.ts @@ -15,18 +15,23 @@ export function builder(yargs: Argv) { } export async function handler({ - oldValue, - newValue, + old: oldValues, + new: newValues, path }: ArgumentsCamelCase<{ - oldValue: string; - newValue: string; + old: string[]; + new: string[]; path: string; }>) { const files = await readFiles(path); for (const [path, file] of files) { const diff = new Diff(path, file); - const xml = file.update({ oldValue, newValue }).toXML(); + + if (oldValues.length !== newValues.length) { + throw new Error('The number of old and new values must be the same'); + } + + const xml = file.update({ oldValues, newValues }).toXML(); await writeFile(path, xml); diff.print(xml); } diff --git a/packages/cli/src/options/key-value.ts b/packages/cli/src/options/key-value.ts index b68adea..dc3df16 100644 --- a/packages/cli/src/options/key-value.ts +++ b/packages/cli/src/options/key-value.ts @@ -2,30 +2,30 @@ import type { Argv } from 'yargs'; export function keyValueOptions(argv: Argv, action: string) { return argv - .option('key', { + .option('keys', { alias: 'k', - desc: `Key of ${action} string`, - type: 'string' + desc: `Key(s) of ${action} string(s)`, + type: 'array' }) - .option('value', { + .option('values', { alias: 'v', - desc: `Value of ${action} string`, - type: 'string' + desc: `Value(s) of ${action} string(s)`, + type: 'array' }); } export function oldKeyOrValueOptions(argv: Argv) { return argv - .option('oldValue', { + .option('old', { alias: 'o', - desc: 'Old key or value of update string', + desc: 'Old key(s) or value(s) of update string(s)', demandOption: true, - type: 'string' + type: 'array' }) - .option('newValue', { + .option('new', { alias: 'n', - desc: 'New key or value of update string', + desc: 'New key(s) or value(s) of update string(s)', demandOption: true, - type: 'string' + type: 'array' }); } diff --git a/packages/cli/src/utils/files.ts b/packages/cli/src/utils/files.ts index 25a9759..6698fdc 100644 --- a/packages/cli/src/utils/files.ts +++ b/packages/cli/src/utils/files.ts @@ -1,5 +1,5 @@ import fs from 'node:fs/promises'; -import { resolve } from 'node:path'; +import { relative, resolve } from 'node:path'; import { XmlLocales } from 'xml-locales'; async function scanPath(path: string): Promise { @@ -10,7 +10,7 @@ async function scanPath(path: string): Promise { const paths = await fs.readdir(path); return paths .filter((file) => file.endsWith('.xml')) - .map((file) => resolve(`${path}/${file}`)); + .map((file) => relative(process.cwd(), resolve(`${path}/${file}`))); } } catch (err) { throw new Error( diff --git a/packages/xml-locales/CHANGELOG.md b/packages/xml-locales/CHANGELOG.md index 0ee4e0a..39b44e7 100644 --- a/packages/xml-locales/CHANGELOG.md +++ b/packages/xml-locales/CHANGELOG.md @@ -1,5 +1,11 @@ # xml-locales +## 1.0.0 + +### Major Changes + +- Add multiple changes, update tests + ## 0.0.5 ### Patch Changes diff --git a/packages/xml-locales/README.md b/packages/xml-locales/README.md index c033328..0b3c05d 100644 --- a/packages/xml-locales/README.md +++ b/packages/xml-locales/README.md @@ -83,7 +83,7 @@ const xmlData = ` ` const xmlLocales = new XmlLocales(xmlData) -const jsonData = xmlLocales.add({key: 'newKey', value: 'newValue'}).toXML() +const jsonData = xmlLocales.add({keys: ['newKey'], values: ['newValue']}).toXML() console.log(jsonData) ``` @@ -111,9 +111,9 @@ const xmlData = ` ` const xmlLocales = new XmlLocales(xmlData) -const jsonData = xmlLocales.add({key: 'newKey', value: 'newValue'}) -.update({oldValue: 'key1', newValue: 'firstKey'}) -.update({oldValue: 'value2', newValue: 'secondValue'}) +const jsonData = xmlLocales.add({keys: ['newKey'], values: ['newValue']}) +.update({oldValues: ['key1'], newValues: ['firstKey']}) +.update({oldValues: ['value2'], newValues: ['secondValue']}) .toXML() console.log(jsonData) @@ -141,7 +141,7 @@ const xmlData = ` ` const xmlLocales = new XmlLocales(xmlData) -const jsonData = xmlLocales.add({key: 'newKey', value: 'newValue'}) +const jsonData = xmlLocales.add({keys: ['newKey'], values: ['newValue']}) .deleteByKey('key1') .deleteByValue('value2') .toXML() @@ -220,9 +220,9 @@ const xmlData = ` const xmlLocales = new XmlLocales(xmlData) -const jsonData = xmlLocales.add({key: 'newKey', value: 'newValue'}) -.add({key: 'newKey2', value: 'newValue2'}) -.update({oldValue: 'key1', newValue: 'firstKey'}) +const jsonData = xmlLocales.add({keys: ['newKey'], values: ['newValue']}) +.add({keys: ['newKey2'], values: ['newValue2']}) +.update({oldValues: ['key1'], newValues: ['firstKey']}) .sort('desc') .toXML() diff --git a/packages/xml-locales/package.json b/packages/xml-locales/package.json index 0c1dcce..9708aae 100644 --- a/packages/xml-locales/package.json +++ b/packages/xml-locales/package.json @@ -1,7 +1,7 @@ { "name": "xml-locales", "description": "Tool for locales in xml files", - "version": "0.0.5", + "version": "1.0.0", "type": "module", "keywords": [ "xml-locales", diff --git a/packages/xml-locales/src/__snapshots__/xml-locales.test.ts.snap b/packages/xml-locales/src/__snapshots__/xml-locales.test.ts.snap index 5816ae9..e1eca10 100644 --- a/packages/xml-locales/src/__snapshots__/xml-locales.test.ts.snap +++ b/packages/xml-locales/src/__snapshots__/xml-locales.test.ts.snap @@ -16,10 +16,6 @@ XmlJsonData { exports[`XmlLocales > XmlLocales constructor > should return json object 1`] = ` XmlJsonData { "resources": { - "#text": " - - -", "string": [ { "#text": "value1", @@ -34,34 +30,6 @@ XmlJsonData { } `; -exports[`XmlLocales > should return json object 1`] = ` -XmlJsonData { - "resources": { - "#text": " - - -", - "string": [ - { - "#text": "value1", - "key_name": "key1", - }, - { - "#text": "value2", - "key_name": "key2", - }, - ], - }, -} -`; - -exports[`XmlLocales > should return xml string 1`] = ` -" - value1 - value2 -" -`; - exports[`XmlLocales > to XML > should return xml string with formatting 1`] = ` " value1 @@ -69,9 +37,4 @@ exports[`XmlLocales > to XML > should return xml string with formatting 1`] = ` " `; -exports[`XmlLocales > to XML > should return xml string without formatting 1`] = ` -"value1value2 - - -" -`; +exports[`XmlLocales > to XML > should return xml string without formatting 1`] = `"value1value2"`; diff --git a/packages/xml-locales/src/modifiers/delete.ts b/packages/xml-locales/src/modifiers/delete.ts index 460fa67..68eafcb 100644 --- a/packages/xml-locales/src/modifiers/delete.ts +++ b/packages/xml-locales/src/modifiers/delete.ts @@ -1,15 +1,11 @@ -import { checkXmlKey } from '../utils/helpers.js'; import { XmlJsonData } from '../utils/xml.js'; export function deleteByKeyXmlNode( xmlData: XmlJsonData, - key: string + keys: string[] ): XmlJsonData { - const hasKey = checkXmlKey(xmlData, key); - if (!hasKey) return xmlData; - const filteredNodes = xmlData.resources.string.filter( - (element) => element.key_name !== key + (element) => !keys.includes(element.key_name) ); return new XmlJsonData({ resources: { string: filteredNodes } }); @@ -17,10 +13,10 @@ export function deleteByKeyXmlNode( export function deleteByValueXmlNode( xmlData: XmlJsonData, - value: string + values: string[] ): XmlJsonData { const filteredNodes = xmlData.resources.string.filter( - (element) => element['#text'] !== value + (element) => !values.includes(element['#text']) ); return new XmlJsonData({ resources: { string: filteredNodes } }); diff --git a/packages/xml-locales/src/utils/types.ts b/packages/xml-locales/src/utils/types.ts index e5766bc..18db509 100644 --- a/packages/xml-locales/src/utils/types.ts +++ b/packages/xml-locales/src/utils/types.ts @@ -14,13 +14,13 @@ export interface XmlJson { } export interface AddOptions { - key: string; - value: string; + keys: string[]; + values: string[]; } export interface UpdateOptions { - oldValue: string; - newValue: string; + oldValues: string[]; + newValues: string[]; } export type SortDirection = 'asc' | 'desc'; diff --git a/packages/xml-locales/src/xml-locales.test.ts b/packages/xml-locales/src/xml-locales.test.ts index 1ea7624..572f16a 100644 --- a/packages/xml-locales/src/xml-locales.test.ts +++ b/packages/xml-locales/src/xml-locales.test.ts @@ -15,27 +15,61 @@ describe('XmlLocales', () => { describe('add', () => { test('should add new node', () => { const xmlLocales = new XmlLocales(xmlData); - const jsonXml = xmlLocales.add({ key: 'key3', value: 'value3' }).toJSON(); + const jsonXml = xmlLocales + .add({ keys: ['key3'], values: ['value3'] }) + .toJSON(); const newNode = jsonXml.resources.string[2]; expect(newNode?.key_name).toBe('key3'); expect(newNode?.['#text']).toBe('value3'); }); + test('should add two new node', () => { + const xmlLocales = new XmlLocales(xmlData); + const jsonXml = xmlLocales + .add({ keys: ['key3', 'key4'], values: ['value3', 'value4'] }) + .toJSON(); + const firstNewNode = jsonXml.resources.string[2]; + const secondNewNode = jsonXml.resources.string[3]; + + expect(firstNewNode?.key_name).toBe('key3'); + expect(firstNewNode?.['#text']).toBe('value3'); + + expect(secondNewNode?.key_name).toBe('key4'); + expect(secondNewNode?.['#text']).toBe('value4'); + }); + test('should replace the value of the key', () => { const xmlLocales = new XmlLocales(xmlData); - const jsonXml = xmlLocales.add({ key: 'key1', value: 'value3' }).toJSON(); + const jsonXml = xmlLocales + .add({ keys: ['key1'], values: ['value3'] }) + .toJSON(); const newNode = jsonXml.resources.string[0]; expect(newNode?.key_name).toBe('key1'); expect(newNode?.['#text']).toBe('value3'); }); + + test('should replace two values of two keys', () => { + const xmlLocales = new XmlLocales(xmlData); + const jsonXml = xmlLocales + .add({ keys: ['key1', 'key2'], values: ['value3', 'value4'] }) + .toJSON(); + const firstNewNode = jsonXml.resources.string[0]; + const secondNewNode = jsonXml.resources.string[1]; + + expect(firstNewNode?.key_name).toBe('key1'); + expect(firstNewNode?.['#text']).toBe('value3'); + + expect(secondNewNode?.key_name).toBe('key2'); + expect(secondNewNode?.['#text']).toBe('value4'); + }); }); describe('remove', () => { test('should remove a node of the key', () => { const xmlLocales = new XmlLocales(xmlData); - xmlLocales.deleteByKey('key1'); + xmlLocales.deleteByKey(['key1']); const jsonXml = xmlLocales.toJSON(); expect(jsonXml.resources.string[0]?.['#text']).toBe('value2'); @@ -43,19 +77,44 @@ describe('XmlLocales', () => { test('should remove a node of the value', () => { const xmlLocales = new XmlLocales(xmlData); - xmlLocales.deleteByValue('value1'); + xmlLocales.deleteByValue(['value1']); const jsonXml = xmlLocales.toJSON(); expect(jsonXml.resources.string[0]?.['#text']).toBe('value2'); }); + test('should remove a node of two keys', () => { + const xmlLocales = new XmlLocales(xmlData); + xmlLocales.deleteByKey(['key1', 'key2']); + const jsonXml = xmlLocales.toJSON(); + + expect(jsonXml.resources.string.length).toBe(0); + }); + test('not found key or value', () => { const xmlLocales = new XmlLocales(xmlData); - xmlLocales.deleteByKey('key3'); + xmlLocales.deleteByKey(['key3']); const jsonXml = xmlLocales.toJSON(); expect(jsonXml.resources.string[0]?.['#text']).toBe('value1'); }); + + test('not found keys or values', () => { + const xmlLocales = new XmlLocales(xmlData); + xmlLocales.deleteByKey(['key3', 'key4']); + const jsonXml = xmlLocales.toJSON(); + + expect(jsonXml.resources.string[0]?.['#text']).toBe('value1'); + }); + + test('found one of keys', () => { + const xmlLocales = new XmlLocales(xmlData); + xmlLocales.deleteByKey(['key3', 'key1']); + const jsonXml = xmlLocales.toJSON(); + + expect(jsonXml.resources.string[0]?.['#text']).toBe('value2'); + expect(jsonXml.resources.string.length).toBe(1); + }); }); describe('sort', () => { @@ -79,18 +138,66 @@ describe('XmlLocales', () => { describe('update', () => { test('should update key', () => { const xmlLocales = new XmlLocales(xmlData); - xmlLocales.update({ oldValue: 'key1', newValue: 'newKey1' }); + xmlLocales.update({ oldValues: ['key1'], newValues: ['newKey1'] }); + const jsonXml = xmlLocales.toJSON(); + + expect(jsonXml.resources.string[0]?.key_name).toBe('newKey1'); + }); + + test('should update two keys', () => { + const xmlLocales = new XmlLocales(xmlData); + xmlLocales.update({ + oldValues: ['key1', 'key2'], + newValues: ['newKey1', 'newKey2'] + }); + const jsonXml = xmlLocales.toJSON(); + + expect(jsonXml.resources.string[0]?.key_name).toBe('newKey1'); + expect(jsonXml.resources.string[1]?.key_name).toBe('newKey2'); + }); + + test('should update one of two keys', () => { + const xmlLocales = new XmlLocales(xmlData); + xmlLocales.update({ + oldValues: ['key1', 'ley2'], + newValues: ['newKey1', 'newKey2'] + }); const jsonXml = xmlLocales.toJSON(); expect(jsonXml.resources.string[0]?.key_name).toBe('newKey1'); + expect(jsonXml.resources.string[1]?.key_name).toBe('key2'); }); test('should update value', () => { const xmlLocales = new XmlLocales(xmlData); - xmlLocales.update({ oldValue: 'value1', newValue: 'newValue1' }); + xmlLocales.update({ oldValues: ['value1'], newValues: ['newValue1'] }); + const jsonXml = xmlLocales.toJSON(); + + expect(jsonXml.resources.string[0]?.['#text']).toBe('newValue1'); + }); + + test('should update two values', () => { + const xmlLocales = new XmlLocales(xmlData); + xmlLocales.update({ + oldValues: ['value1', 'value2'], + newValues: ['newValue1', 'newValue2'] + }); + const jsonXml = xmlLocales.toJSON(); + + expect(jsonXml.resources.string[0]?.['#text']).toBe('newValue1'); + expect(jsonXml.resources.string[1]?.['#text']).toBe('newValue2'); + }); + + test('should update one of values', () => { + const xmlLocales = new XmlLocales(xmlData); + xmlLocales.update({ + oldValues: ['value1', 'balue2'], + newValues: ['newValue1', 'newValue2'] + }); const jsonXml = xmlLocales.toJSON(); expect(jsonXml.resources.string[0]?.['#text']).toBe('newValue1'); + expect(jsonXml.resources.string[1]?.['#text']).toBe('value2'); }); }); diff --git a/packages/xml-locales/src/xml-locales.ts b/packages/xml-locales/src/xml-locales.ts index aa98ac4..ac9414b 100644 --- a/packages/xml-locales/src/xml-locales.ts +++ b/packages/xml-locales/src/xml-locales.ts @@ -66,27 +66,29 @@ export class XmlLocales { return new XmlLocales(this.xmlData, this.xmlOptions); } - add(options: AddOptions): XmlLocales { - this.xmlData = addXmlNode(this.xmlData, options.key, options.value); + add({ keys, values }: AddOptions): XmlLocales { + for (let i = 0; i < keys.length; i++) { + this.xmlData = addXmlNode(this.xmlData, keys[i]!, values[i]!); + } + return this.newInstance(); } - update(options: UpdateOptions): XmlLocales { - this.xmlData = updateXmlNode( - this.xmlData, - options.oldValue, - options.newValue - ); + update({ newValues, oldValues }: UpdateOptions): XmlLocales { + for (let i = 0; i < oldValues.length; i++) { + this.xmlData = updateXmlNode(this.xmlData, oldValues[i]!, newValues[i]!); + } + return this.newInstance(); } - deleteByKey(key: string): XmlLocales { - this.xmlData = deleteByKeyXmlNode(this.xmlData, key); + deleteByKey(keys: string[]): XmlLocales { + this.xmlData = deleteByKeyXmlNode(this.xmlData, keys); return this.newInstance(); } - deleteByValue(value: string): XmlLocales { - this.xmlData = deleteByValueXmlNode(this.xmlData, value); + deleteByValue(values: string[]): XmlLocales { + this.xmlData = deleteByValueXmlNode(this.xmlData, values); return this.newInstance(); }