Утилитные скрипты
Проект использует набор TypeScript скриптов для автоматизации разработки и деплоя. Все скрипты находятся в папке scripts/.
Паттерны команд
| Паттерн | Назначение | Пример |
|---|---|---|
pnpm start <name> | Запуск сервиса | pnpm start sofa |
pnpm generate:* | Генерация чего-либо | pnpm generate:env -- local |
pnpm setup:* | Настройка/инициализация | pnpm setup:local |
Обзор скриптов
| Скрипт | Назначение | Запуск |
|---|---|---|
start-integration.ts | Локальный запуск интеграции | pnpm start <name> |
generate-env.script.ts | Генерация .env и wrangler.toml из Doppler | pnpm generate:env -- <local|dev|prod> |
generate-integration.ts | Создание новой интеграции из шаблона | pnpm generate:integration <name> |
generate-gateway.ts | Генерация gateway routing и types | pnpm generate:gateway |
generate-package.ts | Создание нового пакета из шаблона | pnpm generate:package <name> |
setup-local.ts | Создание локальных D1/KV баз (SQLite) | pnpm setup:local |
cli.ts | Интерактивный CLI для управления проектом | pnpm cli |
sync-cf-secrets.ts | Синхронизация секретов Doppler → CF | pnpm sync-secrets:dev [integration] |
remove-comments.script.ts | Удаление комментариев из кода | pnpm clean:comments |
remove-return-types.script.ts | Удаление return типов | pnpm clean:return-types |
CLI (cli.ts)
Интерактивный командный интерфейс для управления проектом.
Команды
pnpm cli create <name>
Создает новую интеграцию с указанным именем.
pnpm cli create my-integration
# 📦 Создание интеграции: my-integration
# ✅ Интеграция создана!
#
# Следующие шаги:
# 1. cd integrations/my-integration
# 2. Отредактировать wrangler.toml для D1/KV bindings
# 3. Реализовать handlers в src/handlers/
# 4. pnpm devpnpm cli creds:set <integration> <key> <value>
Установить credential для интеграции. Автоматически шифруется и сохраняется в D1.
pnpm cli creds:set sofa API_KEY "sk-12345"Как это работает:
- Получает
CRYPTO_KEYиCRYPTO_SALTиз Doppler - Шифрует значение
- Сохраняет в D1 таблице
credsс полями:integration_name- название интеграцииkey- имя ключаencrypted_value- зашифрованное значениеcreated_at,updated_at- временные метки
pnpm cli creds:list [integration]
Список credentials (маскированные значения).
# Все credentials
pnpm cli creds:list
# Только для конкретной интеграции
pnpm cli creds:list sofa
# Вывод:
# 🔐 Credentials для sofa:
# [sofa]
# - API_KEY: ***masked***
# - SECRET: ***masked***pnpm cli dev
Запуск всех сервисов в dev режиме.
pnpm cli dev
# 🚀 Запуск локально...Эквивалентно: pnpm dev
pnpm cli test [pattern]
Запуск тестов (Vitest).
# Все тесты
pnpm cli test
# Тесты по паттерну
pnpm cli test handlers
pnpm cli test "sofa.test"pnpm cli logs <integration>
Просмотр логов интеграции из Cloudflare.
pnpm cli logs sofa
# Опции:
--follow, -f # Следовать за логами в реальном времениИспользует wrangler tail для стриминга логов.
pnpm cli validate [integration]
Проверить структуру интеграции.
pnpm cli validate sofa
# Проверяет:
# ✅ package.json
# ✅ wrangler.toml
# ✅ src/index.ts
# ✅ tsconfig.json
# ⚠️ Warnings если нет D1 bindingsГенерация интеграции (generate-integration.ts)
Создает новую интеграцию из шаблона с автоматической подстановкой переменных.
Использование
pnpm generate:integration my-new-integrationЧто создается
integrations/my-new-integration/
├── src/
│ ├── index.ts # Entry point (createIntegration)
│ ├── types.ts # TypeScript типы
│ ├── handlers/
│ │ ├── index.ts # Barrel export
│ │ ├── call-originate.ts
│ │ ├── call-events.ts
│ │ ├── agent-init.ts
│ │ └── agent-postcall.ts
│ ├── migrations/
│ │ └── index.ts # MIGRATIONS array
│ └── utils/
│ └── logger.ts
├── migrations/ # .gitkeep
├── package.json # Из template, подставлены переменные
├── tsconfig.json
├── wrangler.toml # Из template, подставлены переменные
└── README.mdПеременные подстановки
| Переменная | Значение |
|---|---|
{{NAME}} | Имя интеграции (kebab-case) |
{{NAME_UPPER}} | UPPERCASE версия |
{{NAME_TITLE}} | Title Case версия |
{{NAME_PASCAL}} | PascalCase версия |
{{CURRENT_DATE}} | Текущая дата (YYYY-MM-DD) |
Пример: Если создать интеграцию my-integration:
{{NAME}} → my-integration
{{NAME_UPPER}} → MY_INTEGRATION
{{NAME_TITLE}} → My Integration
{{NAME_PASCAL}} → MyIntegration
{{CURRENT_DATE}} → 2025-01-15Документация Symlink
Автоматически создается symlink:
docs/integrations/my-integration.md → ../../integrations/my-integration/README.mdЭто позволяет хранить документацию вместе с кодом интеграции.
Валидация
- ✅ Имя должно быть kebab-case:
[a-z0-9-]+ - ✅ Интеграция не должна существовать
- ✅ Шаблон должен существовать
Post-generation
После создания интеграции скрипт автоматически:
- Создает symlink
docs/integrations/{name}.md→ README - Добавляет запись в
integrations.config.tsс авто-портом - Запускает
pnpm generate:gatewayдля обновления gateway routing
Генерация Gateway (generate-gateway.ts)
Автоматически генерирует routing и types для Gateway на основе integrations.config.ts.
Использование
pnpm generate:gatewayЧто генерируется
workers/gateway/src/generated/integrations.ts— types, service bindings, портыworkers/gateway/wrangler.toml— service binding для каждой интеграции
Вызывается автоматически при создании интеграции через
generate-integration.ts.
Генерация .env файлов (generate-env.script.ts)
Скачивает секреты из Doppler и генерирует .env файлы и wrangler.toml.
Использование
pnpm generate:env -- local
pnpm generate:env -- dev
pnpm generate:env -- prodЧто происходит
Загрузка секретов из Doppler конфига:
bashdoppler secrets download --config <local|dev|prod> --format env-no-quotesГенерация файлов:
.env(корневой)integrations/<name>/.dev.vars(для каждой интеграции)workers/<name>/.dev.vars(для каждого воркера)integrations/<name>/wrangler.toml(из шаблонаtemplates/wrangler.integration.toml.tpl)workers/gateway/wrangler.toml(из шаблонаtemplates/wrangler.gateway.toml.tpl)
Автоматическое обнаружение:
- Скрипт автоматически находит все интеграции и воркеры
- Service bindings в Gateway генерируются автоматически
Требуемые секреты в Doppler
| Секрет | Назначение |
|---|---|
CLOUDFLARE_INTEG_DB_ID | ID D1 базы данных |
CLOUDFLARE_INTEG_KV_ID | ID KV namespace |
Конфигурация окружений
| Окружение | ENVIRONMENT | NAME_SUFFIX | DB_SUFFIX |
|---|---|---|---|
local | local | (пусто) | (пусто) |
dev | dev | -dev | -dev |
prod | production | -prod | -prod |
Требования
- Doppler CLI установлен:
brew install doppler - Авторизация:
doppler login - Доступ к проекту
integ-core
Запуск интеграции локально (start-integration.ts)
Запуск Gateway или конкретной интеграции в dev режиме.
Использование
# Gateway
pnpm start gateway
# Интеграция
pnpm start sofaПроцесс запуска
- Сборка интеграции через Turbo
- Запуск wrangler dev с
--persist-to data/miniflare - Готов к приему запросов
Примеры
# В разных терминалах:
# Терминал 1 - Gateway (порт 3001)
pnpm start gateway
# Терминал 2 - Интеграция (порт 8787)
pnpm start sofaТребования
Перед запуском необходимо:
pnpm generate:env -- local # Сгенерировать .env и wrangler.toml
pnpm setup:local # Создать локальные D1/KV базыСинхронизация секретов (sync-cf-secrets.ts)
Синхронизирует секреты из Doppler в Cloudflare Workers (environment variables).
Использование
# Синхронизировать ВСЕ интеграции и Gateway
pnpm sync-secrets:dev
pnpm sync-secrets:prod
# Синхронизировать конкретную интеграцию
pnpm sync-secrets:dev sofa
pnpm sync-secrets:dev gateway
pnpm sync-secrets:prod rozetkaПроцесс
Проверяет инструменты:
- ✅
dopplerCLI - ✅
wranglerCLI
- ✅
Загружает секреты из Doppler:
bashdoppler secrets --project integ-core --config dev --jsonВалидирует что присутствуют обязательные секреты:
GROQ_API_KEY
Загружает каждый секрет в Cloudflare для каждого Worker:
bashwrangler secret put KEY_NAME --env dev
Пример вывода
🔄 Syncing secrets: Doppler (dev) → Cloudflare Workers (dev)
Mode: all integrations
📥 Fetching secrets from Doppler (config: dev)...
Found 15 secrets
✅ All required secrets present
📤 Uploading to 2 worker(s):
📦 sofa
────────────────────────────────
✓ 15/15 secrets synced
📦 gateway
────────────────────────────────
✓ 15/15 secrets synced
==================================================
✅ Success: 2
🎉 All secrets synced successfully!Требования
- Doppler CLI -
brew install doppler - Wrangler CLI -
npm install -g wrangler - Авторизация:bash
doppler login # Для локального запуска export DOPPLER_TOKEN=... # Для CI/CD
Исключаемые секреты
Следующие секреты не загружаются (внутренние Doppler переменные):
DOPPLER_CONFIGDOPPLER_ENVIRONMENTDOPPLER_PROJECT
Использование в CI/CD
При деплое секреты синхронизируются автоматически благодаря Turbo:
# Turbo определяет измененные интеграции и синхронизирует только их
pnpm exec turbo sync-secrets:dev --filter='./integrations/*' --filter='integ-gateway'Ручная синхронизация через GitHub Actions
- Перейти в Actions → Sync Secrets
- Нажать Run workflow
- Выбрать окружение (
dev/production) - Опционально указать интеграцию (оставить пусто для всех)
Локальные D1/KV базы (setup-local.ts)
Создает локальные SQLite файлы для эмуляции D1 и KV.
Использование
# Создать локальные базы
pnpm setup:local
# Сбросить и пересоздать
pnpm setup:resetТребования
Перед запуском необходимо сгенерировать .env файл:
pnpm generate:env -- localСкрипт читает ID баз данных из .env:
CLOUDFLARE_INTEG_DB_ID— ID для D1CLOUDFLARE_INTEG_KV_ID— ID для KV
Что создается
data/miniflare/v3/
├── d1/miniflare-D1DatabaseObject/
│ └── <hash>.sqlite # D1 база данных
└── kv/miniflare-KVNamespaceObject/
└── <hash>.sqlite # KV namespaceАлгоритм хеширования Miniflare
Wrangler/Miniflare использует HMAC-based алгоритм для генерации имени файла SQLite:
function getHashedFileName(id: string) {
const uniqueKey = "miniflare-D1DatabaseObject";
const key = crypto.createHash("sha256").update(uniqueKey).digest();
const nameHmac = crypto.createHmac("sha256", key).update(id).digest().subarray(0, 16);
const hmac = crypto.createHmac("sha256", key).update(nameHmac).digest().subarray(0, 16);
return Buffer.concat([nameHmac, hmac]).toString("hex") + ".sqlite";
}setup-local.ts использует тот же алгоритм, чтобы создавать файлы совместимые с wrangler.
Миграции
Скрипт не применяет миграции. Он только создаёт пустые D1/KV базы данных (SQLite файлы).
Директории migrations/ (глобальная и в интеграциях) содержат только .gitkeep. Миграции определяются в коде — в src/migrations/index.ts каждой интеграции как массив IMigration[]:
export const MIGRATIONS: IMigration[] = [{
name: "integration/0001_create_table",
sql: "CREATE TABLE IF NOT EXISTS ..."
}];Миграции применяются через POST /setup эндпоинт (built-in), а не через setup-local.ts.
Очистка кода
Два скрипта для удаления лишнего кода перед деплоем.
remove-comments.script.ts
Удаляет все комментарии из TypeScript/JavaScript файлов.
pnpm clean:commentsЧто удаляет:
// комментарии/* блочные комментарии */- JSDoc комментарии
remove-return-types.script.ts
Удаляет явное указание return типов функций.
pnpm clean:return-typesПреобразование:
// До
async function handleEvent(data: IData): Promise<void> {
return doSomething(data);
}
// После
async function handleEvent(data: IData) {
return doSomething(data);
}Объединенная очистка
pnpm clean:code
# Эквивалентно:
# pnpm clean:comments && pnpm clean:return-typesИспользуется в:
- Pre-commit hook (husky + lint-staged)
- Pre-deploy:
pnpm pre-deploy
Жизненный цикл разработки
Локальная разработка
# 1. Генерация .env и wrangler.toml из Doppler
pnpm generate:env -- local
# 2. Создание локальных D1/KV баз
pnpm setup:local
# 3. Запуск Gateway в терминале 1
pnpm start gateway
# 4. Запуск интеграции в терминале 2
pnpm start sofa
# 5. Разработка, тестирование
pnpm lint
pnpm testСоздание новой интеграции
# 1. Создать из шаблона
pnpm generate:integration my-integration
# 2. Перегенерировать wrangler.toml (включит новую интеграцию)
pnpm generate:env -- local
# 3. Реализовать handlers
cd integrations/my-integration
# 4. Запустить локально
pnpm start my-integration
# 5. Коммит + Push
git add .
git commit -m "feat: add my-integration"
git push origin feature/my-integrationДеплой
# Автоматический (через GitHub Actions)
git push origin dev # → deploy-to-dev.yml
git push origin main # → deploy-to-prod.yml
# Проверка деплоя
pnpm cli logs sofaОптимизация и отладка
Turbo filtering
Запуск только нужного пакета:
# Dev только Sofa
turbo dev --filter=sofa
# Build только Sofa и зависимостей
turbo build --filter=sofa...Clearing cache
Если возникают проблемы с кэшем:
# Удалить Turbo cache
rm -rf .turbo
# Удалить dist папки
find . -name dist -type d -exec rm -rf {} +
# Переустановить зависимости
rm pnpm-lock.yaml
pnpm installСмежные документы
- CI_CD.md — GitHub Actions workflows и оптимизация
- DEVELOPMENT.md — локальная разработка
- CODE_RULES.md — стандарты кода
- INTEGRATION_CHECKLIST.md — чеклист для новой интеграции