Просмотр исходного кода

chore: adds builtin transformers

e22m4u 1 год назад
Родитель
Сommit
2229443b47

+ 5 - 1
README.md

@@ -314,6 +314,9 @@ schema.defineModel({
 нужно производить с входящими данными.
 нужно производить с входящими данными.
 
 
 - `trim` удаление пробельных символов с начала и конца строки
 - `trim` удаление пробельных символов с начала и конца строки
+- `toUpperCase` перевод строки в верхний регистр
+- `toLowerCase` перевод строки в нижний регистр
+- `toTitleCase` перевод строки в регистр заголовка
 
 
 **Пример**
 **Пример**
 
 
@@ -330,7 +333,8 @@ schema.defineModel({
     name: {
     name: {
       type: DataType.STRING,
       type: DataType.STRING,
       transform: [ // трансформеры свойства "name"
       transform: [ // трансформеры свойства "name"
-        'trim', // обрезать пробелы в начале и в конце строки
+        'trim', // удалить пробелы в начале и конце строки
+        'toTitleCase', // перевод в регистр заголовка
       ],
       ],
     },
     },
   },
   },

+ 4 - 1
docs/index.html

@@ -150,6 +150,9 @@
 нужно производить с входящими данными.</p>
 нужно производить с входящими данными.</p>
 <ul>
 <ul>
 <li><code>trim</code> удаление пробельных символов с начала и конца строки</li>
 <li><code>trim</code> удаление пробельных символов с начала и конца строки</li>
+<li><code>toUpperCase</code> перевод строки в верхний регистр</li>
+<li><code>toLowerCase</code> перевод строки в нижний регистр</li>
+<li><code>toTitleCase</code> перевод строки в регистр заголовка</li>
 </ul>
 </ul>
 <p><strong>Пример</strong></p>
 <p><strong>Пример</strong></p>
 <p>Трансформеры указываются в объявлении свойства модели параметром
 <p>Трансформеры указываются в объявлении свойства модели параметром
@@ -157,7 +160,7 @@
 указать несколько названий, то используется массив. Если трансформер
 указать несколько названий, то используется массив. Если трансформер
 имеет настройки, то используется объект, где ключом является название
 имеет настройки, то используется объект, где ключом является название
 трансформера, а значением его параметры.</p>
 трансформера, а значением его параметры.</p>
-<pre><code class="language-js"><span class="hl-4">schema</span><span class="hl-1">.</span><span class="hl-0">defineModel</span><span class="hl-1">({</span><br/><span class="hl-1">  </span><span class="hl-4">name:</span><span class="hl-1"> </span><span class="hl-2">&#39;user&#39;</span><span class="hl-1">,</span><br/><span class="hl-1">  </span><span class="hl-4">properties:</span><span class="hl-1"> {</span><br/><span class="hl-1">    </span><span class="hl-4">name:</span><span class="hl-1"> {</span><br/><span class="hl-1">      </span><span class="hl-4">type:</span><span class="hl-1"> </span><span class="hl-4">DataType</span><span class="hl-1">.</span><span class="hl-7">STRING</span><span class="hl-1">,</span><br/><span class="hl-1">      </span><span class="hl-4">transform:</span><span class="hl-1"> [ </span><span class="hl-5">// трансформеры свойства &quot;name&quot;</span><br/><span class="hl-1">        </span><span class="hl-2">&#39;trim&#39;</span><span class="hl-1">, </span><span class="hl-5">// обрезать пробелы в начале и в конце строки</span><br/><span class="hl-1">      ],</span><br/><span class="hl-1">    },</span><br/><span class="hl-1">  },</span><br/><span class="hl-1">});</span>
+<pre><code class="language-js"><span class="hl-4">schema</span><span class="hl-1">.</span><span class="hl-0">defineModel</span><span class="hl-1">({</span><br/><span class="hl-1">  </span><span class="hl-4">name:</span><span class="hl-1"> </span><span class="hl-2">&#39;user&#39;</span><span class="hl-1">,</span><br/><span class="hl-1">  </span><span class="hl-4">properties:</span><span class="hl-1"> {</span><br/><span class="hl-1">    </span><span class="hl-4">name:</span><span class="hl-1"> {</span><br/><span class="hl-1">      </span><span class="hl-4">type:</span><span class="hl-1"> </span><span class="hl-4">DataType</span><span class="hl-1">.</span><span class="hl-7">STRING</span><span class="hl-1">,</span><br/><span class="hl-1">      </span><span class="hl-4">transform:</span><span class="hl-1"> [ </span><span class="hl-5">// трансформеры свойства &quot;name&quot;</span><br/><span class="hl-1">        </span><span class="hl-2">&#39;trim&#39;</span><span class="hl-1">, </span><span class="hl-5">// удалить пробелы в начале и конце строки</span><br/><span class="hl-1">        </span><span class="hl-2">&#39;toTitleCase&#39;</span><span class="hl-1">, </span><span class="hl-5">// перевод в регистр заголовка</span><br/><span class="hl-1">      ],</span><br/><span class="hl-1">    },</span><br/><span class="hl-1">  },</span><br/><span class="hl-1">});</span>
 </code><button>Copy</button></pre>
 </code><button>Copy</button></pre>
 <a id="md:репозиторий" class="tsd-anchor"></a><h2><a href="#md:репозиторий">Репозиторий</a></h2><p>Выполняет операции чтения и записи документов определенной модели.
 <a id="md:репозиторий" class="tsd-anchor"></a><h2><a href="#md:репозиторий">Репозиторий</a></h2><p>Выполняет операции чтения и записи документов определенной модели.
 Получить репозиторий можно методом <code>getRepository</code> экземпляра схемы.</p>
 Получить репозиторий можно методом <code>getRepository</code> экземпляра схемы.</p>

+ 3 - 0
src/definition/model/properties/property-transformer/builtin/index.d.ts

@@ -1 +1,4 @@
 export * from './trim-transformer.js';
 export * from './trim-transformer.js';
+export * from './to-lower-case-transformer.js';
+export * from './to-upper-case-transformer.js';
+export * from './to-title-case-transformer.js';

+ 3 - 0
src/definition/model/properties/property-transformer/builtin/index.js

@@ -1 +1,4 @@
 export * from './trim-transformer.js';
 export * from './trim-transformer.js';
+export * from './to-lower-case-transformer.js';
+export * from './to-upper-case-transformer.js';
+export * from './to-title-case-transformer.js';

+ 6 - 0
src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.d.ts

@@ -0,0 +1,6 @@
+import {PropertyTransformer} from '../property-transformer.js';
+
+/**
+ * To lower case transformer.
+ */
+export declare type toLowerCaseTransformer = PropertyTransformer;

+ 19 - 0
src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.js

@@ -0,0 +1,19 @@
+import {InvalidArgumentError} from '../../../../../errors/index.js';
+
+/**
+ * To lower case transformer.
+ *
+ * @param {*} value
+ * @param {undefined} options
+ * @param {object} context
+ * @returns {string|undefined|null}
+ */
+export function toLowerCaseTransformer(value, options, context) {
+  if (value == null) return value;
+  if (typeof value === 'string') return value.toLowerCase();
+  throw new InvalidArgumentError(
+    'The property transformer %v requires a String value, but %v given.',
+    context.transformerName,
+    value,
+  );
+}

+ 39 - 0
src/definition/model/properties/property-transformer/builtin/to-lower-case-transformer.spec.js

@@ -0,0 +1,39 @@
+import {expect} from 'chai';
+import {format} from '@e22m4u/js-format';
+import {toLowerCaseTransformer} from './to-lower-case-transformer.js';
+
+describe('toLowerCaseTransformer', function () {
+  it('returns undefined and null values as is', function () {
+    const res1 = toLowerCaseTransformer(undefined, undefined, {});
+    const res2 = toLowerCaseTransformer(null, undefined, {});
+    expect(res1).to.be.undefined;
+    expect(res2).to.be.null;
+  });
+
+  it('converts the given string to lower case', function () {
+    const res = toLowerCaseTransformer('TEST', undefined, {});
+    expect(res).to.be.eq('test');
+  });
+
+  it('throws an error if the given value is not a string', function () {
+    const throwable = v => () =>
+      toLowerCaseTransformer(v, undefined, {
+        transformerName: 'toLowerCase',
+      });
+    const error = v =>
+      format(
+        'The property transformer "toLowerCase" requires a String value, but %s given.',
+        v,
+      );
+    expect(throwable(10)).to.throw(error('10'));
+    expect(throwable(0)).to.throw(error('0'));
+    expect(throwable(true)).to.throw(error('true'));
+    expect(throwable(false)).to.throw(error('false'));
+    expect(throwable({})).to.throw(error('Object'));
+    expect(throwable([])).to.throw(error('Array'));
+    throwable('str')();
+    throwable('')();
+    throwable(undefined)();
+    throwable(null)();
+  });
+});

+ 6 - 0
src/definition/model/properties/property-transformer/builtin/to-title-case-transformer.d.ts

@@ -0,0 +1,6 @@
+import {PropertyTransformer} from '../property-transformer.js';
+
+/**
+ * To title case transformer.
+ */
+export declare type toTitleCaseTransformer = PropertyTransformer;

+ 22 - 0
src/definition/model/properties/property-transformer/builtin/to-title-case-transformer.js

@@ -0,0 +1,22 @@
+import {InvalidArgumentError} from '../../../../../errors/index.js';
+
+/**
+ * To title case transformer.
+ *
+ * @param {*} value
+ * @param {undefined} options
+ * @param {object} context
+ * @returns {string|undefined|null}
+ */
+export function toTitleCaseTransformer(value, options, context) {
+  if (value == null) return value;
+  if (typeof value === 'string')
+    return value.replace(/\p{L}\S*/gu, text => {
+      return text.charAt(0).toUpperCase() + text.substring(1).toLowerCase();
+    });
+  throw new InvalidArgumentError(
+    'The property transformer %v requires a String value, but %v given.',
+    context.transformerName,
+    value,
+  );
+}

+ 41 - 0
src/definition/model/properties/property-transformer/builtin/to-title-case-transformer.spec.js

@@ -0,0 +1,41 @@
+import {expect} from 'chai';
+import {format} from '@e22m4u/js-format';
+import {toTitleCaseTransformer} from './to-title-case-transformer.js';
+
+describe('toTitleCaseTransformer', function () {
+  it('returns undefined and null values as is', function () {
+    const res1 = toTitleCaseTransformer(undefined, undefined, {});
+    const res2 = toTitleCaseTransformer(null, undefined, {});
+    expect(res1).to.be.undefined;
+    expect(res2).to.be.null;
+  });
+
+  it('converts the given string to title case', function () {
+    const res1 = toTitleCaseTransformer('TEST', undefined, {});
+    const res2 = toTitleCaseTransformer('test', undefined, {});
+    expect(res1).to.be.eq('Test');
+    expect(res2).to.be.eq('Test');
+  });
+
+  it('throws an error if the given value is not a string', function () {
+    const throwable = v => () =>
+      toTitleCaseTransformer(v, undefined, {
+        transformerName: 'toTitleCase',
+      });
+    const error = v =>
+      format(
+        'The property transformer "toTitleCase" requires a String value, but %s given.',
+        v,
+      );
+    expect(throwable(10)).to.throw(error('10'));
+    expect(throwable(0)).to.throw(error('0'));
+    expect(throwable(true)).to.throw(error('true'));
+    expect(throwable(false)).to.throw(error('false'));
+    expect(throwable({})).to.throw(error('Object'));
+    expect(throwable([])).to.throw(error('Array'));
+    throwable('str')();
+    throwable('')();
+    throwable(undefined)();
+    throwable(null)();
+  });
+});

+ 6 - 0
src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.d.ts

@@ -0,0 +1,6 @@
+import {PropertyTransformer} from '../property-transformer.js';
+
+/**
+ * To upper case transformer.
+ */
+export declare type toUpperCaseTransformer = PropertyTransformer;

+ 19 - 0
src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.js

@@ -0,0 +1,19 @@
+import {InvalidArgumentError} from '../../../../../errors/index.js';
+
+/**
+ * To upper case transformer.
+ *
+ * @param {*} value
+ * @param {undefined} options
+ * @param {object} context
+ * @returns {string|undefined|null}
+ */
+export function toUpperCaseTransformer(value, options, context) {
+  if (value == null) return value;
+  if (typeof value === 'string') return value.toUpperCase();
+  throw new InvalidArgumentError(
+    'The property transformer %v requires a String value, but %v given.',
+    context.transformerName,
+    value,
+  );
+}

+ 39 - 0
src/definition/model/properties/property-transformer/builtin/to-upper-case-transformer.spec.js

@@ -0,0 +1,39 @@
+import {expect} from 'chai';
+import {format} from '@e22m4u/js-format';
+import {toUpperCaseTransformer} from './to-upper-case-transformer.js';
+
+describe('toUpperCaseTransformer', function () {
+  it('returns undefined and null values as is', function () {
+    const res1 = toUpperCaseTransformer(undefined, undefined, {});
+    const res2 = toUpperCaseTransformer(null, undefined, {});
+    expect(res1).to.be.undefined;
+    expect(res2).to.be.null;
+  });
+
+  it('converts the given string to upper case', function () {
+    const res = toUpperCaseTransformer('test', undefined, {});
+    expect(res).to.be.eq('TEST');
+  });
+
+  it('throws an error if the given value is not a string', function () {
+    const throwable = v => () =>
+      toUpperCaseTransformer(v, undefined, {
+        transformerName: 'toUpperCase',
+      });
+    const error = v =>
+      format(
+        'The property transformer "toUpperCase" requires a String value, but %s given.',
+        v,
+      );
+    expect(throwable(10)).to.throw(error('10'));
+    expect(throwable(0)).to.throw(error('0'));
+    expect(throwable(true)).to.throw(error('true'));
+    expect(throwable(false)).to.throw(error('false'));
+    expect(throwable({})).to.throw(error('Object'));
+    expect(throwable([])).to.throw(error('Array'));
+    throwable('str')();
+    throwable('')();
+    throwable(undefined)();
+    throwable(null)();
+  });
+});

+ 6 - 0
src/definition/model/properties/property-transformer/property-transformer-registry.js

@@ -1,5 +1,8 @@
 import {Service} from '@e22m4u/js-service';
 import {Service} from '@e22m4u/js-service';
 import {trimTransformer} from './builtin/index.js';
 import {trimTransformer} from './builtin/index.js';
+import {toUpperCaseTransformer} from './builtin/index.js';
+import {toLowerCaseTransformer} from './builtin/index.js';
+import {toTitleCaseTransformer} from './builtin/index.js';
 import {InvalidArgumentError} from '../../../../errors/index.js';
 import {InvalidArgumentError} from '../../../../errors/index.js';
 
 
 /**
 /**
@@ -13,6 +16,9 @@ export class PropertyTransformerRegistry extends Service {
    */
    */
   _transformers = {
   _transformers = {
     trim: trimTransformer,
     trim: trimTransformer,
+    toUpperCase: toUpperCaseTransformer,
+    toLowerCase: toLowerCaseTransformer,
+    toTitleCase: toTitleCaseTransformer,
   };
   };
 
 
   /**
   /**

+ 6 - 0
src/definition/model/properties/property-transformer/property-transformer-registry.spec.js

@@ -1,6 +1,9 @@
 import {expect} from 'chai';
 import {expect} from 'chai';
 import {format} from '@e22m4u/js-format';
 import {format} from '@e22m4u/js-format';
 import {trimTransformer} from './builtin/index.js';
 import {trimTransformer} from './builtin/index.js';
+import {toUpperCaseTransformer} from './builtin/index.js';
+import {toLowerCaseTransformer} from './builtin/index.js';
+import {toTitleCaseTransformer} from './builtin/index.js';
 import {PropertyTransformerRegistry} from './property-transformer-registry.js';
 import {PropertyTransformerRegistry} from './property-transformer-registry.js';
 
 
 describe('PropertyTransformerRegistry', function () {
 describe('PropertyTransformerRegistry', function () {
@@ -9,6 +12,9 @@ describe('PropertyTransformerRegistry', function () {
       const S = new PropertyTransformerRegistry();
       const S = new PropertyTransformerRegistry();
       expect(S['_transformers']).to.be.eql({
       expect(S['_transformers']).to.be.eql({
         trim: trimTransformer,
         trim: trimTransformer,
+        toUpperCase: toUpperCaseTransformer,
+        toLowerCase: toLowerCaseTransformer,
+        toTitleCase: toTitleCaseTransformer,
       });
       });
     });
     });