TypeScript
Пакет для TypeScript — это эталонная реализация TDC. CLI хорош, когда нужен файл; библиотека нужна, чтобы получить данные прямо в коде — как строку или как живые JS-объекты — без запуска внешнего процесса и чтения файла.
import { TDC } from "tdcv2";
Создание TDC
Конструктор принимает либо путь к DSL-файлу (configFile), либо строку с DSL
(configString). Runtime-параметры seed, count, locale и now можно
переопределить из кода — они бьют значения из <env>.
const tdc = new TDC({
configString: `<tdc>
<env count="4" seed="demo" local="ru">
<sequence name="Gender"><gen type="text" value="Мужчина,Женщина"/></sequence>
<sequence name="MaleName" parent="Gender.Мужчина"><gen type="template" value="person.male.firstName"/></sequence>
<sequence name="FemaleName" parent="Gender.Женщина"><gen type="template" value="person.female.firstName"/></sequence>
<before><line><data>Пол,Имя</data></line></before>
</env>
<block><line><data>\${{Gender}},\${{MaleName}}\${{FemaleName}}</data></line></block>
</tdc>`,
});
console.log(tdc.toString());
Имя привязано к полу через parent: две последовательности, каждая под своей веткой, —
иначе имя разыгрывалось бы независимо и мужчине досталось бы женское имя. На каждой
строке заполнена ровно одна из них, поэтому в выводе они просто идут подряд.
Пол,Имя Женщина,Злата Мужчина,Матвей Мужчина,Павел Женщина,Лариса
Переопределение из кода — эти значения бьют <env>:
const tdc = new TDC({
configFile: "./patients.tdc",
seed: "test-seed",
count: 100,
locale: "ru",
});
Для внешних файловых источников задайте папки данных (и базовую директорию для
configString):
const tdc = new TDC({
configFile: "./configs/users.tdc",
dataPaths: ["./data", "./private-data"],
});
При configFile относительные пути src внутри .tdc считаются от папки этого
файла; при configString базовую директорию baseDir задавайте вручную.
Терминальные методы
| Метод | Что возвращает | Для чего |
|---|---|---|
toString() | весь вывод одной строкой | маленькие / средние результаты |
writeFile(path) | пишет вывод в файл (частями) | файл любой величины |
toIterator() | генератор строк (по одной карточке) | большой текст без общей строки |
toStream() | Node.js Readable | pipe в файл / HTTP / архиватор |
toArray() | массив объектов-строк | маленькие объектные фикстуры |
iterate() | генератор объектов-строк | объектный вывод без массива |
getAt(index) | одну объектную строку по индексу | точечный доступ |
preflight(opts?) | диагностику по памяти или undefined | проверка до большого запуска |
seedInfo() | { seed, generated } | узнать / залогировать сид |
toString/writeFile/toIterator/toStream — текстовый вывод через диск,
память O(числа полей). Замеры смотрите на странице
Большие объёмы.
Объектный вывод
В тестах часто удобнее работать с живыми объектами, чем парсить CSV/JSON — можно
проверять row.Gender напрямую. Это дают toArray(), iterate() и getAt(index).
Объектный вывод игнорирует <block> и текстовые обёртки — берёт только
материализованные <sequence>:
- простая sequence становится скалярным свойством;
- составная sequence становится вложенным объектом;
- sequence с фильтром по родителю даёт
undefinedв строках, где она не применима.
const tdc = new TDC({
configString: `<tdc>
<env count="4" seed="demo" local="ru">
<sequence name="Gender"><gen type="text" value="Мужчина,Женщина"/></sequence>
<sequence name="Person">
<gen name="Code" type="regex" value="[0-9]{4}"/>
</sequence>
<sequence name="MaleName" parent="Gender.Мужчина"><gen type="template" value="person.male.firstName"/></sequence>
<sequence name="FemaleName" parent="Gender.Женщина"><gen type="template" value="person.female.firstName"/></sequence>
</env>
<block><line><data>игнорируется</data></line></block>
</tdc>`,
});
console.log(tdc.getAt(0)); // женская строка
console.log(tdc.getAt(1)); // мужская строка
{
Gender: 'Женщина',
Person: { Code: '5218' },
MaleName: undefined,
FemaleName: 'Милана'
}
{
Gender: 'Мужчина',
Person: { Code: '7698' },
MaleName: 'Иван',
FemaleName: undefined
}Person — вложенный объект. MaleName и FemaleName присутствуют обе, но на каждой
строке заполнена ровно одна: вторая равна undefined, потому что её parent на этой
строке не совпал. Так в объектном выводе и выглядит фильтр по родителю.
Объектные методы читают из того движка, в который конфиг направил роутер, — из того
же, что и toString(). Значения совпадают, а getAt(index) стоит одной строки, а не
всего прогона до неё: спросить девятимиллионную строку у конфига на десять миллионов —
работа на одну строку.
Одно значение без конфига
Пакет экспортирует ещё и tdc — он вытягивает одно значение из тех же пакетов данных,
которые читает конфиг: ни файла, ни <env>, один вызов.
import { tdc } from "tdcv2";
tdc.person.lastName(); // Jones
tdc.country.usa.docs.ssn(); // 699209702, с настоящими контрольными цифрами
tdc.person.lastName.many(5); // сразу пять
tdc.seed("demo").locale("ru").person.lastName(); // закреплено и по-русски
Каждый встроенный адрес — настоящее свойство типа, поэтому опечатка становится ошибкой компиляции, а автодополнение работает без всяких плагинов. Вся поверхность — на странице По одному значению.
Смотрите также
- CLI — тот же движок из командной строки.
- Большие объёмы — потоковые методы и память.