@set2333/upload-script-helpers
v1.0.4
Published
Helper library for upload scripts
Readme
Upload Scripts Helpers
Набор утилит для загрузки и обработки данных для дальнейшей обработки в Pentaho.
Установка
npm install @set2333/upload-script-helpersТребования
- Node.js >= 12.0.0
Быстрый старт
import {
EmailManager,
FileManager,
Logger,
ParserXLS,
Validator,
ApiManager,
JsonMapper
} from '@set2333/upload-script-helpers'
// Создание логгера
const logger = new Logger({
displayTypes: ['console', { type: 'file', options: { logFile: 'app.log' } }]
})
// Управление файлами
const fileManager = new FileManager({
workDirectory: './work-dir',
logger
})
// Работа с API
const apiManager = new ApiManager({
baseUrl: 'https://api.example.com',
headers: { 'Authorization': 'Bearer token' }
})
// Получение данных
const apiData = await apiManager.fetch({ page: 1, limit: 100 })
// Сохранение данных
fileManager.saveJSONFile(apiData, 'api-response.json')Модули
Logger
Система логирования с поддержкой консоли и файлов.
Опции:
messageTypes- типы сообщений для логирования:['log', 'warn', 'error']displayTypes- способы вывода:['console']или[{ type: 'file', options: { logFile: 'app.log', logDir: './logs' } }]
Методы:
log(message: string, ...args: unknown[])- обычное сообщениеwarn(message: string, ...args: unknown[])- предупреждениеerror(message: string, ...args: unknown[])- ошибкаstart(message: string)- начало процесса с временной меткойend(message: string)- конец процесса с временной меткойduration(processName: string)- длительность процесса
Пример:
const logger = new Logger({
displayTypes: [
'console',
{ type: 'file', options: { logFile: 'app.log', logDir: './logs' } }
]
})
logger.start('Обработка данных')
logger.log('Загружаем файл...')
logger.warn('Файл большой, это может занять время')
logger.duration('Обработка данных')
logger.end('Обработка завершена')FileManager
Управление файлами и рабочими директориями.
Опции:
workDirectory(string) - путь к рабочей директорииlogger(ILogger | null) - логгер для вывода сообщений
Методы:
saveJSONFile(data: unknown, fileName: string)- сохранение JSON файлаsaveAttachment(attachmentData: Buffer, fileName: string)- сохранение вложения
Пример:
const fileManager = new FileManager({
workDirectory: './work-dir',
logger
})
// Сохранение JSON данных
const userData = { users: [{ name: 'John', age: 30 }] }
fileManager.saveJSONFile(userData, 'users.json')
// Сохранение вложения из email
const attachmentBuffer = Buffer.from('file content')
fileManager.saveAttachment(attachmentBuffer, 'document.xlsx')EmailManager
Работа с email через IMAP и SMTP.
Опции:
credentials- данные для подключения к почтовому серверуsearchRules- правила поиска писемlogger- логгер для вывода сообщений
Методы:
connect()- подключение к серверуdisconnect()- отключение от сервераgetEmails()- получение писем с вложениямиsendEmail(options)- отправка письма
Пример:
const emailManager = new EmailManager({
credentials: {
host: 'imap.gmail.com',
port: 993,
user: '[email protected]',
pass: 'your-password',
smtpHost: 'smtp.gmail.com',
smtpPort: 587,
smtpUser: '[email protected]',
smtpPass: 'your-password'
},
searchRules: {
since: '2024-01-01',
before: '2024-12-31',
attachmentMask: /\.xlsx$/
},
logger
})
await emailManager.connect()
const emails = await emailManager.getEmails()
for (const email of emails) {
fileManager.saveAttachment(email.buffer, email.attachment)
}
await emailManager.sendEmail({
to: '[email protected]',
subject: 'Обработка завершена',
text: 'Данные успешно обработаны'
})
await emailManager.disconnect()ParserXLS
Парсинг Excel файлов (.xlsx).
Опции:
data- Buffer с данными Excel файлаfileName- имя файлаusedSheet- название листа для парсингаlogger- логгер для вывода сообщений
Методы:
getColumnNames()- получение названий колонокparse(options)- парсинг данных в объекты
Пример:
const parser = new ParserXLS({
data: excelBuffer,
fileName: 'data.xlsx',
usedSheet: 'Sheet1',
logger
})
// Получение названий колонок
const columns = parser.getColumnNames()
console.log('Колонки:', columns)
// Парсинг данных
const parsedData = await parser.parse({
fieldNames: ['name', 'age', 'email', null], // null игнорирует колонку
initDataRow: (fileName) => ({
source: fileName,
processed: false
})
})
console.log('Данные:', parsedData)Validator
Валидация Excel файлов перед обработкой.
Опции:
validationRules- массив правил валидацииusedSheet- название листа для валидацииlogger- логгер для вывода сообщений
Типы правил:
sheetExists- проверка существования листаsheetHasData- проверка наличия данныхcolumnHasName- проверка названия колонкиcolumnHasType- проверка типа данных в колонке
Пример:
const validator = new Validator({
validationRules: [
{ type: 'sheetExists' },
{ type: 'sheetHasData' },
{ type: 'columnHasName', options: [0, 'Name'] },
{ type: 'columnHasType', options: [1, 'number'] }
],
usedSheet: 'Sheet1',
logger
})
const errors = await validator.validate(excelBuffer)
if (errors) {
console.error('Ошибки валидации:', errors)
} else {
console.log('Файл прошел валидацию')
}ApiManager
Работа с HTTP API.
Опции:
baseUrl- базовый URL APIheaders- заголовки запросовmethod- HTTP метод (по умолчанию GET)logger- логгер для вывода сообщений
Методы:
fetch(params?)- выполнение HTTP запроса
Пример:
const apiManager = new ApiManager({
baseUrl: 'https://api.example.com',
headers: {
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json'
},
method: 'GET',
logger
})
// GET запрос с параметрами
const data = await apiManager.fetch({
page: 1,
limit: 100,
search: 'test'
})
// POST запрос (изменяем метод)
apiManager['method'] = 'POST'
const result = await apiManager.fetch({ name: 'New Item' })JsonMapper
Преобразование JSON данных.
Опции:
nameRules- правила переименования полейvalueRules- правила преобразования значенийexcludeRules- поля для исключенияdataExpansion- функция для расширения данных
Методы:
map(data)- преобразование данных
Пример:
const jsonMapper = new JsonMapper({
nameRules: {
'user_name': 'name',
'user_age': 'age'
},
valueRules: {
'age': (value) => Number(value),
'email': (value) => String(value).toLowerCase()
},
excludeRules: ['password', 'secret'],
dataExpansion: (data) => ({
...data,
processedAt: new Date().toISOString()
})
})
const originalData = {
user_name: 'John',
user_age: '30',
email: '[email protected]',
password: 'secret123'
}
const mappedData = jsonMapper.map(originalData)
console.log(mappedData)
// { name: 'John', age: 30, email: '[email protected]', processedAt: '2024-01-01T12:00:00.000Z' }Полный пример использования
Пример скрипта, который получает данные из email, валидирует Excel файлы, парсит их и сохраняет результат:
import {
EmailManager,
FileManager,
Logger,
ParserXLS,
Validator,
JsonMapper
} from '@set2333/upload-script-helpers'
async function processEmailAttachments() {
const logger = new Logger({
displayTypes: ['console', { type: 'file', options: { logFile: 'process.log' } }]
})
const fileManager = new FileManager({
workDirectory: './processed-data',
logger
})
const emailManager = new EmailManager({
credentials: {
host: 'imap.gmail.com',
port: 993,
user: process.env.EMAIL_USER!,
pass: process.env.EMAIL_PASS!,
smtpHost: 'smtp.gmail.com',
smtpPort: 587,
smtpUser: process.env.EMAIL_USER!,
smtpPass: process.env.EMAIL_PASS!
},
searchRules: {
since: '2024-01-01',
before: '2024-12-31',
attachmentMask: /\.xlsx$/
},
logger
})
const validator = new Validator({
validationRules: [
{ type: 'sheetExists' },
{ type: 'sheetHasData' },
{ type: 'columnHasName', options: [0, 'Name'] },
{ type: 'columnHasType', options: [1, 'number'] }
],
usedSheet: 'Data',
logger
})
const jsonMapper = new JsonMapper({
nameRules: {
'Name': 'name',
'Age': 'age',
'Email': 'email'
},
valueRules: {
'age': (value) => Number(value),
'email': (value) => String(value).toLowerCase()
},
dataExpansion: (data) => ({
...data,
processedAt: new Date().toISOString(),
source: 'email-attachment'
})
})
try {
logger.start('Обработка email вложений')
await emailManager.connect()
const emails = await emailManager.getEmails()
logger.log(`Найдено писем с вложениями: ${emails.length}`)
for (const email of emails) {
logger.log(`Обрабатываем файл: ${email.attachment}`)
// Валидация файла
const validationErrors = await validator.validate(email.buffer)
if (validationErrors) {
logger.error(`Файл ${email.attachment} не прошел валидацию:`, validationErrors)
continue
}
// Парсинг Excel файла
const parser = new ParserXLS({
data: email.buffer,
fileName: email.attachment,
usedSheet: 'Data',
logger
})
const parsedData = await parser.parse({
fieldNames: ['name', 'age', 'email']
})
// Преобразование данных
const mappedData = parsedData.map(row => jsonMapper.map(row))
// Сохранение результата
const resultFileName = `processed_${email.attachment.replace('.xlsx', '.json')}`
fileManager.saveJSONFile(mappedData, resultFileName)
logger.log(`Файл ${email.attachment} успешно обработан`)
}
await emailManager.sendEmail({
to: '[email protected]',
subject: 'Обработка завершена',
text: `Обработано файлов: ${emails.length}`
})
await emailManager.disconnect()
logger.end('Обработка email вложений')
} catch (error) {
logger.error('Ошибка при обработке:', error)
throw error
}
}
// Запуск скрипта
processEmailAttachments().catch(console.error)Готовый к использованию пакет
Пакет поставляется уже скомпилированным и готовым к использованию:
dist/index.js- CommonJS версия (минифицированная)dist/index.mjs- ES модули версия (минифицированная)dist/index.d.ts- TypeScript типы
Разработка
# Установка зависимостей
npm install
# Сборка
npm run build
# Разработка с отслеживанием изменений
npm run dev
# Проверка типов
npm run typecheck
# Запуск тестов
npm test
# Запуск тестов один раз
npm run test:run
# Проверка линтера
npm run lint
# Автоисправление ошибок линтера
npm run lint:fix
# Запуск pre-commit проверок
npm run pre-commit
# Запуск pre-publish проверок
npm run pre-publishGit хуки
Проект использует Husky для автоматических проверок:
Pre-commit хук
Автоматически запускается перед каждым коммитом:
- Исправляет ошибки ESLint в измененных файлах
- Проверяет типы TypeScript
- Запускает
lint-staged
Pre-publish хук
Автоматически запускается перед публикацией:
- Проверяет код линтером
- Проверяет типы TypeScript
- Запускает все тесты
- Собирает проект
Хуки настроены в .husky/ директории и автоматически устанавливаются при npm install.
Публикация
# Публикация с поднятием patch версии (1.0.0 -> 1.0.1)
npm run publish:patch
# Публикация с поднятием minor версии (1.0.0 -> 1.1.0)
npm run publish:minor
# Публикация с поднятием major версии (1.0.0 -> 2.0.0)
npm run publish:majorСкрипт автоматически:
- Поднимает версию в package.json
- Собирает проект
- Публикует в npm
Примечание: Git команды убраны из скрипта. Версию нужно обновлять в git вручную.
Поддерживаемые форматы
- CommonJS (
require) - ES модули (
import) - TypeScript типы
