goods-exporter
Version:
A versatile JavaScript library for exporting goods data to various formats such as YML, CSV, and Excel. Simplify data export tasks with ease. Supports streams.
745 lines (720 loc) • 30.9 kB
TypeScript
import { Writable } from 'stream';
interface Product {
/**
* **ID товара**
*
* Любая последовательность длиной до 80 знаков. В нее могут входить английские и русские (кроме ё) буквы, цифры и символы . , / \ ( ) [ ] - = _
*
* Пример: belaya-kofta-12345
*/
productId: number;
/**
* **Родительскй SKU**
*
* Любая последовательность длиной до 80 знаков. В нее могут входить английские и русские (кроме ё) буквы, цифры и символы . , / \ ( ) [ ] - = _
*
* Пример: belaya-kofta-12345
*/
parentId?: number;
/**
* **SKU**
*
* Любая последовательность длиной до 80 знаков. В нее могут входить английские и русские (кроме ё) буквы, цифры и символы . , / \ ( ) [ ] - = _
*
* Пример: belaya-kofta-12345
*/
variantId: number;
/**
* **Название**
*
* Составляйте название по схеме: тип + бренд или производитель + модель + особенности, если есть (например, цвет, размер или вес) и количество в упаковке.
*
* Не включайте в название условия продажи (например, «скидка», «бесплатная доставка» и т. д.), эмоциональные характеристики («хит», «супер» и т. д.). Не пишите слова большими буквами — кроме устоявшихся названий брендов и моделей.
*
* Оптимальная длина — 50–60 символов, максимальная — 150.
*
* Составлять хорошие названия помогут [рекомендации](https://yandex.ru/support/marketplace/assortment/fields/title.html).
*
* Пример: Ударная дрель Makita HP1630, 710 Вт
*/
title: string;
/**
* **Описание**
*
* Подробное описание товара: например, его преимущества и особенности.
*
* Не давайте в описании инструкций по установке и сборке. Не используйте слова «скидка», «распродажа», «дешевый», «подарок» (кроме подарочных категорий), «бесплатно», «акция», «специальная цена», «новинка», «new», «аналог», «заказ», «хит». Не указывайте никакой контактной информации и не давайте ссылок.
*
* Можно использовать теги:
*
** <h>, <h1>, <h2> и так далее — для заголовков;
** <br> и <p> — для переноса строки;
** <ol> — для нумерованного списка;
** <ul> — для маркированного списка;
** <li> — для создания элементов списка (должен находиться внутри <ol> или <ul>);
** <div> — поддерживается, но не влияет на отображение текста.
* Оптимальная длина — 400–600 символов, максимальная — 6000.
*
* Составить хорошее описание помогут рекомендации.
*
* Пример: В комплекте с детским микроскопом есть все, что нужно вашему ребенку для изучения микромира
*/
description: string;
/**
* **Бренд**
*
* Название бренда или производителя.
*
* Записывайте название так, как его пишет сам бренд.
*
* Пример: LEVENHUK
*/
vendor?: string;
/**
* **Артикул производителя**
*
* Код товара, который ему присвоил производитель.
*
* Если артикулов несколько, укажите их через запятую.
*
* Пример: VNDR-0005A, VNDR-0005B
*/
vendorCode?: string;
/**
* **Дата выхода**
*
* Пример: 01.01.2000
*/
saleDate?: string;
/**
* **Вендор в магазине**
*
* Содержит номер вендора, а не ее название.
*/
vendorId?: number;
/**
* **Категория в магазине**
*
* Категория, к которой вы относите товар. Она помогает точнее определить для товара категорию на Маркете.
*
* Указывайте конкретные категории — например, набор ножей лучше отнести к категории Столовые приборы, а не просто Посуда.
*
* Выбирайте категории, которые описывают товар, а не абстрактный признак — например, лучше указать Духи, а не Подарки.
*
* Содержит номер категории, а не ее название.
*/
categoryId: number;
/**
* **Страна производства**
*
* Страна, где был произведен товар.
*
* Записывайте названия стран так, как они записаны в [списке](https://yastatic.net/s3/doc-binary/src/support/market/ru/countries.xlsx).
*
* Пример: Россия
*/
countryOfOrigin?: string;
/**
* **Изображение**
*
* До двадцати изображений, которые показываются на карточке товара.
*
* Принимаются jpg- или png-изображения товара, соответствующие [требованиям](https://yandex.ru/support/marketplace/assortment/fields/images.html).
*
* В кабинете изображения добавляются в виде файлов. В Excel-файле — в виде ссылок через запятую. Первое фото становится основным.
*
* Чтобы изменить изображение, выложите новое по новой ссылке, иначе картинка не обновится.
*/
images?: string[];
/**
* **Видео**
*
* Видеоиллюстрации для карточки товара.
*
* Видео должно соответствовать [требованиям](https://yandex.ru/support/marketplace/assortment/fields/video.html).
*
* Можно добавить не больше 6 видео.
*
* В кабинете можно загрузить видеофайлы. В Excel-шаблоне укажите ссылки на файлы.
*/
videos?: string[];
/**
* **Базовая цена**
*
* Цена указывается в рублях. Число должно быть целым.
*
* Пример:
*
* 240
*/
price: number;
/**
* **Цена до скидки**
*
* Цена указывается в рублях. Число должно быть целым.
*
* Вы можете указать цену со скидкой от 5 до 75 %.
*
* Пример:
*
* 250
*/
oldPrice?: number;
/**
* **Себестоимость**
*
* Цена указывается в рублях. Число должно быть целым.
*
* Пример:
*
* 200
*/
purchasePrice?: number;
/**
* **Дополнительные расходы**
*
* Дополнительные расходы на товар. Например, на доставку или упаковку.
*
* После заполнения этого поля в калькуляторе и на странице управления ценами рассчитается потенциальная маржинальность товара.
*
* Цена указывается в рублях. Число должно быть целым.
*
* Пример:
*
* 75
*/
additionalExpenses?: number;
/**
* **Порог для скидок с Маркетом**
*
* Цена указывается в рублях. Число должно быть целым.
*
* Пример:
*
* 300
*/
cofinancePrice?: number;
/**
* **Валюта (DBS)**
*
* Валюта, в которой указана цена товара. Покупателям Маркет показывает цену в рублях, пересчитывая ее по курсу Центробанка.
*
* Поле используется, если для кабинета еще не включена работа с базовыми ценами.
*
* Поддерживаются российские и белорусские рубли, евро, доллары, украинские гривны и казахстанские тенге.
*
* В кабинете валюту можно просто выбрать из списка. В Excel-файле указывается код валюты: RUR, BYN, EUR, USD, UAN, KZT.
*/
currency: Currency;
/**
* **Ссылка на страницу товара**
*
* Адрес страницы на вашем сайте с фотографиями и описанием товара.
*
* Максимальная длина URL — 512 символов. Записывайте его согласно стандарту RFC 3986.
*
* Пример: http://best.seller.ru/product_page.asp?pid=12346
*/
url?: string;
/**
* **Убрать из продажи**
*
* Поле позволяет приостановить продажу товара.
*
* Укажите значение true, если нужно приостановить продажу.
*/
disabled?: boolean;
/**
* **Доступное количество товара**
*
* Общее количество товара, доступное для продажи
*
* Укажите 0, если товара нет в наличии.
*
* Пример: 7
*/
count?: number;
/**
* **Товар в наличии (DBS)**
*
* Поле указывает, есть ли товар в наличии.
*/
available?: boolean;
/**
* **Время доставки**
*
* Указывает на время доставки в днях, от и до скольких.
*/
timeDelivery?: {
min?: number;
max?: number;
};
/**
* **Минимальное количество товара**
*
* Если значение задано, покупатель не сможет заказать меньше единиц товара. Ограничение не работает, когда товара на складе осталось меньше этого количества — тогда покупатель сможет сделать заказ на остаток.
*
* Целое число.
*/
minQuantity?: number;
/**
* **Квант продажи**
*
* Если значение задано, покупатель сможет добавить к заказу только кратное количество товара. Ограничение не работает, когда на складе осталось меньше этого количества — тогда покупатель сможет сделать заказ на остаток.
*
* Целое число.
*/
stepQuantity?: number;
/**
* **Штрихкод**
*
* Указывайте в виде последовательности символов. Подойдут коды EAN-13, EAN-8, UPC-A, UPC-E или Code 128.
*
* Для книг указывайте ISBN.
*
* Для товаров [определенных категорий и торговых марок](https://yastatic.net/s3/doc-binary/src/support/market/ru/yandex-market-list-for-gtin.xlsx) штрихкод должен быть действительным кодом GTIN. Обратите внимание: внутренние штрихкоды, начинающиеся на 2 или 02, и коды формата Code 128 не являются GTIN.
*
* Если штрихкодов несколько, напишите все через запятую.
*
* Пример: 46012300000000
*/
barcode?: string;
/**
* **Код ТН ВЭД**
*
* Для некоторых категорий товаров код ТН ВЭД обязателен. Если это касается ваших товаров, вы получите уведомление в каталоге.
*
* 10 или 14 цифр без пробелов.
*
* Пример: 8517610008
*/
codesTN?: string[];
/**
* **С какого возраста пользоваться**
*
* Если товар не предназначен для детей младше определенного возраста, укажите это.
*
* Возрастные ограничения можно задавать в годах (с нуля, с 6, 12, 16 или 18) или в месяцах (любое число от 0 до 12).
*/
age?: {
unit: "year" | "month";
value: number;
};
/**
* **Вес с упаковкой**
*
* Вес товара с упаковкой.
*
* Единица измерения — килограммы. Можно дроби: разделитель — точка или запятая, не больше трех цифр после него.
*
* Пример: 3.1
*/
weight?: number;
/**
* **Габариты с упаковкой**
*
* Длина, ширина, высота в упаковке.
*
* Единица измерения — сантиметры. Можно дроби: разделитель — точка или запятая, не больше трех цифр после него.
*
* Пример: 20.1/20.551/22.5
*/
dimensions?: string;
/**
* **Товар занимает больше одного места**
*
* Если товар занимает одно место (представляет собой одну коробку, упаковку и так далее), оставьте поле пустым. Если товар занимает несколько мест — укажите их количество. Например, кондиционер занимает два места — внешний и внутренний блоки в двух коробках.
*
* Укажите количество мест.
*
* Пример: 2
*/
boxCount?: number;
/**
* **Ставка НДС**
*
* Значение ставки НДС для товара.
*
* Выберите одно из значений:
*
** НДС не облагается — 6 или NO_VAT
*
** 0 % — 5 или VAT_0
*
** 10 % — 2 или VAT_10
*
** 20 % — 7 или VAT_20
*
* Если не заполнено, Маркет устанавливает ставку, соответствующую схеме налогообложения.
*
* Пример: VAT_20
*/
vat: Vat;
/**
* **Характеристики, которые есть только у товаров конкретной категории**
*
* Кроме общих свойств, у товара есть характеристики, присущие конкретной категории, к которой он относится. Например, у велосипеда есть размер рамы, а детское пюре бывает овощное, мясное или фруктовое.
*/
params?: IParam[];
/**
* **Свойства товара**
*
* *не YML поле
*/
properties?: IParam[];
/**
* **Теги**
*
* Придумайте любое название — его можно будет изменить после.
*
* Максимальная длина тега — 20 символов.
*
* У одного товара — максимум 10 тегов.
*
* Всего можно создать не больше 50 разных тегов.
*
* Пример: apple, до 500 рублей
*/
tags?: string[];
/**
* **Товар для взрослых**
*
* Параметр включает для товара пометку 18+. Устанавливайте ее только для товаров, которые относятся к удовлетворению сексуальных потребностей.
*/
adult?: boolean;
/**
* **Цифровой товар**
*
* Параметр, устанавливаемый для цифровых товаров, которые просто скачиваются.
*/
downloadable?: boolean;
/**
* **Срок годности**
*
* Период с момента изготовления, по прошествии которого товар становится непригоден.
*
* Указывайте срок, указанный на банке или упаковке. Текущая дата, дата поставки или дата отгрузки значения не имеет.
*
* Срок можно указывать в годах, месяцах, днях, неделях и часах.
*
* Обязательно указывайте срок, если он есть.
*
* Продолжительность указывается согласно ISO 8601, то есть в виде строчки, начинающейся буквой P:
*
** P1Y — 1 год;
** P1Y6M — 1 год и 6 месяцев;
** P15D — 15 дней.
*/
validityPeriod?: string;
/**
* **Комментарий к сроку годности**
*
* Поле предназначено для описаний условий хранения.
*
* Не длиннее 250 знаков и без спецсимволов.
*
* Пример: Хранить в сухом помещении
*/
validityComment?: string;
/**
* **Срок службы**
*
* В течение срока службы товар должен исправно выполнять свою функцию.
*
* Обязательно указывайте срок, если он есть.
*
* Срок можно указывать в годах, месяцах и днях.
* Продолжительность указывается согласно ISO 8601, то есть в виде строчки, начинающейся буквой P:
*
** P1Y — 1 год;
** P1Y2M — 1 год и 2 месяца;
** P15D — 15 дней;
** P2Y10D — 2 года, 10 дней;
** P2Y6M10D — 2 года, 6 месяцев и 10 дней.
*/
serviceLifePeriod?: string;
/**
* **Комментарий к сроку службы**
*
* Поле предназначено для описаний условий использования.
*
* Не длиннее 250 знаков и без спецсимволов.
*
* Пример: Использовать при температуре не ниже −10 градусов
*/
serviceLifeComment?: string;
/**
* **Гарантийный срок**
*
* В течение какого времени можно бесплатно заменить или починить товар.
*
* Срок можно указывать в годах, месяцах или днях.
*
* Продолжительность указывается согласно ISO 8601, то есть в виде строчки, начинающейся буквой P:
*
** P1Y — 1 год;
** P1Y2M — 1 год и 2 месяца;
** P15D — 15 дней;
** P2Y10D — 2 года, 10 дней;
** P2Y6M10D — 2 года, 6 месяцев и 10 дней.
*/
warrantyPeriod?: string;
/**
* **Комментарий к гарантийному сроку**
*
* Поле предназначено для описания особенностей гарантийных условий.
*
* Указывайте только то, что относится к гарантии изготовителя.
*
* Не длиннее 250 знаков и без спецсимволов.
*
* Пример: Гарантия на аккумулятор — 6 месяцев
*/
warrantyComment?: string;
/**
* **Официальная гарантия производителя**
*/
manufacturerWarranty?: boolean;
/**
* **Номер документа**
*
* Номер документа на товар: сертификата, декларации соответствия и т. п.
*
* Прежде чем указывать номер документа, загрузите скан документа через кабинет.
*
* Укажите номер документа.
*
* Пример: 6241421
*/
certificate?: string;
/**
* **Ключевые слова**
*
* Пример: Кроссовки, высокая подошва
*/
keywords?: string[];
/**
* **Размерная сетка**
*/
sizes?: ISize[];
/**
* **Связанные товары**
*
* Указываются id товаров
*
* Пример: 1234
*/
relatedProducts?: number[];
/**
* **Название коллекции, ряда или серии товара**
*
* Пример: Jordan 4
*/
seriesName?: string;
/**
* **Пол или название группы потребителей**
*
* Пример: Дети, Женское, Унисекс
*/
gender?: string;
/**
* **Кол-во клиентов, которым понравился товар**
*
* Пример: 982134
*/
favoriteCount?: number;
}
declare enum Vat {
NO_VAT = "NO_VAT",
VAT_0 = "VAT_0",
VAT_10 = "VAT_10",
VAT_20 = "VAT_20"
}
declare enum Currency {
RUB = "RUB",
BYN = "BYN",
EUR = "EUR",
USD = "USD",
CNY = "CNY",
KZT = "KZT"
}
interface IParam {
/**
* **Название характеристики**
*/
key: string;
/**
* **Значение**
*/
value: string;
}
interface ISize {
/**
* **Название единицы измерения**
*/
name: string;
/**
* **Разделитель**
*/
delimiter: string;
/**
* **Значения размерного ряда**
*
* Размеры указываются через разделитель
*/
value: string;
}
interface Category {
/**
* **ID категории**
*
* Целое число
*/
id: number;
/**
* **ID родительской категории**
*
* Целое число
*/
parentId?: number;
/**
* **Название категории**
*/
name: string;
}
interface Brand {
/**
* **ID бренда**
*
* Целое число
*/
id: number;
/**
* **Название бренда**
*/
name: string;
/**
* **Ссылка на изображение логотипа**
*/
logoUrl?: string;
/**
* **Ссылка на изображение баннера**
*/
coverURL?: string;
}
declare abstract class FormatterAbstract {
abstract formatterName: string;
abstract fileExtension: Extension;
abstract format(writableStream: Writable, products: Product[], categories?: Category[], brands?: Brand[], option?: FormatterOptions): Promise<void>;
}
interface FormatterOptions {
shopName?: string;
companyName?: string;
splitParams?: boolean;
}
declare enum Extension {
CSV = "csv",
YML = "yml",
XML = "xml",
XLSX = "xlsx",
JSON = "json"
}
declare class CSVFormatter implements FormatterAbstract {
formatterName: string;
fileExtension: Extension;
format(writableStream: Writable, products: Product[], categories?: Category[], _?: Brand[], __?: FormatterOptions): Promise<void>;
}
declare class ExcelFormatter implements FormatterAbstract {
formatterName: string;
fileExtension: Extension;
format(writableStream: Writable, products: Product[], categories?: Category[], _?: Brand[], __?: FormatterOptions): Promise<void>;
}
declare class InsalesFormatter implements FormatterAbstract {
formatterName: string;
fileExtension: Extension;
format(writableStream: Writable, products: Product[], categories?: Category[], brands?: Brand[], __?: FormatterOptions): Promise<void>;
}
declare class JSONFormatter implements FormatterAbstract {
formatterName: string;
fileExtension: Extension;
format(writableStream: Writable, products: Product[], categories?: Category[], brands?: Brand[], _?: FormatterOptions): Promise<void>;
}
declare class PriceFormatter implements FormatterAbstract {
formatterName: string;
fileExtension: Extension;
format(writableStream: Writable, products: Product[], _categories?: Category[], _brands?: Brand[], _?: FormatterOptions): Promise<void>;
}
declare class SimpleJSONFormatter implements FormatterAbstract {
formatterName: string;
fileExtension: Extension;
format(writableStream: Writable, products: Product[], categories?: Category[], brands?: Brand[], _?: FormatterOptions): Promise<void>;
}
declare class TgShopFormatter implements FormatterAbstract {
formatterName: string;
fileExtension: Extension;
format(writableStream: Writable, products: Product[], categories?: Category[], _?: Brand[], __?: FormatterOptions): Promise<void>;
}
declare class TildaFormatter implements FormatterAbstract {
formatterName: string;
fileExtension: Extension;
format(writableStream: Writable, products: Product[], categories?: Category[], _?: Brand[], __?: FormatterOptions): Promise<void>;
}
declare class WooCommerceFormatter implements FormatterAbstract {
formatterName: string;
fileExtension: Extension;
private readonly DEFAULT_COLUMNS;
private readonly CUSTOM_ATTRIBUTES;
private formatKeyAttribute;
private formatValueAttribute;
private formatProducts;
private createAttribute;
private extractAttributes;
private removeVisibleFromAttributes;
format(writableStream: Writable, products: Product[], categories?: Category[], _?: Brand[], __?: FormatterOptions): Promise<void>;
}
declare class YMLFormatter implements FormatterAbstract {
formatterName: string;
fileExtension: Extension;
format(writableStream: Writable, products: Product[], categories?: Category[], brands?: Brand[], options?: FormatterOptions): Promise<void>;
private getBrands;
private getCategories;
private getOffer;
}
declare class XMLFormatter extends YMLFormatter {
formatterName: string;
fileExtension: Extension;
}
declare const Formatters: {
TildaFormatter: typeof TildaFormatter;
CSVFormatter: typeof CSVFormatter;
InsalesFormatter: typeof InsalesFormatter;
YMLFormatter: typeof YMLFormatter;
TgShopFormatter: typeof TgShopFormatter;
ExcelFormatter: typeof ExcelFormatter;
JSONFormatter: typeof JSONFormatter;
SimpleJSONFormatter: typeof SimpleJSONFormatter;
XMLFormatter: typeof XMLFormatter;
WooCommerceFormatter: typeof WooCommerceFormatter;
PriceFormatter: typeof PriceFormatter;
};
type Transformer<Context> = (products: Product[], context: Context) => Product[] | Promise<Product[]>;
type Exporter = () => Writable;
declare class GoodsExporter<Context extends object | undefined> {
readonly context: Context;
private _context;
constructor(context: Context);
setContext(context: Context): void;
private formatter;
private exporter;
private transformers;
setTransformers(transformers: Array<Transformer<Context>>): void;
setFormatter(formatter: FormatterAbstract): void;
setExporter(exporter: Exporter): void;
export(products: Product[], categories?: Category[], brands?: Brand[], option?: FormatterOptions): Promise<void>;
}
declare const buildCategoryPaths: (categories: Category[]) => Map<number, Category[]>;
declare const writeWithDrain: (stream: Writable) => (chunk: any) => Promise<void>;
declare const delay: (ms: number) => Promise<unknown>;
declare function getRFC3339Date(date: Date): string;
declare const urlQueryEncode: (inputUrl: string) => string;
export { type Brand, type Category, Currency, type Exporter, Extension, FormatterAbstract, type FormatterOptions, Formatters, GoodsExporter, type IParam, type ISize, type Product, type Transformer, Vat, buildCategoryPaths, delay, getRFC3339Date, urlQueryEncode, writeWithDrain };