letopis 1.4.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT-CHEATSHEET.md +329 -278
- package/CHANGELOG.md +558 -1
- package/README.md +606 -1037
- package/dist/acl.d.ts +78 -1
- package/dist/acl.js +264 -13
- package/dist/admin.d.ts +10 -141
- package/dist/admin.js +24 -175
- package/dist/auth.d.ts +2 -2
- package/dist/auth.js +5 -15
- package/dist/cache.d.ts +8 -1
- package/dist/cache.js +33 -10
- package/dist/chain.d.ts +19 -41
- package/dist/chain.js +169 -201
- package/dist/cli.js +51 -88
- package/dist/demo/booking.d.ts +352 -36
- package/dist/describe.d.ts +47 -0
- package/dist/describe.js +195 -0
- package/dist/errors.d.ts +59 -13
- package/dist/errors.js +190 -29
- package/dist/index.d.ts +52 -71
- package/dist/index.js +245 -130
- package/dist/internal.d.ts +12 -0
- package/dist/internal.js +5 -0
- package/dist/jsonschema.js +18 -17
- package/dist/load.d.ts +20 -12
- package/dist/load.js +225 -186
- package/dist/mcp.d.ts +5 -7
- package/dist/mcp.js +171 -215
- package/dist/messages/access.d.ts +90 -0
- package/dist/messages/access.js +113 -0
- package/dist/messages/api.d.ts +171 -0
- package/dist/messages/api.js +215 -0
- package/dist/messages/boot.d.ts +201 -0
- package/dist/messages/boot.js +256 -0
- package/dist/messages/codes.d.ts +172 -0
- package/dist/messages/codes.js +173 -0
- package/dist/messages/index.d.ts +95 -0
- package/dist/messages/index.js +118 -0
- package/dist/messages/mcp.d.ts +306 -0
- package/dist/messages/mcp.js +387 -0
- package/dist/messages/model.d.ts +233 -0
- package/dist/messages/model.js +283 -0
- package/dist/messages/query.d.ts +131 -0
- package/dist/messages/query.js +158 -0
- package/dist/messages/sql-access.d.ts +70 -0
- package/dist/messages/sql-access.js +87 -0
- package/dist/messages/sql-core.d.ts +150 -0
- package/dist/messages/sql-core.js +181 -0
- package/dist/messages/sql-time.d.ts +71 -0
- package/dist/messages/sql-time.js +88 -0
- package/dist/messages/sql-write.d.ts +246 -0
- package/dist/messages/sql-write.js +270 -0
- package/dist/messages/time.d.ts +23 -0
- package/dist/messages/time.js +29 -0
- package/dist/messages/types.d.ts +27 -0
- package/dist/messages/types.js +5 -0
- package/dist/messages/write.d.ts +405 -0
- package/dist/messages/write.js +509 -0
- package/dist/model.d.ts +73 -60
- package/dist/model.js +26 -29
- package/dist/ops.d.ts +35 -0
- package/dist/ops.js +101 -0
- package/dist/pglite.d.ts +0 -9
- package/dist/pglite.js +3 -1
- package/dist/registry.d.ts +3 -19
- package/dist/registry.js +3 -16
- package/dist/signals.d.ts +5 -9
- package/dist/signals.js +5 -9
- package/dist/sql.d.ts +13 -6
- package/dist/sql.js +176 -83
- package/dist/sync.d.ts +9 -3
- package/dist/sync.js +51 -21
- package/dist/tx.d.ts +26 -1
- package/dist/tx.js +44 -14
- package/dist/typed.d.ts +240 -45
- package/dist/types.d.ts +23 -91
- package/dist/types.js +12 -14
- package/dist/up.d.ts +53 -32
- package/dist/up.js +184 -73
- package/dist/uuid.js +5 -5
- package/dist/validate.d.ts +13 -1
- package/dist/validate.js +61 -29
- package/dist/watch.d.ts +11 -10
- package/dist/watch.js +33 -70
- package/dist/write.d.ts +9 -16
- package/dist/write.js +118 -187
- package/llms.txt +22 -25
- package/package.json +8 -11
- package/sql/10-core.sql +7 -50
- package/sql/15-errors.sql +64 -10
- package/sql/20-context.sql +7 -6
- package/sql/30-validate.sql +35 -27
- package/sql/40-class.sql +20 -114
- package/sql/50-acl.sql +8 -13
- package/sql/60-write.sql +220 -667
- package/sql/70-read.sql +20 -16
- package/sql/80-auth.sql +24 -27
- package/sql/90-time.sql +70 -859
- package/sql/95-seed.system.sql +7 -14
- package/sql/99-revision.sql +2 -1
- package/sql/README.md +32 -24
- package/sql/migrate/README.md +14 -0
- package/AGENT-CHEATSHEET.en.md +0 -485
- package/MIGRATION.md +0 -190
- package/README.en.md +0 -2859
- package/dist/import.d.ts +0 -185
- package/dist/import.js +0 -820
- package/dist/project.d.ts +0 -350
- package/dist/project.js +0 -1224
- package/sql/75-history.sql +0 -358
- package/sql/88-derived.sql +0 -1235
- package/sql/migrate/0006-changed-paths.sql +0 -3
- package/sql/migrate/0007-secret-account-fk.sql +0 -12
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Этап 2: connect() — подключение под сессией, реестр классов, отложенный сигнал, db.sql.
|
|
6
6
|
* Этап 3: цепочки чтения t.Класс(…).Связь().rows(); этап 4 — запись цепочками и загрузчик.
|
|
7
7
|
* Этап 5: db.auth (креды, вход, сессии), db.acl, db.as(аккаунт, { tenant }) — имперсонация.
|
|
8
|
-
* Этап 6: история (
|
|
8
|
+
* Этап 6: история (versions, asOf, restore), maintain, watch, кэш результатов.
|
|
9
9
|
*/
|
|
10
10
|
import postgres from 'postgres';
|
|
11
11
|
import { Registry } from './registry.js';
|
|
@@ -13,41 +13,40 @@ import { type Tx } from './tx.js';
|
|
|
13
13
|
import { type AuthApi } from './auth.js';
|
|
14
14
|
import { type AclApi } from './acl.js';
|
|
15
15
|
import { type LoadInput, type LoadOptions, type LoadReport } from './load.js';
|
|
16
|
-
import { type Batch, type Chain, type StepFn } from './chain.js';
|
|
16
|
+
import { type Batch, type Chain, type ChainRef, type StepFn } from './chain.js';
|
|
17
17
|
import type { QueryEvent, Row } from './types.js';
|
|
18
18
|
import { type CacheOptions, type CacheStats } from './cache.js';
|
|
19
19
|
import { Subscription, type WatchOptions } from './watch.js';
|
|
20
|
-
import {
|
|
21
|
-
import
|
|
22
|
-
import type { AnyModelLike, StepsOf } from './typed.js';
|
|
20
|
+
import { type MaintainReport } from './admin.js';
|
|
21
|
+
import type { AnyModelLike, OrOp, StepsOf } from './typed.js';
|
|
23
22
|
export { DDL_REVISION } from './types.js';
|
|
24
23
|
export { uuidv5, v5Name, v5Id, idOf, type KeyedClass } from './uuid.js';
|
|
25
24
|
export { LetopisError, ValidationError, fromDbError, type Issue } from './errors.js';
|
|
26
|
-
export { Registry, type
|
|
25
|
+
export { Registry, type ClassInfo, type EndInfo, type LeafType } from './registry.js';
|
|
27
26
|
export { compileValidator, applyDefaults, type Validator } from './validate.js';
|
|
28
27
|
export { syncModels, generateTypes, schemaToTs, type SyncResult } from './sync.js';
|
|
29
|
-
export { ne, gt, gte, lt, lte, between, inList, like, ilike, starts, ends, has, hasAny, hasAll, exists, isNull, not,
|
|
28
|
+
export { ne, gt, gte, lt, lte, between, inList, like, ilike, starts, ends, has, hasAny, hasAll, exists, isNull, not, isOp } from './ops.js';
|
|
29
|
+
/**
|
|
30
|
+
* Хотя бы один из фильтров: `db.Product(or({ sku: 'K-1' }, { price: lt(500) }))` — товар K-1 или дешевле 500. Ставится
|
|
31
|
+
* вместо всего фильтра шага, а не значением поля; условия внутри одного фильтра соединяются через «и». В шаге подключения
|
|
32
|
+
* с моделями (`TypedDb`) фильтры внутри — поля и роли класса шага: тип им даёт шаг (план 2.0, этап 4, п. 1). Та же
|
|
33
|
+
* фабрика, что в реестре операторов (ops.ts), — другой у неё только тип.
|
|
34
|
+
*/
|
|
35
|
+
export declare const or: <F extends object>(...filters: NoInfer<F>[]) => OrOp<F>;
|
|
30
36
|
export { cursorOf } from './sql.js';
|
|
31
37
|
export { inc, isInc, type IncMarker, type WriteRow } from './write.js';
|
|
32
38
|
export { totpCode, hashPassword, verifyHash, type AuthApi, type LoginResult, type Credential, type SessionInfo } from './auth.js';
|
|
33
|
-
export type { AclApi, AclDecision, AclDataDecision, AclOp } from './acl.js';
|
|
39
|
+
export type { AclApi, AclDecision, AclDataDecision, AclOp, AclRule, AclRuleSpec, AclTarget } from './acl.js';
|
|
34
40
|
export type { LoadOptions, LoadReport, LoadIssue, LoadInput } from './load.js';
|
|
35
|
-
export type { Chain, ChainCore, StepFn, BatchEntry } from './chain.js';
|
|
36
|
-
export type { ModelLike, AnyModelLike, RowOf, FilterOf, FieldFilterOf, TypedChain, StepsOf, PatchOf } from './typed.js';
|
|
41
|
+
export type { Chain, ChainCore, ChainRef, StepFn, BatchEntry } from './chain.js';
|
|
42
|
+
export type { ModelLike, AnyModelLike, RowOf, FilterOf, FieldFilterOf, TypedChain, StepsOf, PatchOf, OrOp, SystemModels } from './typed.js';
|
|
37
43
|
export type { Row, Path, Filter, FieldFilter, Cursor, ChainMods, QueryEvent, Op, Scalar } from './types.js';
|
|
38
|
-
export type { DiffChange, DiffResult, DiffOptions, BlameField, BlameResult, BlameOptions } from './types.js';
|
|
39
44
|
export type { CacheOptions, CacheStats } from './cache.js';
|
|
40
45
|
export type { SignalMode } from './signals.js';
|
|
41
46
|
export type { WatchOptions, WatchEvent, Subscription } from './watch.js';
|
|
42
|
-
export type {
|
|
43
|
-
export
|
|
44
|
-
export { describeText } from './admin.js';
|
|
45
|
-
export { up, createTenant, type UpOptions, type UpResult, type HistoryPolicy, type TenantOptions, type TenantResult } from './up.js';
|
|
47
|
+
export type { MaintainReport } from './admin.js';
|
|
48
|
+
export { up, createTenant, type UpOptions, type UpResult, type TenantOptions, type TenantResult, type LoginOptions } from './up.js';
|
|
46
49
|
export { RESERVED_CLASS_NAMES, CHAIN_METHODS, DB_METHODS } from './types.js';
|
|
47
|
-
/** Снесено в 1.0.0: id v7 больше не выдаются (§2.3). */
|
|
48
|
-
export declare function uuidv7(): never;
|
|
49
|
-
/** Снесено в 1.0.0: пространство имён v5 — id арендатора. Любое использование значения — ошибка. */
|
|
50
|
-
export declare const LETOPIS_NS: string;
|
|
51
50
|
export interface ConnectOptions {
|
|
52
51
|
/** Строка подключения; либо готовый пул postgres.js в `sql`. */
|
|
53
52
|
dsn?: string;
|
|
@@ -58,13 +57,25 @@ export interface ConnectOptions {
|
|
|
58
57
|
token?: string;
|
|
59
58
|
apiKey?: string;
|
|
60
59
|
service?: string;
|
|
61
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* Продлевать сессию раз в минуту работы (по умолчанию да, §2.9); после простоя дольше минуты — до операции: истёкшая
|
|
62
|
+
* сессия тогда даёт `no_session`, а не анонимное чтение с пустым ответом, а подключение по `apiKey` обменивает ключ
|
|
63
|
+
* заново. `false` — без продления и без этой проверки.
|
|
64
|
+
*/
|
|
62
65
|
refreshSession?: boolean;
|
|
63
66
|
/** Разрешить роль, которая обходит RLS (суперпользователь, `BYPASSRLS`, член роли-владельца), — администраторское подключение (§2.9). */
|
|
64
67
|
allowBypassRls?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Один процесс малого приложения (план 2.0, этап 3): строка подключения администратора (или пул postgres.js). Второй
|
|
70
|
+
* пул — не больше двух соединений — открывается при первой надобности и служит только администраторским вызовам корня
|
|
71
|
+
* подключения: `load`, `maintain` и `syncModels`, с той же сессией.
|
|
72
|
+
* Цепочки и `db.sql` идут через пул приложения (`dsn`) под RLS. Роль строки — суперпользователь или роль с `SET` на
|
|
73
|
+
* роль-владельца, иначе `admin_required`. Пароль администратора в процессе приложения — только для малых приложений.
|
|
74
|
+
*/
|
|
75
|
+
admin?: string | postgres.Sql;
|
|
65
76
|
/** Имя роли-владельца (по умолчанию `letopis_owner`). */
|
|
66
77
|
owner?: string;
|
|
67
|
-
/** Интервал отправки отложенного сигнала, мс (по умолчанию 100
|
|
78
|
+
/** Интервал отправки отложенного сигнала, мс (по умолчанию 100). */
|
|
68
79
|
notifyIntervalMs?: number;
|
|
69
80
|
/** Размер пула, если подключение создаёт сам `connect()`. */
|
|
70
81
|
max?: number;
|
|
@@ -87,7 +98,7 @@ export interface ConnectOptions {
|
|
|
87
98
|
* Запускать `maintain()` по расписанию: интервал — число миллисекунд или строка вроде `'15m'`, `'1h'`, от 1 мс до
|
|
88
99
|
* 2³¹−1 мс (около 24 суток); иначе `connect()` отказывает с `invalid_data`, не открывая соединений. Если обслуживание в
|
|
89
100
|
* этот момент уже ведёт другой процесс или ещё идёт прошлый запуск, запуск пропускается. `close()` ждёт, пока идущий
|
|
90
|
-
* запуск
|
|
101
|
+
* запуск закончится.
|
|
91
102
|
*/
|
|
92
103
|
maintain?: string | number;
|
|
93
104
|
}
|
|
@@ -119,37 +130,10 @@ export interface DbCore {
|
|
|
119
130
|
/** Отправить накопленные сигналы сейчас. */
|
|
120
131
|
flushSignals(): Promise<void>;
|
|
121
132
|
/**
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* версий всех объектов: храните его вне базы, тогда заметна и подмена самых свежих версий. Нужно право `letopis.verify`
|
|
125
|
-
* (по умолчанию оно у системного администратора) или администраторское подключение.
|
|
126
|
-
*/
|
|
127
|
-
verify(opts?: {
|
|
128
|
-
data?: boolean;
|
|
129
|
-
}): Promise<VerifyResult>;
|
|
130
|
-
/** Обслуживание: истёкшие сессии и коды, прореживание журнала по политике хранения, очередь сигналов. */
|
|
131
|
-
maintain(opts?: MaintainOptions): Promise<MaintainReport>;
|
|
132
|
-
/**
|
|
133
|
-
* Сбрасывает тестовую установку: сессии, данные одного арендатора или всё — смотря по `level`. Работает, только если
|
|
134
|
-
* установка поставлена с `up({ allowReset: true })`, у вызывающего есть право `letopis.reset` (или подключение
|
|
135
|
-
* администраторское), а `confirm` совпадает с именем схемы.
|
|
136
|
-
*/
|
|
137
|
-
reset(opts: ResetOptions): Promise<ResetResult>;
|
|
138
|
-
/**
|
|
139
|
-
* Стирает версии, сделанные раньше момента `before`; текущая версия остаётся всегда. Вместо стёртого начала истории
|
|
140
|
-
* остаётся служебная запись `trim` со временем появления объекта.
|
|
141
|
-
*/
|
|
142
|
-
trimHistory(target: string | string[] | Row | Row[], before: string | Date): Promise<number>;
|
|
143
|
-
/**
|
|
144
|
-
* Меняет ключ класса. Объекты его семейства (сам класс и потомки), у которых по новому ключу выходит другой id,
|
|
145
|
-
* переезжают на новый id, а ссылки на них переводятся.
|
|
133
|
+
* Обслуживание: истёкшие и погашенные сессии, одноразовые коды, строки-замки удалённых классов, очередь сигналов. Нужно
|
|
134
|
+
* право `letopis.maintain` (по умолчанию оно у системного администратора) или администраторское подключение.
|
|
146
135
|
*/
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Описание модели для программ и языковых моделей: классы арендатора сессии и общие классы System с полями, ключом,
|
|
150
|
-
* ссылками и метаданными `meta`. `describeText(db.describe())` превращает его в текст.
|
|
151
|
-
*/
|
|
152
|
-
describe(): ModelDescription;
|
|
136
|
+
maintain(): Promise<MaintainReport>;
|
|
153
137
|
/** Подписка по курсору: `for await (const ev of db.watch({ from })) …`; `sub.cursor` — откуда продолжить. */
|
|
154
138
|
watch(opts?: WatchOptions): Subscription;
|
|
155
139
|
/** Кэш результатов подключения. */
|
|
@@ -158,7 +142,7 @@ export interface DbCore {
|
|
|
158
142
|
stats(): CacheStats;
|
|
159
143
|
};
|
|
160
144
|
/** Начать путь с готового узла: `db.entity(row | цепочка)`. */
|
|
161
|
-
entity(x:
|
|
145
|
+
entity(x: ChainRef | Row): Chain;
|
|
162
146
|
/**
|
|
163
147
|
* Подключение на том же пуле от имени другого аккаунта: запросы идут с его правами и в его арендаторе. Журнал
|
|
164
148
|
* записывает автором версий этот аккаунт, а исполнителем (`agent`) — аккаунт сессии, например сервис. Нужно право
|
|
@@ -170,8 +154,7 @@ export interface DbCore {
|
|
|
170
154
|
owner?: string;
|
|
171
155
|
tenant?: string;
|
|
172
156
|
}): Promise<Db>;
|
|
173
|
-
/** Явная транзакция `read committed`: те же цепочки, `commit()`, `rollback()`, `lock()`, `forUpdate()
|
|
174
|
-
/** Явная транзакция; `reason` — причина изменения для всех операций блока (план 1.1). */
|
|
157
|
+
/** Явная транзакция `read committed`: те же цепочки, `commit()`, `rollback()`, `lock()`, `forUpdate()`; `reason` — причина изменения для всех операций блока. */
|
|
175
158
|
begin(opts?: {
|
|
176
159
|
reason?: string;
|
|
177
160
|
}): Promise<DbTx>;
|
|
@@ -182,18 +165,6 @@ export interface DbCore {
|
|
|
182
165
|
* от имени пользователя (опция `as`). Работает только на администраторском подключении, иначе `admin_required`.
|
|
183
166
|
*/
|
|
184
167
|
load(input: LoadInput, opts?: LoadOptions): Promise<LoadReport>;
|
|
185
|
-
/**
|
|
186
|
-
* Проектор из журнала (план 1.1, §2.4): строит строки производных классов (`derivedBy: имя`) из изменений
|
|
187
|
-
* классов `from`; `run()` — догнать журнал и следовать за ним, `rebuild()` — перестроить с текущего состояния.
|
|
188
|
-
* Только на администраторском подключении (иначе `admin_required`).
|
|
189
|
-
*/
|
|
190
|
-
projector(name: string, opts: ProjectorOptions): Projector;
|
|
191
|
-
/**
|
|
192
|
-
* Ремонт агрегатов в базе (план 1.1, §2.4): поля класса (с потомками) во всех арендаторах — заново из живых строк
|
|
193
|
-
* источников, под исключительными блокировками; версия — только у исправленных. Возвращает их число. Только на
|
|
194
|
-
* администраторском подключении (иначе `admin_required`).
|
|
195
|
-
*/
|
|
196
|
-
rebuildAggregates(cls: string): Promise<number>;
|
|
197
168
|
/**
|
|
198
169
|
* Именованная очередь планов фасада: `batch.Класс(…).create(…)`; `batch.run()` — одной транзакцией. У корня,
|
|
199
170
|
* у каждого `db.as()` и у каждой `db.begin()` очереди свои: план исполняется от имени фасада, который его поставил.
|
|
@@ -215,12 +186,22 @@ export type Db = DbCore & {
|
|
|
215
186
|
};
|
|
216
187
|
/** Явная транзакция `db.begin()`: тот же API; ошибка любого запроса её ломает (§2.5). */
|
|
217
188
|
export type DbTx = Db;
|
|
218
|
-
/**
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
189
|
+
/**
|
|
190
|
+
* Подключение со строгими типами по моделям: `connect({ models })` или `connect<Models>()` с объявлениями
|
|
191
|
+
* `letopis types`. Шаг — только известный класс или алиас (модели и системные классы), переходы — по концам, слоты — роли
|
|
192
|
+
* класса; имена, известные только во время выполнения, — `loose(db)` (план 2.0, этап 4, п. 1). Модели без литеральных
|
|
193
|
+
* имён (`AnyModel[]` вместо списка `as const`) строгим типам не помогут — тогда это `Db`.
|
|
194
|
+
*/
|
|
195
|
+
export type TypedDb<M extends readonly AnyModelLike[]> = string extends M[number]['name'] ? Db : DbCore & StepsOf<M>;
|
|
222
196
|
export type { Batch };
|
|
197
|
+
/**
|
|
198
|
+
* То же подключение без строгих типов: шагом может быть любое имя, в том числе известное только во время выполнения, —
|
|
199
|
+
* `loose(db)[имя]()`. Объект тот же: проверки во время выполнения (неизвестное имя или поле, переход, слот) не меняются.
|
|
200
|
+
*/
|
|
201
|
+
export declare function loose(db: DbCore): Db;
|
|
223
202
|
export declare function connect<const M extends readonly AnyModelLike[]>(opts: ConnectOptions & {
|
|
224
203
|
models: M;
|
|
225
204
|
}): Promise<TypedDb<M>>;
|
|
226
205
|
export declare function connect(opts: ConnectOptions): Promise<Db>;
|
|
206
|
+
/** Строгие типы без моделей Zod — из объявлений `letopis types`: `connect<Models>({ … })`. */
|
|
207
|
+
export declare function connect<M extends readonly AnyModelLike[]>(opts: ConnectOptions): Promise<TypedDb<M>>;
|