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

refactor: swaps data and schema arguments

e22m4u 1 месяц назад
Родитель
Сommit
d603ed7f8f
6 измененных файлов с 100 добавлено и 104 удалено
  1. 17 17
      README.md
  2. 12 12
      dist/cjs/index.cjs
  3. 9 9
      src/data-projector.js
  4. 14 16
      src/data-projector.spec.js
  5. 4 4
      src/project-data.js
  6. 44 46
      src/project-data.spec.js

+ 17 - 17
README.md

@@ -97,7 +97,7 @@ const data = {
   extra: 10,           // будет доступно в режиме по умолчанию
   extra: 10,           // будет доступно в режиме по умолчанию
 };
 };
 
 
-const result = projectData(schema, data);
+const result = projectData(data, schema);
 console.log(result);
 console.log(result);
 // {
 // {
 //   name: 'Fedor',
 //   name: 'Fedor',
@@ -120,7 +120,7 @@ const data = [
   {id: 2, secret: 'B'},
   {id: 2, secret: 'B'},
 ];
 ];
 
 
-const result = projectData(schema, data);
+const result = projectData(data, schema);
 console.log(result);
 console.log(result);
 // [
 // [
 //   {id: 1},
 //   {id: 1},
@@ -154,7 +154,7 @@ const data = {
   },
   },
 };
 };
 
 
-const result = projectData(schema, data);
+const result = projectData(data, schema);
 console.log(result);
 console.log(result);
 // {
 // {
 //   name: 'Fedor',
 //   name: 'Fedor',
@@ -182,7 +182,7 @@ const data = {
   extra: 10,           // будет исключено в строгом режиме
   extra: 10,           // будет исключено в строгом режиме
 };
 };
 
 
-const result = projectData(schema, data, {
+const result = projectData(data, schema, {
   strict: true, // <= строгий режим
   strict: true, // <= строгий режим
 });
 });
 console.log(result);
 console.log(result);
@@ -213,7 +213,7 @@ const data = {
   password: 'pass123', // будет доступно в зависимости от области
   password: 'pass123', // будет доступно в зависимости от области
 };
 };
 
 
-const inputData = projectData(schema, data, {
+const inputData = projectData(data, schema, {
   scope: 'input', // <= область видимости
   scope: 'input', // <= область видимости
 });
 });
 console.log(inputData);
 console.log(inputData);
@@ -222,7 +222,7 @@ console.log(inputData);
 //   password: 'pass123'
 //   password: 'pass123'
 // }
 // }
 
 
-const outputData = projectData(schema, data, {
+const outputData = projectData(data, schema, {
   scope: 'output', // <= область видимости
   scope: 'output', // <= область видимости
 });
 });
 console.log(outputData);
 console.log(outputData);
@@ -256,16 +256,16 @@ const data = {
   password: 'secret123',
   password: 'secret123',
 }
 }
 
 
-// аналог dps.projectData('user', data, {scope: 'input'})
-const input = dps.projectInput('user', data);
+// аналог dps.projectData(data, 'user', {scope: 'input'})
+const input = dps.projectInput(data, 'user');
 console.log(input);
 console.log(input);
 // {
 // {
 //   username: 'john_doe',
 //   username: 'john_doe',
 //   password: 'secret123'
 //   password: 'secret123'
 // }
 // }
 
 
-// аналог dps.projectData('user', data, {scope: 'output'})
-const output = dps.projectOutput('user', data);
+// аналог dps.projectData(data, 'user', {scope: 'output'})
+const output = dps.projectOutput(data, 'user');
 console.log(output);
 console.log(output);
 // {
 // {
 //   username: 'john_doe'
 //   username: 'john_doe'
@@ -293,7 +293,7 @@ const data = {
 };
 };
 
 
 // передача функции вместо объекта
 // передача функции вместо объекта
-const result = projectData(getSchema, data);
+const result = projectData(data, getSchema);
 console.log(result);
 console.log(result);
 // {
 // {
 //   id: 1
 //   id: 1
@@ -326,7 +326,7 @@ const data = {
   },
   },
 };
 };
 
 
-const result = projectData(userSchema, data);
+const result = projectData(data, userSchema);
 console.log(result);
 console.log(result);
 // {
 // {
 //   name: 'Fedor',
 //   name: 'Fedor',
@@ -357,7 +357,7 @@ const data = {
   secret: 'john123',
   secret: 'john123',
 };
 };
 
 
-const result = projectData(getSchema, data, {
+const result = projectData(data, getSchema, {
   factoryArgs: [logger], // <= передача logger в фабрику
   factoryArgs: [logger], // <= передача logger в фабрику
 });
 });
 // Factory was invoked!
 // Factory was invoked!
@@ -389,7 +389,7 @@ const data = {
   secret: 'john123',
   secret: 'john123',
 };
 };
 
 
-const result = dps.projectData(getSchema, data);
+const result = dps.projectData(data, getSchema);
 console.log(result);
 console.log(result);
 // {
 // {
 //   name: 'John',
 //   name: 'John',
@@ -422,7 +422,7 @@ const data = {
 };
 };
 
 
 // проекция данных по зарегистрированному имени
 // проекция данных по зарегистрированному имени
-const result = dps.projectData('user', data);
+const result = dps.projectData(data, 'user');
 console.log(result);
 console.log(result);
 // {
 // {
 //   id: 10,
 //   id: 10,
@@ -466,7 +466,7 @@ const data = {
   },
   },
 };
 };
 
 
-const result = dps.projectData('user', data);
+const result = dps.projectData(data, 'user');
 console.log(result);
 console.log(result);
 // {
 // {
 //   name: 'Fedor',
 //   name: 'Fedor',
@@ -496,8 +496,8 @@ const data = {
 };
 };
 
 
 const result = projectData(
 const result = projectData(
-  'user', // <= вместо схемы передается имя
   data,
   data,
+  'user', // <= вместо схемы передается имя
   {nameResolver}, // <= разрешающая функция
   {nameResolver}, // <= разрешающая функция
 );
 );
 console.log(result);
 console.log(result);

+ 12 - 12
dist/cjs/index.cjs

@@ -124,7 +124,7 @@ function validateProjectionSchema(schema, shallowMode = false, validatedSchemas
 __name(validateProjectionSchema, "validateProjectionSchema");
 __name(validateProjectionSchema, "validateProjectionSchema");
 
 
 // src/project-data.js
 // src/project-data.js
-function projectData(schema, data, options) {
+function projectData(data, schema, options) {
   if (options !== void 0) {
   if (options !== void 0) {
     if (!options || typeof options !== "object" || Array.isArray(options)) {
     if (!options || typeof options !== "object" || Array.isArray(options)) {
       throw new import_js_format2.InvalidArgumentError(
       throw new import_js_format2.InvalidArgumentError(
@@ -187,7 +187,7 @@ function projectData(schema, data, options) {
     return data;
     return data;
   }
   }
   if (Array.isArray(data)) {
   if (Array.isArray(data)) {
-    return data.map((item) => projectData(schema, item, options));
+    return data.map((item) => projectData(item, schema, options));
   }
   }
   const result = {};
   const result = {};
   const strict = Boolean(options && options.strict);
   const strict = Boolean(options && options.strict);
@@ -199,7 +199,7 @@ function projectData(schema, data, options) {
     if (_shouldSelect(propOptions, strict, scope)) {
     if (_shouldSelect(propOptions, strict, scope)) {
       const value = data[propName];
       const value = data[propName];
       if (propOptions && typeof propOptions === "object" && propOptions.schema) {
       if (propOptions && typeof propOptions === "object" && propOptions.schema) {
-        result[propName] = projectData(propOptions.schema, value, options);
+        result[propName] = projectData(value, propOptions.schema, options);
       } else {
       } else {
         result[propName] = value;
         result[propName] = value;
       }
       }
@@ -345,39 +345,39 @@ var _DataProjector = class _DataProjector extends import_js_service2.Service {
   /**
   /**
    * Project data.
    * Project data.
    *
    *
-   * @param {object|Function|string} schema
    * @param {object|object[]|*} data
    * @param {object|object[]|*} data
+   * @param {object|Function|string} schema
    * @param {object} [options]
    * @param {object} [options]
    * @returns {*}
    * @returns {*}
    */
    */
-  projectData(schema, data, options) {
+  projectData(data, schema, options) {
     const registry = this.getService(ProjectionSchemaRegistry);
     const registry = this.getService(ProjectionSchemaRegistry);
     const defaultNameResolver = /* @__PURE__ */ __name((name) => registry.getSchema(name), "defaultNameResolver");
     const defaultNameResolver = /* @__PURE__ */ __name((name) => registry.getSchema(name), "defaultNameResolver");
     const nameResolver = options && options.nameResolver || defaultNameResolver;
     const nameResolver = options && options.nameResolver || defaultNameResolver;
     const factoryArgs = options && options.factoryArgs || [this.container];
     const factoryArgs = options && options.factoryArgs || [this.container];
-    return projectData(schema, data, { ...options, nameResolver, factoryArgs });
+    return projectData(data, schema, { ...options, nameResolver, factoryArgs });
   }
   }
   /**
   /**
    * Project input.
    * Project input.
    *
    *
-   * @param {object|Function|string} schema
    * @param {object|object[]|*} data
    * @param {object|object[]|*} data
+   * @param {object|Function|string} schema
    * @param {object} [options]
    * @param {object} [options]
    * @returns {*}
    * @returns {*}
    */
    */
-  projectInput(schema, data, options) {
-    return this.projectData(schema, data, { ...options, scope: "input" });
+  projectInput(data, schema, options) {
+    return this.projectData(data, schema, { ...options, scope: "input" });
   }
   }
   /**
   /**
    * Project output.
    * Project output.
    *
    *
-   * @param {object|Function|string} schema
    * @param {object|object[]|*} data
    * @param {object|object[]|*} data
+   * @param {object|Function|string} schema
    * @param {object} [options]
    * @param {object} [options]
    * @returns {*}
    * @returns {*}
    */
    */
-  projectOutput(schema, data, options) {
-    return this.projectData(schema, data, { ...options, scope: "output" });
+  projectOutput(data, schema, options) {
+    return this.projectData(data, schema, { ...options, scope: "output" });
   }
   }
 };
 };
 __name(_DataProjector, "DataProjector");
 __name(_DataProjector, "DataProjector");

+ 9 - 9
src/data-projector.js

@@ -20,41 +20,41 @@ export class DataProjector extends Service {
   /**
   /**
    * Project data.
    * Project data.
    *
    *
-   * @param {object|Function|string} schema
    * @param {object|object[]|*} data
    * @param {object|object[]|*} data
+   * @param {object|Function|string} schema
    * @param {object} [options]
    * @param {object} [options]
    * @returns {*}
    * @returns {*}
    */
    */
-  projectData(schema, data, options) {
+  projectData(data, schema, options) {
     const registry = this.getService(ProjectionSchemaRegistry);
     const registry = this.getService(ProjectionSchemaRegistry);
     const defaultNameResolver = name => registry.getSchema(name);
     const defaultNameResolver = name => registry.getSchema(name);
     const nameResolver =
     const nameResolver =
       (options && options.nameResolver) || defaultNameResolver;
       (options && options.nameResolver) || defaultNameResolver;
     const factoryArgs = (options && options.factoryArgs) || [this.container];
     const factoryArgs = (options && options.factoryArgs) || [this.container];
-    return projectData(schema, data, {...options, nameResolver, factoryArgs});
+    return projectData(data, schema, {...options, nameResolver, factoryArgs});
   }
   }
 
 
   /**
   /**
    * Project input.
    * Project input.
    *
    *
-   * @param {object|Function|string} schema
    * @param {object|object[]|*} data
    * @param {object|object[]|*} data
+   * @param {object|Function|string} schema
    * @param {object} [options]
    * @param {object} [options]
    * @returns {*}
    * @returns {*}
    */
    */
-  projectInput(schema, data, options) {
-    return this.projectData(schema, data, {...options, scope: 'input'});
+  projectInput(data, schema, options) {
+    return this.projectData(data, schema, {...options, scope: 'input'});
   }
   }
 
 
   /**
   /**
    * Project output.
    * Project output.
    *
    *
-   * @param {object|Function|string} schema
    * @param {object|object[]|*} data
    * @param {object|object[]|*} data
+   * @param {object|Function|string} schema
    * @param {object} [options]
    * @param {object} [options]
    * @returns {*}
    * @returns {*}
    */
    */
-  projectOutput(schema, data, options) {
-    return this.projectData(schema, data, {...options, scope: 'output'});
+  projectOutput(data, schema, options) {
+    return this.projectData(data, schema, {...options, scope: 'output'});
   }
   }
 }
 }

+ 14 - 16
src/data-projector.spec.js

@@ -42,25 +42,23 @@ describe('DataProjector', function () {
   describe('projectData', function () {
   describe('projectData', function () {
     it('should project the data object by the given schema', function () {
     it('should project the data object by the given schema', function () {
       const S = new DataProjector();
       const S = new DataProjector();
-      const res = S.projectData({foo: true, bar: false}, {foo: 10, bar: 20});
+      const res = S.projectData({foo: 10, bar: 20}, {foo: true, bar: false});
       expect(res).to.be.eql({foo: 10});
       expect(res).to.be.eql({foo: 10});
     });
     });
 
 
     it('should project the data object by the schema name', function () {
     it('should project the data object by the schema name', function () {
       const S = new DataProjector();
       const S = new DataProjector();
       S.defineSchema({name: 'mySchema', schema: {foo: true, bar: false}});
       S.defineSchema({name: 'mySchema', schema: {foo: true, bar: false}});
-      const res = S.projectData('mySchema', {foo: 10, bar: 20, baz: 30});
+      const res = S.projectData({foo: 10, bar: 20, baz: 30}, 'mySchema');
       expect(res).to.be.eql({foo: 10, baz: 30});
       expect(res).to.be.eql({foo: 10, baz: 30});
     });
     });
 
 
     it('should exclude properties without rules in the strict mode', function () {
     it('should exclude properties without rules in the strict mode', function () {
       const S = new DataProjector();
       const S = new DataProjector();
       S.defineSchema({name: 'mySchema', schema: {foo: true, bar: false}});
       S.defineSchema({name: 'mySchema', schema: {foo: true, bar: false}});
-      const res = S.projectData(
-        'mySchema',
-        {foo: 10, bar: 20, baz: 30},
-        {strict: true},
-      );
+      const res = S.projectData({foo: 10, bar: 20, baz: 30}, 'mySchema', {
+        strict: true,
+      });
       expect(res).to.be.eql({foo: 10});
       expect(res).to.be.eql({foo: 10});
     });
     });
 
 
@@ -73,7 +71,7 @@ describe('DataProjector', function () {
         expect(name).to.be.eq(schemaName);
         expect(name).to.be.eq(schemaName);
         return {foo: true, bar: false};
         return {foo: true, bar: false};
       };
       };
-      const res = S.projectData('mySchema', {foo: 10, bar: 20}, {nameResolver});
+      const res = S.projectData({foo: 10, bar: 20}, 'mySchema', {nameResolver});
       expect(res).to.be.eql({foo: 10});
       expect(res).to.be.eql({foo: 10});
       expect(invoked).to.be.eq(1);
       expect(invoked).to.be.eq(1);
     });
     });
@@ -86,7 +84,7 @@ describe('DataProjector', function () {
         expect(container).to.be.eq(S.container);
         expect(container).to.be.eq(S.container);
         return {foo: true, bar: false};
         return {foo: true, bar: false};
       };
       };
-      const res = S.projectData(factory, {foo: 10, bar: 20});
+      const res = S.projectData({foo: 10, bar: 20}, factory);
       expect(res).to.be.eql({foo: 10});
       expect(res).to.be.eql({foo: 10});
       expect(invoked).to.be.eq(1);
       expect(invoked).to.be.eq(1);
     });
     });
@@ -100,7 +98,7 @@ describe('DataProjector', function () {
         expect(args).to.be.eql(factoryArgs);
         expect(args).to.be.eql(factoryArgs);
         return {foo: true, bar: false};
         return {foo: true, bar: false};
       };
       };
-      const res = S.projectData(factory, {foo: 10, bar: 20}, {factoryArgs});
+      const res = S.projectData({foo: 10, bar: 20}, factory, {factoryArgs});
       expect(res).to.be.eql({foo: 10});
       expect(res).to.be.eql({foo: 10});
       expect(invoked).to.be.eq(1);
       expect(invoked).to.be.eq(1);
     });
     });
@@ -115,11 +113,11 @@ describe('DataProjector', function () {
       const result = {foo: 10};
       const result = {foo: 10};
       let invoked = 0;
       let invoked = 0;
       S.projectData = (...args) => {
       S.projectData = (...args) => {
-        expect(args).to.be.eql([schema, data, {extra: true, scope: 'input'}]);
+        expect(args).to.be.eql([data, schema, {extra: true, scope: 'input'}]);
         invoked++;
         invoked++;
         return result;
         return result;
       };
       };
-      const res = S.projectInput(schema, data, options);
+      const res = S.projectInput(data, schema, options);
       expect(res).to.be.eq(result);
       expect(res).to.be.eq(result);
       expect(invoked).to.be.eq(1);
       expect(invoked).to.be.eq(1);
     });
     });
@@ -131,7 +129,7 @@ describe('DataProjector', function () {
         bar: {select: true, scopes: {input: false}},
         bar: {select: true, scopes: {input: false}},
       };
       };
       const data = {foo: 10, bar: 20};
       const data = {foo: 10, bar: 20};
-      const res = S.projectInput(schema, data);
+      const res = S.projectInput(data, schema);
       expect(res).to.be.eql({foo: 10});
       expect(res).to.be.eql({foo: 10});
     });
     });
   });
   });
@@ -145,11 +143,11 @@ describe('DataProjector', function () {
       const result = {foo: 10};
       const result = {foo: 10};
       let invoked = 0;
       let invoked = 0;
       S.projectData = (...args) => {
       S.projectData = (...args) => {
-        expect(args).to.be.eql([schema, data, {extra: true, scope: 'output'}]);
+        expect(args).to.be.eql([data, schema, {extra: true, scope: 'output'}]);
         invoked++;
         invoked++;
         return result;
         return result;
       };
       };
-      const res = S.projectOutput(schema, data, options);
+      const res = S.projectOutput(data, schema, options);
       expect(res).to.be.eq(result);
       expect(res).to.be.eq(result);
       expect(invoked).to.be.eq(1);
       expect(invoked).to.be.eq(1);
     });
     });
@@ -161,7 +159,7 @@ describe('DataProjector', function () {
         bar: {select: true, scopes: {output: false}},
         bar: {select: true, scopes: {output: false}},
       };
       };
       const data = {foo: 10, bar: 20};
       const data = {foo: 10, bar: 20};
-      const res = S.projectOutput(schema, data);
+      const res = S.projectOutput(data, schema);
       expect(res).to.be.eql({foo: 10});
       expect(res).to.be.eql({foo: 10});
     });
     });
   });
   });

+ 4 - 4
src/project-data.js

@@ -4,12 +4,12 @@ import {validateProjectionSchema} from './validate-projection-schema.js';
 /**
 /**
  * Project data.
  * Project data.
  *
  *
- * @param {object|Function|string} schema
  * @param {object|object[]|*} data
  * @param {object|object[]|*} data
+ * @param {object|Function|string} schema
  * @param {object} [options]
  * @param {object} [options]
  * @returns {*}
  * @returns {*}
  */
  */
-export function projectData(schema, data, options) {
+export function projectData(data, schema, options) {
   // options
   // options
   if (options !== undefined) {
   if (options !== undefined) {
     if (!options || typeof options !== 'object' || Array.isArray(options)) {
     if (!options || typeof options !== 'object' || Array.isArray(options)) {
@@ -108,7 +108,7 @@ export function projectData(schema, data, options) {
   // если данные являются массивом,
   // если данные являются массивом,
   // то схема применяется к каждому элементу
   // то схема применяется к каждому элементу
   if (Array.isArray(data)) {
   if (Array.isArray(data)) {
-    return data.map(item => projectData(schema, item, options));
+    return data.map(item => projectData(item, schema, options));
   }
   }
   // если данные являются объектом,
   // если данные являются объектом,
   // то проекция создается согласно схеме
   // то проекция создается согласно схеме
@@ -135,7 +135,7 @@ export function projectData(schema, data, options) {
         typeof propOptions === 'object' &&
         typeof propOptions === 'object' &&
         propOptions.schema
         propOptions.schema
       ) {
       ) {
-        result[propName] = projectData(propOptions.schema, value, options);
+        result[propName] = projectData(value, propOptions.schema, options);
       }
       }
       // иначе значение присваивается
       // иначе значение присваивается
       // свойству без изменений
       // свойству без изменений

+ 44 - 46
src/project-data.spec.js

@@ -4,7 +4,7 @@ import {projectData} from './project-data.js';
 
 
 describe('projectData', function () {
 describe('projectData', function () {
   it('should require the "options" argument to be an object', function () {
   it('should require the "options" argument to be an object', function () {
-    const throwable = v => () => projectData({}, 10, v);
+    const throwable = v => () => projectData(10, {}, v);
     const error = s =>
     const error = s =>
       format('Projection options must be an Object, but %s was given.', s);
       format('Projection options must be an Object, but %s was given.', s);
     expect(throwable('str')).to.throw(error('"str"'));
     expect(throwable('str')).to.throw(error('"str"'));
@@ -20,7 +20,7 @@ describe('projectData', function () {
   });
   });
 
 
   it('should require the "strict" option to be a boolean', function () {
   it('should require the "strict" option to be a boolean', function () {
-    const throwable = v => () => projectData({}, 10, {strict: v});
+    const throwable = v => () => projectData(10, {}, {strict: v});
     const error = s =>
     const error = s =>
       format(
       format(
         'Projection option "strict" must be a Boolean, but %s was given.',
         'Projection option "strict" must be a Boolean, but %s was given.',
@@ -39,7 +39,7 @@ describe('projectData', function () {
   });
   });
 
 
   it('should require the "scope" option to be a non-empty string', function () {
   it('should require the "scope" option to be a non-empty string', function () {
-    const throwable = v => () => projectData({}, 10, {scope: v});
+    const throwable = v => () => projectData(10, {}, {scope: v});
     const error = s =>
     const error = s =>
       format(
       format(
         'Projection option "scope" must be a non-empty String, ' +
         'Projection option "scope" must be a non-empty String, ' +
@@ -59,7 +59,7 @@ describe('projectData', function () {
   });
   });
 
 
   it('should require the "nameResolver" option to be a function', function () {
   it('should require the "nameResolver" option to be a function', function () {
-    const throwable = v => () => projectData({}, 10, {nameResolver: v});
+    const throwable = v => () => projectData(10, {}, {nameResolver: v});
     const error = s =>
     const error = s =>
       format(
       format(
         'Projection option "nameResolver" must be ' +
         'Projection option "nameResolver" must be ' +
@@ -80,7 +80,7 @@ describe('projectData', function () {
   });
   });
 
 
   it('should require the "factoryArgs" option to be an Array', function () {
   it('should require the "factoryArgs" option to be an Array', function () {
-    const throwable = v => () => projectData({}, 10, {factoryArgs: v});
+    const throwable = v => () => projectData(10, {}, {factoryArgs: v});
     const error = s =>
     const error = s =>
       format(
       format(
         'Projection option "factoryArgs" must be an Array, but %s was given.',
         'Projection option "factoryArgs" must be an Array, but %s was given.',
@@ -104,7 +104,7 @@ describe('projectData', function () {
       invoked++;
       invoked++;
       return {foo: true, bar: false};
       return {foo: true, bar: false};
     };
     };
-    const res = projectData(factory, {foo: 10, bar: 20});
+    const res = projectData({foo: 10, bar: 20}, factory);
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
     expect(invoked).to.be.eq(1);
     expect(invoked).to.be.eq(1);
   });
   });
@@ -117,7 +117,7 @@ describe('projectData', function () {
       expect(args).to.be.eql(factoryArgs);
       expect(args).to.be.eql(factoryArgs);
       return {foo: true, bar: false};
       return {foo: true, bar: false};
     };
     };
-    const res = projectData(factory, {foo: 10, bar: 20}, {factoryArgs});
+    const res = projectData({foo: 10, bar: 20}, factory, {factoryArgs});
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
     expect(invoked).to.be.eq(1);
     expect(invoked).to.be.eq(1);
   });
   });
@@ -131,8 +131,8 @@ describe('projectData', function () {
       return {bar: true, baz: false};
       return {bar: true, baz: false};
     };
     };
     const res = projectData(
     const res = projectData(
-      {foo: {schema: factory}},
       {foo: {bar: 10, baz: 20}},
       {foo: {bar: 10, baz: 20}},
+      {foo: {schema: factory}},
       {factoryArgs},
       {factoryArgs},
     );
     );
     expect(res).to.be.eql({foo: {bar: 10}});
     expect(res).to.be.eql({foo: {bar: 10}});
@@ -140,7 +140,7 @@ describe('projectData', function () {
   });
   });
 
 
   it('should require a factory value to be an object or a non-empty string', function () {
   it('should require a factory value to be an object or a non-empty string', function () {
-    const throwable = v => () => projectData(() => v, {});
+    const throwable = v => () => projectData({}, () => v);
     const error = s =>
     const error = s =>
       format(
       format(
         'Schema factory must return an Object ' +
         'Schema factory must return an Object ' +
@@ -156,8 +156,8 @@ describe('projectData', function () {
     expect(throwable(undefined)).to.throw(error('undefined'));
     expect(throwable(undefined)).to.throw(error('undefined'));
     expect(throwable(null)).to.throw(error('null'));
     expect(throwable(null)).to.throw(error('null'));
     expect(throwable(() => undefined)).to.throw(error('Function'));
     expect(throwable(() => undefined)).to.throw(error('Function'));
-    projectData(() => ({}), {});
-    projectData(() => 'str', {}, {nameResolver: () => ({})});
+    projectData({}, () => ({}));
+    projectData({}, () => 'str', {nameResolver: () => ({})});
   });
   });
 
 
   it('should resolve the schema name by the name resolver', function () {
   it('should resolve the schema name by the name resolver', function () {
@@ -167,13 +167,13 @@ describe('projectData', function () {
       expect(name).to.be.eql('mySchema');
       expect(name).to.be.eql('mySchema');
       return {foo: true, bar: false};
       return {foo: true, bar: false};
     };
     };
-    const res = projectData('mySchema', {foo: 10, bar: 20}, {nameResolver});
+    const res = projectData({foo: 10, bar: 20}, 'mySchema', {nameResolver});
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
     expect(invoked).to.be.eq(1);
     expect(invoked).to.be.eq(1);
   });
   });
 
 
   it('should require the "nameResolver" option when the schema name is provided', function () {
   it('should require the "nameResolver" option when the schema name is provided', function () {
-    const throwable = () => projectData('mySchema', {});
+    const throwable = () => projectData({}, 'mySchema');
     expect(throwable).to.throw(
     expect(throwable).to.throw(
       'Projection option "nameResolver" is required ' +
       'Projection option "nameResolver" is required ' +
         'to resolve "mySchema" name.',
         'to resolve "mySchema" name.',
@@ -182,7 +182,7 @@ describe('projectData', function () {
 
 
   it('should require the name resolver to return an object', function () {
   it('should require the name resolver to return an object', function () {
     const throwable = v => () =>
     const throwable = v => () =>
-      projectData('mySchema', {}, {nameResolver: () => v});
+      projectData({}, 'mySchema', {nameResolver: () => v});
     const error = s =>
     const error = s =>
       format('Name resolver must return an Object, but %s was given.', s);
       format('Name resolver must return an Object, but %s was given.', s);
     expect(throwable('str')).to.throw(error('"str"'));
     expect(throwable('str')).to.throw(error('"str"'));
@@ -205,11 +205,9 @@ describe('projectData', function () {
       expect(name).to.be.eql('mySchema');
       expect(name).to.be.eql('mySchema');
       return {foo: true, bar: false};
       return {foo: true, bar: false};
     };
     };
-    const res = projectData(
-      () => 'mySchema',
-      {foo: 10, bar: 20},
-      {nameResolver},
-    );
+    const res = projectData({foo: 10, bar: 20}, () => 'mySchema', {
+      nameResolver,
+    });
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
     expect(invoked).to.be.eq(1);
     expect(invoked).to.be.eq(1);
   });
   });
@@ -225,7 +223,7 @@ describe('projectData', function () {
       }
       }
     };
     };
     const data = {foo: 10, bar: {baz: 20, qux: 30}};
     const data = {foo: 10, bar: {baz: 20, qux: 30}};
-    const res = projectData('schema1', data, {nameResolver});
+    const res = projectData(data, 'schema1', {nameResolver});
     expect(res).to.be.eql({foo: 10, bar: {baz: 20}});
     expect(res).to.be.eql({foo: 10, bar: {baz: 20}});
     expect(invoked).to.be.eq(2);
     expect(invoked).to.be.eq(2);
   });
   });
@@ -233,45 +231,45 @@ describe('projectData', function () {
   it('should validate the given schema in the shallow mode', function () {
   it('should validate the given schema in the shallow mode', function () {
     const schema1 = {foo: '?'};
     const schema1 = {foo: '?'};
     const schema2 = {foo: true, bar: {schema: {baz: '?'}}};
     const schema2 = {foo: true, bar: {schema: {baz: '?'}}};
-    expect(() => projectData(schema1, {foo: 10})).to.throw(
+    expect(() => projectData({foo: 10}, schema1)).to.throw(
       'Property options must be an Object or a Boolean, but "?" was given.',
       'Property options must be an Object or a Boolean, but "?" was given.',
     );
     );
-    const res = projectData(schema2, {foo: 10});
+    const res = projectData({foo: 10}, schema2);
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
-    expect(() => projectData(schema2, {bar: {baz: 20}})).to.throw(
+    expect(() => projectData({bar: {baz: 20}}, schema2)).to.throw(
       'Property options must be an Object or a Boolean, but "?" was given.',
       'Property options must be an Object or a Boolean, but "?" was given.',
     );
     );
   });
   });
 
 
   it('should return primitive value as is', function () {
   it('should return primitive value as is', function () {
-    expect(projectData({}, 'str')).to.be.eq('str');
-    expect(projectData({}, '')).to.be.eq('');
-    expect(projectData({}, 10)).to.be.eq(10);
-    expect(projectData({}, 0)).to.be.eq(0);
-    expect(projectData({}, true)).to.be.eq(true);
-    expect(projectData({}, false)).to.be.eq(false);
-    expect(projectData({}, undefined)).to.be.eq(undefined);
-    expect(projectData({}, null)).to.be.eq(null);
+    expect(projectData('str', {})).to.be.eq('str');
+    expect(projectData('', {})).to.be.eq('');
+    expect(projectData(10, {})).to.be.eq(10);
+    expect(projectData(0, {})).to.be.eq(0);
+    expect(projectData(true, {})).to.be.eq(true);
+    expect(projectData(false, {})).to.be.eq(false);
+    expect(projectData(undefined, {})).to.be.eq(undefined);
+    expect(projectData(null, {})).to.be.eq(null);
   });
   });
 
 
   it('should project an array items', function () {
   it('should project an array items', function () {
     const list = [{foo: 10, bar: 20, baz: 30}, {qux: 30}];
     const list = [{foo: 10, bar: 20, baz: 30}, {qux: 30}];
     const expectedList = [{foo: 10, baz: 30}, {qux: 30}];
     const expectedList = [{foo: 10, baz: 30}, {qux: 30}];
-    const res = projectData({foo: true, bar: false}, list);
+    const res = projectData(list, {foo: true, bar: false});
     expect(res).to.be.eql(expectedList);
     expect(res).to.be.eql(expectedList);
   });
   });
 
 
   it('should project an array items in the strict mode', function () {
   it('should project an array items in the strict mode', function () {
     const list = [{foo: 10, bar: 20, baz: 30}, {qux: 30}];
     const list = [{foo: 10, bar: 20, baz: 30}, {qux: 30}];
     const expectedList = [{foo: 10}, {}];
     const expectedList = [{foo: 10}, {}];
-    const res = projectData({foo: true, bar: false}, list, {strict: true});
+    const res = projectData(list, {foo: true, bar: false}, {strict: true});
     expect(res).to.be.eql(expectedList);
     expect(res).to.be.eql(expectedList);
   });
   });
 
 
   it('should exclude properties without rules when the strict mode is enabled', function () {
   it('should exclude properties without rules when the strict mode is enabled', function () {
     const res = projectData(
     const res = projectData(
-      {foo: true, bar: false},
       {foo: 10, bar: 20, baz: 30},
       {foo: 10, bar: 20, baz: 30},
+      {foo: true, bar: false},
       {strict: true},
       {strict: true},
     );
     );
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
@@ -282,19 +280,19 @@ describe('projectData', function () {
     data.foo = 10;
     data.foo = 10;
     data.bar = 20;
     data.bar = 20;
     expect(data).to.be.eql({foo: 10, bar: 20, baz: 30});
     expect(data).to.be.eql({foo: 10, bar: 20, baz: 30});
-    const res = projectData({foo: true, bar: false}, data);
+    const res = projectData(data, {foo: true, bar: false});
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
   });
   });
 
 
   it('should project the property by a boolean rule', function () {
   it('should project the property by a boolean rule', function () {
-    const res = projectData({foo: true, bar: false}, {foo: 10, bar: 20});
+    const res = projectData({foo: 10, bar: 20}, {foo: true, bar: false});
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
   });
   });
 
 
   it('should project the property by the select option', function () {
   it('should project the property by the select option', function () {
     const res = projectData(
     const res = projectData(
-      {foo: {select: true}, bar: {select: false}},
       {foo: 10, bar: 20},
       {foo: 10, bar: 20},
+      {foo: {select: true}, bar: {select: false}},
     );
     );
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
   });
   });
@@ -304,7 +302,7 @@ describe('projectData', function () {
       foo: {select: true, scopes: {input: false}},
       foo: {select: true, scopes: {input: false}},
       bar: {select: false, scopes: {output: true}},
       bar: {select: false, scopes: {output: true}},
     };
     };
-    const res = projectData(schema, {foo: 10, bar: 20});
+    const res = projectData({foo: 10, bar: 20}, schema);
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
   });
   });
 
 
@@ -313,7 +311,7 @@ describe('projectData', function () {
       foo: {scopes: {input: true}},
       foo: {scopes: {input: true}},
       bar: {scopes: {input: false}},
       bar: {scopes: {input: false}},
     };
     };
-    const res = projectData(schema, {foo: 10, bar: 20}, {scope: 'input'});
+    const res = projectData({foo: 10, bar: 20}, schema, {scope: 'input'});
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
   });
   });
 
 
@@ -322,7 +320,7 @@ describe('projectData', function () {
       foo: {scopes: {input: {select: true}}},
       foo: {scopes: {input: {select: true}}},
       bar: {scopes: {input: {select: false}}},
       bar: {scopes: {input: {select: false}}},
     };
     };
-    const res = projectData(schema, {foo: 10, bar: 20}, {scope: 'input'});
+    const res = projectData({foo: 10, bar: 20}, schema, {scope: 'input'});
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
   });
   });
 
 
@@ -331,7 +329,7 @@ describe('projectData', function () {
       foo: {select: false, scopes: {input: true}},
       foo: {select: false, scopes: {input: true}},
       bar: {select: true, scopes: {input: false}},
       bar: {select: true, scopes: {input: false}},
     };
     };
-    const res = projectData(schema, {foo: 10, bar: 20}, {scope: 'input'});
+    const res = projectData({foo: 10, bar: 20}, schema, {scope: 'input'});
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
   });
   });
 
 
@@ -340,7 +338,7 @@ describe('projectData', function () {
       foo: {scopes: {input: true, output: false}},
       foo: {scopes: {input: true, output: false}},
       bar: {scopes: {input: false, output: true}},
       bar: {scopes: {input: false, output: true}},
     };
     };
-    const res = projectData(schema, {foo: 10, bar: 20}, {scope: 'input'});
+    const res = projectData({foo: 10, bar: 20}, schema, {scope: 'input'});
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
   });
   });
 
 
@@ -351,7 +349,7 @@ describe('projectData', function () {
       baz: {scopes: {output: true}},
       baz: {scopes: {output: true}},
     };
     };
     const data = {foo: 10, bar: 20, baz: 30, qux: 40};
     const data = {foo: 10, bar: 20, baz: 30, qux: 40};
-    const res = projectData(schema, data, {strict: true, scope: 'input'});
+    const res = projectData(data, schema, {strict: true, scope: 'input'});
     expect(res).to.be.eql({foo: 10});
     expect(res).to.be.eql({foo: 10});
   });
   });
 
 
@@ -361,7 +359,7 @@ describe('projectData', function () {
       bar: {select: false, scopes: {input: {select: true}}},
       bar: {select: false, scopes: {input: {select: true}}},
     };
     };
     const data = {foo: 10, bar: 20, baz: 30};
     const data = {foo: 10, bar: 20, baz: 30};
-    const res = projectData(schema, data, {strict: true, scope: 'input'});
+    const res = projectData(data, schema, {strict: true, scope: 'input'});
     expect(res).to.be.eql({foo: 10, bar: 20});
     expect(res).to.be.eql({foo: 10, bar: 20});
   });
   });
 
 
@@ -371,7 +369,7 @@ describe('projectData', function () {
       bar: {schema: {baz: true, qux: false}},
       bar: {schema: {baz: true, qux: false}},
     };
     };
     const data = {foo: 10, bar: {baz: 20, qux: 30, buz: 40}};
     const data = {foo: 10, bar: {baz: 20, qux: 30, buz: 40}};
-    const res = projectData(schema, data, {scope: 'input'});
+    const res = projectData(data, schema, {scope: 'input'});
     expect(res).to.be.eql({foo: 10, bar: {baz: 20, buz: 40}});
     expect(res).to.be.eql({foo: 10, bar: {baz: 20, buz: 40}});
   });
   });
 
 
@@ -381,7 +379,7 @@ describe('projectData', function () {
       bar: {select: true, schema: {baz: true, qux: false}},
       bar: {select: true, schema: {baz: true, qux: false}},
     };
     };
     const data = {foo: 10, bar: {baz: 20, qux: 30, buz: 40}};
     const data = {foo: 10, bar: {baz: 20, qux: 30, buz: 40}};
-    const res = projectData(schema, data, {strict: true, scope: 'input'});
+    const res = projectData(data, schema, {strict: true, scope: 'input'});
     expect(res).to.be.eql({foo: 10, bar: {baz: 20}});
     expect(res).to.be.eql({foo: 10, bar: {baz: 20}});
   });
   });
 });
 });