letopis 0.20.3 → 1.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.en.md +368 -0
- package/AGENT-CHEATSHEET.md +354 -0
- package/CHANGELOG.md +348 -0
- package/MIGRATION.md +190 -0
- package/README.en.md +1937 -0
- package/README.md +1493 -3466
- package/dist/acl.d.ts +26 -50
- package/dist/acl.js +22 -267
- package/dist/admin.d.ts +138 -0
- package/dist/admin.js +170 -0
- package/dist/auth.d.ts +120 -73
- package/dist/auth.js +121 -306
- package/dist/cache.d.ts +73 -0
- package/dist/cache.js +148 -0
- package/dist/chain.d.ts +124 -191
- package/dist/chain.js +369 -551
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +164 -0
- package/dist/demo/booking.d.ts +289 -0
- package/dist/demo/booking.js +159 -0
- package/dist/errors.d.ts +29 -0
- package/dist/errors.js +70 -0
- package/dist/import.d.ts +179 -0
- package/dist/import.js +792 -0
- package/dist/index.d.ts +172 -26
- package/dist/index.js +304 -178
- package/dist/jsonschema.d.ts +22 -0
- package/dist/jsonschema.js +167 -0
- package/dist/load.d.ts +76 -0
- package/dist/load.js +884 -0
- package/dist/model.d.ts +166 -0
- package/dist/model.js +224 -0
- package/dist/ops.d.ts +7 -6
- package/dist/ops.js +7 -51
- package/dist/pglite.d.ts +22 -0
- package/dist/pglite.js +45 -0
- package/dist/registry.d.ts +57 -0
- package/dist/registry.js +82 -0
- package/dist/sql.d.ts +59 -142
- package/dist/sql.js +568 -654
- package/dist/sync.d.ts +31 -0
- package/dist/sync.js +108 -0
- package/dist/tx.d.ts +129 -8
- package/dist/tx.js +300 -73
- package/dist/typed.d.ts +97 -0
- package/dist/typed.js +1 -0
- package/dist/types.d.ts +71 -250
- package/dist/types.js +27 -108
- package/dist/up.d.ts +140 -47
- package/dist/up.js +339 -267
- package/dist/uuid.d.ts +21 -6
- package/dist/uuid.js +48 -64
- package/dist/validate.d.ts +24 -0
- package/dist/validate.js +251 -0
- package/dist/watch.d.ts +62 -0
- package/dist/watch.js +168 -0
- package/dist/write.d.ts +117 -74
- package/dist/write.js +658 -720
- package/llms.txt +26 -0
- package/package.json +49 -19
- package/sql/10-core.sql +136 -0
- package/sql/15-errors.sql +60 -0
- package/sql/20-context.sql +153 -0
- package/sql/30-validate.sql +423 -0
- package/sql/40-class.sql +259 -0
- package/sql/50-acl.sql +539 -0
- package/sql/60-write.sql +1369 -0
- package/sql/70-read.sql +245 -0
- package/sql/80-auth.sql +827 -0
- package/sql/90-time.sql +957 -0
- package/sql/95-seed.system.sql +178 -0
- package/sql/99-revision.sql +3 -0
- package/sql/README.md +56 -0
- package/sql/seed.booking.sql +39 -112
- package/dist/schema.d.ts +0 -15
- package/dist/schema.js +0 -351
- package/dist/sessions.d.ts +0 -32
- package/dist/sessions.js +0 -114
- package/dist/tables.d.ts +0 -105
- package/dist/tables.js +0 -248
- package/docker/Dockerfile +0 -40
- package/docker/start.sh +0 -18
- package/scripts/check-docs.mjs +0 -375
- package/scripts/gen-api-contract.mjs +0 -226
- package/scripts/gen-types.mjs +0 -350
- package/scripts/release-notes.mjs +0 -76
- package/scripts/schema-sync.mjs +0 -185
- package/sql/ddl.sql +0 -600
- package/sql/seed.auth.sql +0 -73
package/dist/index.d.ts
CHANGED
|
@@ -1,29 +1,175 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* letopis
|
|
2
|
+
* letopis 1.0 — основная точка входа пакета. Руководство — README.md пакета, машинный каталог API —
|
|
3
|
+
* docs/api-contract.json репозитория; решения и их причины — reports/PLAN-LETOPIS-1.0.md (этапы ниже).
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* const db = await connect({ dsn, schema: 'v1.booking' }) // безличный пул
|
|
9
|
-
* const t = await db.as(accountId) // арендатор ВЫЗОВА
|
|
10
|
-
* await t.Мастер({ name: 'Вася' }).навык().Услуга().run()
|
|
5
|
+
* Этап 2: connect() — подключение под сессией, реестр классов, отложенный сигнал, db.sql.
|
|
6
|
+
* Этап 3: цепочки чтения t.Класс(…).Связь().rows(); этап 4 — запись цепочками и загрузчик.
|
|
7
|
+
* Этап 5: db.auth (креды, вход, сессии), db.acl, db.as(аккаунт, { tenant }) — имперсонация.
|
|
8
|
+
* Этап 6: история (restore, purge, rekey, trimHistory), verify, maintain, reset, watch, кэш результатов.
|
|
11
9
|
*/
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export {
|
|
25
|
-
export
|
|
26
|
-
export type
|
|
27
|
-
export
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
10
|
+
import postgres from 'postgres';
|
|
11
|
+
import { Registry } from './registry.js';
|
|
12
|
+
import { type Tx } from './tx.js';
|
|
13
|
+
import { type AuthApi } from './auth.js';
|
|
14
|
+
import { type AclApi } from './acl.js';
|
|
15
|
+
import { type LoadInput, type LoadOptions, type LoadReport } from './load.js';
|
|
16
|
+
import { type Batch, type Chain, type StepFn } from './chain.js';
|
|
17
|
+
import type { QueryEvent, Row } from './types.js';
|
|
18
|
+
import { type CacheOptions, type CacheStats } from './cache.js';
|
|
19
|
+
import { Subscription, type WatchOptions } from './watch.js';
|
|
20
|
+
import { type MaintainOptions, type MaintainReport, type ModelDescription, type ResetOptions, type ResetResult, type VerifyResult } from './admin.js';
|
|
21
|
+
import type { AnyModelLike, StepsOf } from './typed.js';
|
|
22
|
+
export { DDL_REVISION } from './types.js';
|
|
23
|
+
export { uuidv5, v5Name, v5Id, idOf, type KeyedClass } from './uuid.js';
|
|
24
|
+
export { LetopisError, ValidationError, fromDbError, type Issue } from './errors.js';
|
|
25
|
+
export { Registry, type ClassInfo, type EndInfo, type LeafType } from './registry.js';
|
|
26
|
+
export { compileValidator, applyDefaults, type Validator } from './validate.js';
|
|
27
|
+
export { syncModels, generateTypes, schemaToTs, type SyncResult } from './sync.js';
|
|
28
|
+
export { ne, gt, gte, lt, lte, between, inList, like, ilike, starts, ends, has, hasAny, hasAll, exists, isNull, not, or, isOp } from './ops.js';
|
|
29
|
+
export { cursorOf } from './sql.js';
|
|
30
|
+
export { inc, isInc, type IncMarker, type WriteRow } from './write.js';
|
|
31
|
+
export { totpCode, hashPassword, verifyHash, type AuthApi, type LoginResult, type Credential } from './auth.js';
|
|
32
|
+
export type { AclApi, AclDecision, AclDataDecision, AclOp } from './acl.js';
|
|
33
|
+
export type { LoadOptions, LoadReport, LoadIssue, LoadInput } from './load.js';
|
|
34
|
+
export type { Chain, ChainCore, StepFn, BatchEntry } from './chain.js';
|
|
35
|
+
export type { ModelLike, AnyModelLike, RowOf, FilterOf, FieldFilterOf, TypedChain, StepsOf, PatchOf } from './typed.js';
|
|
36
|
+
export type { Row, Path, Filter, FieldFilter, Cursor, ChainMods, QueryEvent, Op, Scalar } from './types.js';
|
|
37
|
+
export type { CacheOptions, CacheStats } from './cache.js';
|
|
38
|
+
export type { WatchOptions, WatchEvent, Subscription } from './watch.js';
|
|
39
|
+
export type { VerifyResult, VerifyIssue, MaintainOptions, MaintainReport, ResetOptions, ResetResult, ModelDescription } from './admin.js';
|
|
40
|
+
export { describeText } from './admin.js';
|
|
41
|
+
export { up, createTenant, type UpOptions, type UpResult, type HistoryPolicy, type TenantOptions, type TenantResult } from './up.js';
|
|
42
|
+
export { RESERVED_CLASS_NAMES, CHAIN_METHODS, DB_METHODS } from './types.js';
|
|
43
|
+
/** Снесено в 1.0.0: id v7 больше не выдаются (§2.3). */
|
|
44
|
+
export declare function uuidv7(): never;
|
|
45
|
+
/** Снесено в 1.0.0: пространство имён v5 — id арендатора. Любое использование значения — ошибка. */
|
|
46
|
+
export declare const LETOPIS_NS: string;
|
|
47
|
+
export interface ConnectOptions {
|
|
48
|
+
/** Строка подключения; либо готовый пул postgres.js в `sql`. */
|
|
49
|
+
dsn?: string;
|
|
50
|
+
sql?: postgres.Sql;
|
|
51
|
+
/** Схема установки, например `v2.salon`. */
|
|
52
|
+
schema: string;
|
|
53
|
+
/** Токен сессии; либо ключ APIKEY в `apiKey` (он же `service` — ключ сервиса) — его обменяют на сессию. */
|
|
54
|
+
token?: string;
|
|
55
|
+
apiKey?: string;
|
|
56
|
+
service?: string;
|
|
57
|
+
/** Продлевать сессию раз в минуту работы (по умолчанию да, §2.9). */
|
|
58
|
+
refreshSession?: boolean;
|
|
59
|
+
/** Разрешить роль, которая обходит RLS (суперпользователь, BYPASSRLS, член роли-владельца), — администраторское подключение (§2.9). */
|
|
60
|
+
allowBypassRls?: boolean;
|
|
61
|
+
/** Имя роли-владельца (по умолчанию letopis_owner). */
|
|
62
|
+
owner?: string;
|
|
63
|
+
/** Интервал отправки отложенного сигнала, мс (по умолчанию 100; решение 9 точки А). */
|
|
64
|
+
notifyIntervalMs?: number;
|
|
65
|
+
/** Размер пула, если подключение создаёт сам connect(). */
|
|
66
|
+
max?: number;
|
|
67
|
+
/** Хук на каждый запрос цепочки (метрики, лог). */
|
|
68
|
+
onQuery?: (e: QueryEvent) => void;
|
|
69
|
+
/** Порог медленного запроса, мс: событие получает slow; без onQuery — console.warn. */
|
|
70
|
+
slowMs?: number;
|
|
71
|
+
/** Модели letopis/model — только для типов цепочек (TypedDb); описания классов берутся из базы. */
|
|
72
|
+
models?: readonly AnyModelLike[];
|
|
73
|
+
/**
|
|
74
|
+
* Слушать сигналы базы (LISTEN, по умолчанию да). false — пул в режиме транзакций (PgBouncer):
|
|
75
|
+
* реестр перечитывается через db.refresh(), подписка опрашивает журнал, кэш результатов выключен
|
|
76
|
+
* (с cache: { ttlOnly: true } — работает только по сроку).
|
|
77
|
+
*/
|
|
78
|
+
listen?: boolean;
|
|
79
|
+
/** Кэш результатов (§2.12): срок по умолчанию, размер, ttlOnly; false — выключен. */
|
|
80
|
+
cache?: CacheOptions | false;
|
|
81
|
+
/** Запускать maintain() по расписанию ('1h', '15m', мс) под advisory-блокировкой: работает один процесс. */
|
|
82
|
+
maintain?: string | number;
|
|
83
|
+
}
|
|
84
|
+
export interface DbCore {
|
|
85
|
+
readonly schema: string;
|
|
86
|
+
readonly token: string | null;
|
|
87
|
+
/** Арендатор сессии. */
|
|
88
|
+
readonly tenant: string | null;
|
|
89
|
+
readonly registry: Registry;
|
|
90
|
+
/** Креды, вход и сессии (этап 5). */
|
|
91
|
+
readonly auth: AuthApi;
|
|
92
|
+
/** Решения прав: check(endpoint), checkData(class, op) (этап 5). */
|
|
93
|
+
readonly acl: AclApi;
|
|
94
|
+
/** Сырой SQL под сессией и RLS, одной транзакцией (в db.begin() — в ней): db.sql`select …`. */
|
|
95
|
+
sql(strings: TemplateStringsArray, ...values: unknown[]): Promise<postgres.Row[]>;
|
|
96
|
+
/** Транзакция под сессией: fn получает соединение postgres.js (в db.begin() — ту же транзакцию). */
|
|
97
|
+
transaction<T>(fn: (tx: Tx) => Promise<T>): Promise<T>;
|
|
98
|
+
/** id объекта класса с ключом в арендаторе сессии. */
|
|
99
|
+
idOf(cls: string, key: Readonly<Record<string, unknown>>): string;
|
|
100
|
+
/** Перечитать описания классов. */
|
|
101
|
+
refresh(): Promise<void>;
|
|
102
|
+
/** Отправить накопленные сигналы сейчас. */
|
|
103
|
+
flushSignals(): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Проверка цепочек хэшей и якорь (хэш всех голов); { data: true } — ещё данные, концы, арендаторы,
|
|
106
|
+
* владельцы и id всех строк. Только системный администратор или администраторское подключение.
|
|
107
|
+
*/
|
|
108
|
+
verify(opts?: {
|
|
109
|
+
data?: boolean;
|
|
110
|
+
}): Promise<VerifyResult>;
|
|
111
|
+
/** Обслуживание: истёкшие сессии и коды, прореживание журнала по политике хранения, очередь сигналов. */
|
|
112
|
+
maintain(opts?: MaintainOptions): Promise<MaintainReport>;
|
|
113
|
+
/** Сброс sessions | tenant | all (allowReset установки, право letopis.reset, confirm — имя схемы). */
|
|
114
|
+
reset(opts: ResetOptions): Promise<ResetResult>;
|
|
115
|
+
/** Обрезка истории до момента: класса (с потомками), id, списка id или строк; версия 1 → запись trim. */
|
|
116
|
+
trimHistory(target: string | string[] | Row | Row[], before: string | Date): Promise<number>;
|
|
117
|
+
/** Новый ключ класса: строки семейства переносятся на новые id, ссылки переводятся. */
|
|
118
|
+
rekeyClass(cls: string, key: string[]): Promise<number>;
|
|
119
|
+
/** Машинное описание модели с метаданными классов (describeText — то же текстом, llms.txt). */
|
|
120
|
+
describe(): ModelDescription;
|
|
121
|
+
/** Подписка по курсору: for await (const ev of db.watch({ from })) …; ev.cursor — откуда продолжить. */
|
|
122
|
+
watch(opts?: WatchOptions): Subscription;
|
|
123
|
+
/** Кэш результатов подключения. */
|
|
124
|
+
readonly cache: {
|
|
125
|
+
clear(): void;
|
|
126
|
+
stats(): CacheStats;
|
|
127
|
+
};
|
|
128
|
+
/** Начать путь с готового узла: db.entity(row | цепочка). */
|
|
129
|
+
entity(x: Chain | Row): Chain;
|
|
130
|
+
/**
|
|
131
|
+
* Тот же пул от имени аккаунта (letopis.account: имперсонацию проверяет база — право сервиса
|
|
132
|
+
* auth.impersonate), в арендаторе tenant (собственный аккаунта или по членству) и с явным владельцем
|
|
133
|
+
* новых строк: await db.as(account, { tenant, owner }). account = null — тот же актор.
|
|
134
|
+
*/
|
|
135
|
+
as(account: string | {
|
|
136
|
+
id: string;
|
|
137
|
+
} | null, opts?: {
|
|
138
|
+
owner?: string;
|
|
139
|
+
tenant?: string;
|
|
140
|
+
}): Promise<Db>;
|
|
141
|
+
/** Явная транзакция read committed: те же цепочки, commit(), rollback(), lock(), forUpdate(). */
|
|
142
|
+
begin(): Promise<DbTx>;
|
|
143
|
+
/**
|
|
144
|
+
* Загрузчик (§2.6): строки любых классов — проверки в коде, COPY от роли владельца, один запрос по
|
|
145
|
+
* целям вне загрузки. Только на администраторском подключении (иначе admin_required).
|
|
146
|
+
*/
|
|
147
|
+
load(input: LoadInput, opts?: LoadOptions): Promise<LoadReport>;
|
|
148
|
+
/**
|
|
149
|
+
* Именованная очередь планов фасада: batch.Класс(…).create(…); batch.run() — одной транзакцией. У корня,
|
|
150
|
+
* у каждого db.as() и у каждой db.begin() очереди свои: план исполняется от имени фасада, который его поставил.
|
|
151
|
+
*/
|
|
152
|
+
batch(name: string): Batch;
|
|
153
|
+
/** Advisory-блокировка до конца транзакции — только в db.begin() (иначе tx_required). */
|
|
154
|
+
lock(...keys: (string | number)[]): Promise<void>;
|
|
155
|
+
/** Зафиксировать транзакцию tr (то же, что tr.commit()). */
|
|
156
|
+
commit(tr?: DbTx): Promise<void>;
|
|
157
|
+
/** Откатить транзакцию tr (то же, что tr.rollback()). */
|
|
158
|
+
rollback(tr?: DbTx): Promise<void>;
|
|
159
|
+
close(): Promise<void>;
|
|
160
|
+
}
|
|
161
|
+
/** Подключение: служебные методы и классы как стартовые шаги цепочек — db.Класс(фильтр). */
|
|
162
|
+
export type Db = DbCore & {
|
|
163
|
+
[className: string]: StepFn;
|
|
164
|
+
};
|
|
165
|
+
/** Явная транзакция db.begin(): тот же API; ошибка любого запроса её ломает (§2.5). */
|
|
166
|
+
export type DbTx = Db;
|
|
167
|
+
/** Подключение с типами шагов, строк и фильтров по моделям: connect({ models }). */
|
|
168
|
+
export type TypedDb<M extends readonly AnyModelLike[]> = DbCore & StepsOf<M> & {
|
|
169
|
+
[className: string]: StepFn;
|
|
170
|
+
};
|
|
171
|
+
export type { Batch };
|
|
172
|
+
export declare function connect<const M extends readonly AnyModelLike[]>(opts: ConnectOptions & {
|
|
173
|
+
models: M;
|
|
174
|
+
}): Promise<TypedDb<M>>;
|
|
175
|
+
export declare function connect(opts: ConnectOptions): Promise<Db>;
|