Документація / Changelog
Changelog
Історія релізів пакетів Hopak з посиланнями на відповідні гіди з оновлення.
Нотатки до релізів пакетів Hopak. Кожен розділ посилається на відповідний гід з оновлення.
Поточні версії
| Пакет | Версія | Опис |
|---|---|---|
@hopak/core | 1.0.1 | ядро фреймворку |
@hopak/cli | 1.0.1 | CLI-інструмент |
@hopak/auth | 1.0.1 | auth + OAuth |
@hopak/testing | 1.0.1 | in-process тестовий сервер |
@hopak/common | 1.0.1 | спільні примітиви |
1.0.1 — виправлення після повного наскрізного прогону
Кожну можливість 1.0 було перевірено на реальному заскафолдженому проєкті на всіх трьох діалектах. Що це виявило:
- Типи полів із плагінів тепер справді зберігають значення. Зареєстроване поле створювало колонку в таблиці, про яку Drizzle не знав, тож записи тихо втрачались (або падали, якщо колонка була
NOT NULL).ctx.registerFieldтепер приймає{ storage, schema }— оберітьtext/integer/real/boolean/timestamp/json, а Hopak налаштує колонку та DDL для всіх трьох діалектів. model.tableName— фізична назва таблиці (post→posts) тепер лежить на моделі, тож сирий SQL і DDL міграцій більше не мусять її вгадувати. Раніше документація показувалаFROM post, що ніколи не відповідало реальній таблиці.hashPasswordу@hopak/auth— ідемпотентне хешування. Модель, що хешує уbeforeCreate, іcredentialsSignupхешували обидві, а подвійний хеш ніколи не збігався при вході.createTestServer({ plugins })— проєкт із типами полів від плагіна взагалі неможливо було підняти тестовим сервером.crud.*будує схеми валідації ліниво, тож модулі маршрутів можна імпортувати до налаштування плагінів.ctx.setHeaderдоходить до кожної відповіді — статичних файлів, 404, 405, помилок і відповідей, які обробник створив сам.- Старт попереджає про незастосовані міграції замість того, щоб перший запит помирав на відсутній таблиці.
1.0.0 — плагіни, хуки моделей, OpenAPI, realtime (breaking)
Усі п’ять пакетів переходять на 1.0.0 одним скоординованим релізом.
Нова поверхня — кожна можливість за одним явним жестом, невидима, доки Ви до неї не потягнетеся:
- Плагіни —
hopak().use(plugin): власні типи полів (ctx.registerField+ підкласFieldBuilder), plugin-middleware, хукиonBoot. Вбудовані поля реєструються через той самий реєстр. - Хуки життєвого циклу моделей —
model(name, fields, { hooks }):beforeCreate/afterCreate/beforeUpdate/afterUpdate/beforeDelete/afterDeleteнавколо однорядкових записів; хешування пароля стає одним хуком. - OpenAPI —
hopak openapiгенерує OpenAPI 3.1-документ з моделей + маршрутів; CRUD-операції виходять повністю типізованими, схеми відповідей вирізають чутливі поля. - WebSockets —
export const WS = defineWebSocket({...})у файлі маршруту; upgrade проходить черезbefore-middleware, тож auth закриває і сокети. - SSE — хелпер
sse()для обробників маршрутів зіstream.send/stream.closed. rateLimit()— fixed-window in-process лімітер ізRetry-After.- Ліміт тіла запиту —
server.maxRequestBodyBytes(типово 16 MiB →413). - Типізований CRUD —
crud.read(post)— цеRouteDefinition<Post>; новий хелперWithIncluded<Row, Relations>типізує результатиinclude;builder()типізований на фабриках діалектів. - OAuth PKCE — code verifier, прив’язаний до кукі; типово увімкнено для Google, opt-in для GitHub. Приватні email GitHub розв’язуються через
/user/emails.
Hardening:
- Статичні файли,
404та405тепер проходять через глобальні middleware — access-логи та guard-и бачать кожен запит. - Заголовки, встановлені через
ctx.setHeader, доживають до відповідей з помилками (X-Request-Id,Retry-After). - Умовні запити на статичних файлах:
If-None-Match/If-Modified-Since→304. - Конкурентні транзакції SQLite ставляться у чергу замість колізії на спільному з’єднанні.
?limit=abcна CRUD-списках →400замістьNaN, що доходить до SQL.hopak migrate up --to <unknown-id>завершується помилкою замість мовчазного застосування всього.credentialsLoginперевіряє fallback-хеш, коли користувача не існує — таймінг відповіді більше не видає існування облікового запису.
Breaking:
db.execute()прибрано з публічного інтерфейсуDatabase(deprecated з 0.5).ctx.executeвсередині міграцій залишається.- OAuth-колбеки (
githubCallback/googleCallback) тепер вимагаютьcallbackUrl— однаковий набір параметрів для обох провайдерів. @hopak/testingоголошує@hopak/core/@hopak/commonpeer-залежностями.
0.5.0 — db.sql, db.builder(), deprecated db.execute() (breaking)
- Новий примітив:
db.sql— tagged-template SQL для тих ~5% запитів, що.model()не покриває. Інтерполяції стають driver-native placeholder-ами (?/$N); значення ніколи не потрапляють у текст SQL, тож${attacker}безпечний by construction. - Driver-native на кожному діалекті: SQLite йде через
bun:sqlite.prepare().all(), Postgres черезpostgres.js sql.unsafe(), MySQL черезmysql2 pool.execute(). Drizzle на шляху сирого SQL більше немає. db.raw()→db.builder(). Те саме повернення (Drizzle-клієнт діалекту), зрозуміліша назва. Breaking rename, механічна пошук+заміна.db.execute(sql, params?)позначено@deprecated— залишається як forwarder, щоб наявні файли міграцій компілювалися. Новий код пишеdb.sql. Прибрано в 0.6.0.MigrationContextотримуєctx.sqlпоруч зctx.execute(теж deprecated).hopak migrate newза замовчуванням генеруєctx.sql.- Внутрішній код фреймворку (
tracker.ts,introspect.ts) переведено з cast-хакаdb.raw() as { all?, execute? }наdb.sql.
0.4.9 — Гігієна prototype-pollution у deepMerge
deepMergeу@hopak/commonвідкидає ключі__proto__,constructor,prototypeз source, тож JSON-пейлоад більше не може підмінити prototype chain результату. Перші регресійні тести для пакетаcommon.- Algorithm pinning у JWT-верифікації
@hopak/auth: верифікатор більше не приймає токен, підписаний відмінним від налаштованого алгоритмом — закриває algorithm-confusion атаку. - Static-file handler кешує canonical root path (realpath) на інстанс; symlink, що розрішується за межі public root, і далі падає коректно.
FileField.maxSize(n)тепер реально обмежує Valibot-схему на валідації, а не лише на config-write.
0.4.0 — Valibot, безпечніша валідація
- Runtime валідації переведено з Zod на Valibot: бандл ~10× менший, парсинг ~2–3× швидший.
validate()таbuildModelSchema()зберігають той самий API; model-driven валідація лишається незмінною.RouteSchemas.body | query | paramsтепер мають типv.GenericSchemaзамістьz.ZodType.@hopak/coreбільше не залежить відzod.- Експорт типу
ZodFieldSchemaперейменовано наFieldSchema.
0.3.0 — Міграції
- Нові підкоманди
hopak migrate:init,new,up,down,status. hopak syncстає шляхом dev-бутстрапу; він відмовляється виконуватись, щойно вapp/migrations/з’являються файли.hopak devпропускає викликdb.sync()на старті, коли є міграції — рантайм ніколи не змінює схему самостійно.hopak syncтепер виводить попередження про дрейф, коли моделі оголошують колонки, яких немає в активній БД..index()на полі тепер дійсно створюєCREATE INDEX IF NOT EXISTSпід час sync (раніше мовчки ігнорувалося).- Новий публічний API:
ctx.db.execute(sql, params?)для сирого SQL.
0.2.0 — Скафолдинг CRUD (breaking)
- CRUD-ендпоінти переходять з runtime-генерації на скафолдинг через
hopak generate crud <model>. { crud: true }на моделях прибрано; файли маршрутів стають реальними.ts, які Ви можете читати й редагувати.- Dev-сертифікати HTTPS вимагають
hopak generate cert— старт більше не викликаєopensslза Вашою спиною. @hopak/testingвідмовляється відwithCrud: true; під’єднуйте маршрути через нові хелпериcrud.*або передавайтеrootDirдля наскрізних тестів.- Прибрано невикористовувані опції моделі:
owner,publicRead,auth,softDelete.
0.1.0 — Перший реліз
- Моделі, зв’язки, ергономіка запитів, валідація, серіалізація, типізовані помилки.
- CRUD, згенерований у рантаймі через
{ crud: true }, dev-сертифікати, створені у рантаймі дляserver.https.enabled. - Перша версія CLI:
hopak new,hopak use,hopak sync,hopak check,hopak dev.