JavaScript модуль для создания проекции данных

e22m4u f7227f5222 feat: add types 4 недель назад
.husky 22b5a33b5f chore: initial commit 1 месяц назад
dist f7227f5222 feat: add types 4 недель назад
src f7227f5222 feat: add types 4 недель назад
.c8rc 22b5a33b5f chore: initial commit 1 месяц назад
.commitlintrc 22b5a33b5f chore: initial commit 1 месяц назад
.editorconfig 22b5a33b5f chore: initial commit 1 месяц назад
.gitignore 22b5a33b5f chore: initial commit 1 месяц назад
.mocharc.json 6f15ecb1a5 refactor: improve linting 1 месяц назад
.prettierrc 22b5a33b5f chore: initial commit 1 месяц назад
LICENSE 22b5a33b5f chore: initial commit 1 месяц назад
README.md 1ec543327b docs: updates README.md 1 месяц назад
build-cjs.js 22b5a33b5f chore: initial commit 1 месяц назад
eslint.config.js 6f15ecb1a5 refactor: improve linting 1 месяц назад
package.json f7227f5222 feat: add types 4 недель назад
tsconfig.json f7227f5222 feat: add types 4 недель назад

README.md

@e22m4u/js-data-projection

JavaScript модуль для работы с проекцией данных.

Содержание

Установка

npm install @e22m4u/js-data-projection

Модуль поддерживает ESM и CommonJS стандарты.

ESM

import {projectData} from '@e22m4u/js-data-projection';

CommonJS

const {projectData} = require('@e22m4u/js-data-projection');

Использование

Ниже приводятся примеры использования данного модуля.

Схема проекции

Определение правил видимости полей.

{
  foo: true, // поле доступно
  bar: false // поле скрыто
}

Определение вложенной схемы.

{
  name: true, // поле name доступно
  address: {  // настройки поля address
    select: true, // поле address доступно
    schema: {     // вложенная схема
      city: true,     // поле city доступно
      zip: false      // поле zip скрыто
    }
  }
}

Определение правил для областей проекции.

{
  password: { // настройки поля password
    select: false,  // поле password недоступно по умолчанию
    scopes: {       // настройки для областей проекции
      input: true,     // поле доступно для области 'input'
      output: false    // но скрыто для области 'output'
    }
  }
}

Применение схемы

Создание проекции данных с помощью схемы.

import {projectData} from '@e22m4u/js-data-projection';

const schema = {
  name: true,
  password: false,
};

const data = {
  name: 'Fedor',       // будет доступно, явное правило
  password: 'pass123', // будет исключено, явное правило
  extra: 10,           // будет доступно в режиме по умолчанию
};

const result = projectData(data, schema);
console.log(result);
// {
//   name: 'Fedor',
//   extra: 10
// }

Применение схемы к массиву объектов.

import {projectData} from '@e22m4u/js-data-projection';

const schema = {
  id: true,
  secret: false,
};

const data = [
  {id: 1, secret: 'A'},
  {id: 2, secret: 'B'},
];

const result = projectData(data, schema);
console.log(result);
// [
//   {id: 1},
//   {id: 2}
// ]

Применение вложенной схемы для сложной структуры данных.

import {projectData} from '@e22m4u/js-data-projection';

const schema = {
  id: false,
  name: true,
  city: {
    select: true, // правило видимости поля city
    schema: {     // вложенная схема
      id: false,
      name: true,
    },
  },
};

const data = {
  id: 10, // будет скрыто, явное правило
  name: 'Fedor',
  city: {
    id: 20, // будет скрыто, явное правило
    name: 'Moscow',
  },
};

const result = projectData(data, schema);
console.log(result);
// {
//   name: 'Fedor',
//   city: {
//     name: 'Moscow',
//   }
// }

Строгий режим

Исключение полей не указанных в схеме проекции.

import {projectData} from '@e22m4u/js-data-projection';

const schema = {
  name: true,
  password: false,
};

const data = {
  name: 'Fedor',       // будет доступно, явное правило
  password: 'pass123', // будет исключено, явное правило
  extra: 10,           // будет исключено в строгом режиме
};

const result = projectData(data, schema, {
  strict: true, // <= строгий режим
});
console.log(result);
// {
//   name: 'Fedor'
// }

Область проекции

Создание проекции определенной области.

import {projectData} from '@e22m4u/js-data-projection';

const schema = {
  name: true,
  password: {
    scopes: {
      input: true,   // правило для области 'input'
      output: false, // правило для области 'output'
    },
  },
};

const data = {
  name: 'Fedor',       // будет доступно, явное правило
  password: 'pass123', // будет доступно в зависимости от области
};

const inputData = projectData(data, schema, {
  scope: 'input', // <= область видимости
});
console.log(inputData);
// {
//   name: 'Fedor',
//   password: 'pass123'
// }

const outputData = projectData(data, schema, {
  scope: 'output', // <= область видимости
});
console.log(outputData);
// {
//   name: 'Fedor'
// }

Использование сокращенных методов для работы с областями.

import {DataProjector} from '@e22m4u/js-data-projection';

const dps = new DataProjector();

dps.defineSchema({
  name: 'user',
  schema: {
    username: true,
    password: {
      scopes: {
        input: true,   // поле password доступно для "input" области
        output: false, // поле password скрыто для "output" области
      },
    },
  },
});

const data = {
  username: 'john_doe',
  password: 'secret123',
}

// аналог dps.projectData(data, 'user', {scope: 'input'})
const input = dps.projectInput(data, 'user');
console.log(input);
// {
//   username: 'john_doe',
//   password: 'secret123'
// }

// аналог dps.projectData(data, 'user', {scope: 'output'})
const output = dps.projectOutput(data, 'user');
console.log(output);
// {
//   username: 'john_doe'
// }

Фабричные функции

Использование фабрики вместо объекта схемы.

import {projectData} from '@e22m4u/js-data-projection';

// фабрика возвращает объект схемы
const getSchema = () => {
  return {
    id: true,
    hiddenField: false,
  };
};

const data = {
  id: 1,
  hiddenField: 'secret',
};

// передача функции вместо объекта
const result = projectData(data, getSchema);
console.log(result);
// {
//   id: 1
// }

Использование фабрики во вложенной схеме.

import {projectData} from '@e22m4u/js-data-projection';

// фабрика для вложенных данных
const getAddressSchema = () => {
  return {
    city: true,
    zip: false,
  };
};

const userSchema = {
  name: true,
  address: {
    schema: getAddressSchema, // <= использование фабрики
  },
};

const data = {
  name: 'Fedor',
  address: {
    city: 'Moscow',
    zip: 123456,
  },
};

const result = projectData(data, userSchema);
console.log(result);
// {
//   name: 'Fedor',
//   address: {
//     city: 'Moscow'
//   }
// }

Установка аргументов вызова фабричных функций.

import {projectData} from '@e22m4u/js-data-projection';

// объект будет передан в параметры фабрики
const logger = {
  log: (message) => console.log(message),
};

// фабрика использует logger
const getSchema = (logger) => {
  logger.log('Factory was invoked!');
  return {name: true, secret: false};
};

const data = {
  name: 'John',
  secret: 'john123',
};

const result = projectData(data, getSchema, {
  factoryArgs: [logger], // <= передача logger в фабрику
});
// Factory was invoked!
console.log(result);
// {
//   name: 'John',
// }

Доступ к сервис-контейнеру внутри фабрики.

import {ServiceContainer} from '@e22m4u/js-service';
import {DataProjector} from '@e22m4u/js-data-projection';

// сервис-контейнер доступен только
// при использовании DataProjector
const dps = new DataProjector();

// сервис-контейнер передается
// первым аргументом фабрики
const getSchema = (container) => {
  console.log(container instanceof ServiceContainer); // true
  return {name: true, secret: false};
}

const data = {
  name: 'John',
  secret: 'john123',
};

const result = dps.projectData(data, getSchema);
console.log(result);
// {
//   name: 'John',
// }

Именованные схемы

Регистрация и применение именованной схемы.

import {DataProjector} from '@e22m4u/js-data-projection';

const dps = new DataProjector();

// регистрация схемы
dps.defineSchema({
  name: 'user', // <= имя схемы
  schema: {
    id: true,
    username: true,
    email: false,
  },
});

const data = {
  id: 10,
  username: 'admin',
  email: 'admin@example.com',
};

// проекция данных по зарегистрированному имени
const result = dps.projectData(data, 'user');
console.log(result);
// {
//   id: 10,
//   username: 'admin'
// }

Использование вложенных именованных схем.

import {DataProjector} from '@e22m4u/js-data-projection';

const dps = new DataProjector();

// регистрация схемы "address"
dps.defineSchema({
  name: 'address',
  schema: {
    city: true,
    zip: false,
  },
});

// регистрация схемы "user"
dps.defineSchema({
  name: 'user',
  schema: {
    name: true,
    address: {
      select: true,      // видимость поля address
      schema: 'address', // <= имя вложенной схемы
    },
  },
});

const data = {
  name: 'Fedor',
  address: {
    city: 'Moscow',
    zip: 123456,
  },
};

const result = dps.projectData(data, 'user');
console.log(result);
// {
//   name: 'Fedor',
//   address: {
//     city: 'Moscow'
//   }
// }

Регистрация псевдонима именованной схемы.

import {DataProjector} from '@e22m4u/js-data-projection';

const dps = new DataProjector();

// регистрация основной схемы
dps.defineSchema({
  name: 'user',
  schema: {
    id: true,
    name: true,
    email: false,
  },
});

// регистрация псевдонима
dps.defineSchema({
  name: 'author', // имя псевдонима
  schema: 'user', // <= имя основной схемы
});

const data = {
  id: 10,
  name: 'Fedor',
  email: 'fedor@example.com',
};

// проекция данных по имени псевдонима
const result = dps.projectData(data, 'author');
console.log(result);
// {
//   id: 10,
//   name: 'Fedor'
// }

Использование фабрики при регистрации именованной схемы.

import {DataProjector} from '@e22m4u/js-data-projection';

const dps = new DataProjector();

// создание фабрики
const getUserSchema = () => {
  return {
    id: true,
    name: true,
    email: false,
  };
};

// регистрация схемы
dps.defineSchema({
  name: 'user',
  schema: getUserSchema, // <= фабрика вместо схемы
});

const data = {
  id: 10,
  name: 'Fedor',
  email: 'fedor@example.com',
};

const result = dps.projectData(data, 'user');
console.log(result);
// {
//   id: 10,
//   name: 'Fedor'
// }

Реализация пользовательской функции разрешения имен.

import {projectData} from '@e22m4u/js-data-projection';

// функция разрешения имен
const nameResolver = name => {
  if (name === 'user') {
    return {id: true, name: true, password: false};
  }
  throw new Error(`Schema "${name}" is not found!`);
};

const data = {
  id: 1,
  name: 'Fedor',
  password: 'pass123',
};

const result = projectData(
  data,
  'user', // <= вместо схемы передается имя
  {nameResolver}, // <= разрешающая функция
);
console.log(result);
// {
//   id: 1,
//   name: 'Fedor'
// }

Тесты

npm run test

Лицензия

MIT