npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@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 API
  • headers - заголовки запросов
  • 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-publish

Git хуки

Проект использует 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 типы