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

e22m4u abdfe0e3a2 docs: updates README.md 2 дней назад
.husky 22b5a33b5f chore: initial commit 2 недель назад
dist d87af6d4b7 feat: allows symbols as schema name 2 дней назад
src d87af6d4b7 feat: allows symbols as schema name 2 дней назад
.c8rc 22b5a33b5f chore: initial commit 2 недель назад
.commitlintrc 22b5a33b5f chore: initial commit 2 недель назад
.editorconfig 22b5a33b5f chore: initial commit 2 недель назад
.gitignore 22b5a33b5f chore: initial commit 2 недель назад
.mocharc.json 6f15ecb1a5 refactor: improve linting 1 неделя назад
.prettierrc 22b5a33b5f chore: initial commit 2 недель назад
LICENSE 22b5a33b5f chore: initial commit 2 недель назад
README.md abdfe0e3a2 docs: updates README.md 2 дней назад
build-cjs.js 22b5a33b5f chore: initial commit 2 недель назад
eslint.config.js 6f15ecb1a5 refactor: improve linting 1 неделя назад
package.json d87af6d4b7 feat: allows symbols as schema name 2 дней назад
tsconfig.json 6f15ecb1a5 refactor: improve linting 1 неделя назад

README.md

@e22m4u/js-data-projection

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

Модуль использует декларативные схемы для определения правил видимости полей данных. Поддерживается вложенность, функции-фабрики, именованные схемы, области проекции и строгий режим.

Содержание

Установка

npm install @e22m4u/js-data-projection

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

Модуль экспортирует функцию создания проекции projectData.

Функция projectData

Функция создает проекцию данных на основе переданного объекта схемы. Принимает исходные данные и дополнительные опции для управления режимом строгости и областью видимости.

Сигнатура:

projectData(schemaOrFactory, data, [options])

schemaOrFactory

Тип: object | Function | string | symbol

Определяет правила проекции. Принимает:

  • object: объект схемы проекции;
  • Function: фабрика, возвращающая схему (или ключ схемы);
  • string | symbol: ключ для поиска схемы через функцию resolver;

data

Тип: object | object[] | any

Исходные данные для проекции. Если передан массив, проекция применяется к каждому элементу. Примитивы возвращаются без изменений.

options (необязательно)

Тип: object

Объект с дополнительными настройками:

  • strict?: boolean: включает строгий режим;
  • scope?: string: имя активной области проекции;
  • resolver?: Function: функция для получения схемы по ключу;

Возвращаемое значение:

Возвращает спроецированные данные. Структура результата (объект или массив) соответствует проекции аргумента data согласно схеме.

Создание проекции

Схема проекции описывает настройки видимости для каждого поля. Логические значения определяют видимость поля. Поля, отсутствующие в схеме, остаются в результате по умолчанию.

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

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

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

const result = projectData(schema, data);
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(schema, data);
console.log(result);
// [
//   {id: 1},
//   {id: 2}
// ]

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

Строгий режим исключает из результата все поля, не описанные в схеме явно. Поведение регулируется опцией strict. Данный режим позволяет гарантировать отсутствие лишних данных в результате.

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

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

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

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

Вложенные схемы

Вложенные объекты обрабатываются с помощью свойства schema в настройках поля. Данное свойство позволяет определять правила видимости для вложенных структур данных.

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(schema, data);
console.log(result);
// {
//   name: 'Fedor',
//   city: {
//     name: 'Moscow',
//   }
// }

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

Правила видимости полей могут зависеть от области проекции. Свойство scopes определяет специфичные правила для разных контекстов, передаваемых через опцию scope.

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(schema, data, {
  scope: 'input', // <= область проекции
});
console.log(inputData);
// {
//   name: 'Fedor',
//   password: 'pass123'
// }

const outputData = projectData(schema, data, {
  scope: 'output', // <= область проекции
});
console.log(outputData);
// {
//   name: 'Fedor'
// }

Модуль экспортирует объект констант с именами часто используемых областей проекции.

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

console.log(ProjectionScope);
// {
//   INPUT: 'input',
//   OUTPUT: 'output'
// }

projectData(schema, data, {
  scope: ProjectionScope.INPUT,
});

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

Вместо статической схемы можно передать фабричную функцию, которая вернет объект схемы. Это полезно, если схему необходимо генерировать динамически или переиспользовать логику создания схем.

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

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

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

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

Фабрики также поддерживаются во вложенных структурах. Свойство schema может принимать функцию, возвращающую схему для вложенного объекта.

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

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

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

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

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

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

Для использования именованных схем требуется определить функцию для разрешения имен. Функция передается в опцию resolver, принимает имя схемы в виде строки и возвращает объект соответствующей схемы.

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

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

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

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

Именованные схемы могут быть использованы во вложенной структуре. Свойство schema принимает имя схемы, которое будет передано в разрешающую функцию во время создания проекции.

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

const userSchema = {
  name: true,
  address: {
    schema: 'address', // <= имя вложенной схемы
  }
}

// функция для разрешения имен
const resolver = key => {
  if (key === 'address') {
    return {city: true, zip: false};
  }
  throw new Error(`Schema "${key}" is not found!`);
};

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

const result = projectData(
  userSchema,
  data,
  {resolver}, // <= разрешающая функция
);
console.log(result);
// {
//   name: 'Fedor',
//   address: {
//     city: 'Moscow'
//   }
// }

Тесты

npm run test

Лицензия

MIT