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.
Files changed (89) hide show
  1. package/AGENT-CHEATSHEET.en.md +368 -0
  2. package/AGENT-CHEATSHEET.md +354 -0
  3. package/CHANGELOG.md +348 -0
  4. package/MIGRATION.md +190 -0
  5. package/README.en.md +1937 -0
  6. package/README.md +1493 -3466
  7. package/dist/acl.d.ts +26 -50
  8. package/dist/acl.js +22 -267
  9. package/dist/admin.d.ts +138 -0
  10. package/dist/admin.js +170 -0
  11. package/dist/auth.d.ts +120 -73
  12. package/dist/auth.js +121 -306
  13. package/dist/cache.d.ts +73 -0
  14. package/dist/cache.js +148 -0
  15. package/dist/chain.d.ts +124 -191
  16. package/dist/chain.js +369 -551
  17. package/dist/cli.d.ts +2 -0
  18. package/dist/cli.js +164 -0
  19. package/dist/demo/booking.d.ts +289 -0
  20. package/dist/demo/booking.js +159 -0
  21. package/dist/errors.d.ts +29 -0
  22. package/dist/errors.js +70 -0
  23. package/dist/import.d.ts +179 -0
  24. package/dist/import.js +792 -0
  25. package/dist/index.d.ts +172 -26
  26. package/dist/index.js +304 -178
  27. package/dist/jsonschema.d.ts +22 -0
  28. package/dist/jsonschema.js +167 -0
  29. package/dist/load.d.ts +76 -0
  30. package/dist/load.js +884 -0
  31. package/dist/model.d.ts +166 -0
  32. package/dist/model.js +224 -0
  33. package/dist/ops.d.ts +7 -6
  34. package/dist/ops.js +7 -51
  35. package/dist/pglite.d.ts +22 -0
  36. package/dist/pglite.js +45 -0
  37. package/dist/registry.d.ts +57 -0
  38. package/dist/registry.js +82 -0
  39. package/dist/sql.d.ts +59 -142
  40. package/dist/sql.js +568 -654
  41. package/dist/sync.d.ts +31 -0
  42. package/dist/sync.js +108 -0
  43. package/dist/tx.d.ts +129 -8
  44. package/dist/tx.js +300 -73
  45. package/dist/typed.d.ts +97 -0
  46. package/dist/typed.js +1 -0
  47. package/dist/types.d.ts +71 -250
  48. package/dist/types.js +27 -108
  49. package/dist/up.d.ts +140 -47
  50. package/dist/up.js +339 -267
  51. package/dist/uuid.d.ts +21 -6
  52. package/dist/uuid.js +48 -64
  53. package/dist/validate.d.ts +24 -0
  54. package/dist/validate.js +251 -0
  55. package/dist/watch.d.ts +62 -0
  56. package/dist/watch.js +168 -0
  57. package/dist/write.d.ts +117 -74
  58. package/dist/write.js +658 -720
  59. package/llms.txt +26 -0
  60. package/package.json +49 -19
  61. package/sql/10-core.sql +136 -0
  62. package/sql/15-errors.sql +60 -0
  63. package/sql/20-context.sql +153 -0
  64. package/sql/30-validate.sql +423 -0
  65. package/sql/40-class.sql +259 -0
  66. package/sql/50-acl.sql +539 -0
  67. package/sql/60-write.sql +1369 -0
  68. package/sql/70-read.sql +245 -0
  69. package/sql/80-auth.sql +827 -0
  70. package/sql/90-time.sql +957 -0
  71. package/sql/95-seed.system.sql +178 -0
  72. package/sql/99-revision.sql +3 -0
  73. package/sql/README.md +56 -0
  74. package/sql/seed.booking.sql +39 -112
  75. package/dist/schema.d.ts +0 -15
  76. package/dist/schema.js +0 -351
  77. package/dist/sessions.d.ts +0 -32
  78. package/dist/sessions.js +0 -114
  79. package/dist/tables.d.ts +0 -105
  80. package/dist/tables.js +0 -248
  81. package/docker/Dockerfile +0 -40
  82. package/docker/start.sh +0 -18
  83. package/scripts/check-docs.mjs +0 -375
  84. package/scripts/gen-api-contract.mjs +0 -226
  85. package/scripts/gen-types.mjs +0 -350
  86. package/scripts/release-notes.mjs +0 -76
  87. package/scripts/schema-sync.mjs +0 -185
  88. package/sql/ddl.sql +0 -600
  89. package/sql/seed.auth.sql +0 -73
package/dist/up.d.ts CHANGED
@@ -1,56 +1,149 @@
1
- import type { EntityDb } from './chain.js';
2
- import type { ConnectOpts } from './types.js';
3
- export interface UpOpts extends Omit<ConnectOpts, 'dsn' | 'schema'> {
4
- /** postgres://user:pass@host:port/db. Default postgres://postgres:test@localhost:15432/letopis. */
5
- dsn?: string;
6
- /** Базовое имя схемы БЕЗ версии и точек (напр. 'booking'). */
1
+ import postgres from 'postgres';
2
+ import { type PgliteOptions, type PgliteServer } from './pglite.js';
3
+ export declare const SYSTEM_ID = "2eba6d0a-1edd-4bb6-a85a-a703dab49035";
4
+ export declare const SCHEMA_VERSION = "v2";
5
+ export interface InstallOptions {
6
+ /** Полное имя схемы с версией, например `v2.salon`. */
7
7
  schema: string;
8
- /** Версия движка: итоговая PG-схема "v<N>.<schema>". Бамп руками при breaking-изменении DDL. */
9
- version: number;
10
- /** Имя dev-контейнера. Default 'letopis-timescale'. */
11
- container?: string;
12
- /** Имя docker-образа; при отсутствии соберётся из пакованного Dockerfile. Default 'letopis-db'. */
13
- image?: string;
14
- /**
15
- * Где держать данные PG: путь на хосте (bind mount, на Windows/NTFS — на свой риск)
16
- * либо имя docker-volume. Default — named volume 'letopis-pgdata' (кроссплатформенно;
17
- * переживает пересоздание контейнера).
18
- */
19
- dataDir?: string;
20
- /** Хост-порт Redis контейнера. Default 16379. */
21
- redisPort?: number;
8
+ owner?: string;
9
+ app?: string;
10
+ /** Константа установки: разрешён ли reset (план, §2.2). По умолчанию выключен. */
11
+ allowReset?: boolean;
22
12
  /**
23
- * Сиды после ddl: массив путей — свои файлы (маркер "<SCHEMA-NAME>" в них поддержан);
24
- * default — демо booking + auth. Свой сид должен дать хотя бы один класс в Schema
25
- * (иначе connect в конце честно упадёт «has no classes»); false — голая структура
26
- * без сидов, годится только чтобы поставить движок — connect не переживёт.
13
+ * Константа установки: политика хранения истории для классов без своей (план, §2.11), например
14
+ * `{ all: '1 day', daily: '1 week', weekly: '1 month', monthly: '1 year', yearly: 'forever' }`.
15
+ * Не задана — история хранится вся.
27
16
  */
28
- seeds?: string[] | false;
29
- /** Дропнуть схему и накатить заново. ДАННЫЕ СХЕМЫ ТЕРЯЮТСЯ. */
17
+ history?: HistoryPolicy;
18
+ /** Номер последнего накатываемого файла — для пошаговых тестов. */
19
+ upTo?: number;
20
+ /** Сиды после ядра: имена lib/sql/seed.<имя>.sql (например 'booking') или пути к своим файлам .sql. */
21
+ seeds?: string[];
22
+ /** Обновление (upgrade): ревизия схемы до наката — миграции lib/sql/migrate/ с номером выше неё. */
23
+ migrateFrom?: number;
24
+ /** Каталог миграций (по умолчанию lib/sql/migrate). */
25
+ migrationsDir?: string;
26
+ /** Свой ключ сервиса: зарегистрировать, если такого ещё нет (вместо выпуска случайного). */
27
+ serviceKey?: string;
28
+ }
29
+ /** Политика хранения истории (§2.11): сроки ярусов по возрастанию, 'forever' — бессрочно. */
30
+ export interface HistoryPolicy {
31
+ all: string;
32
+ daily?: string;
33
+ weekly?: string;
34
+ monthly?: string;
35
+ yearly?: string;
36
+ /** Часовой пояс границ периодов (по умолчанию UTC). */
37
+ tz?: string;
38
+ }
39
+ export interface InstallResult {
40
+ schema: string;
41
+ owner: string;
42
+ app: string;
43
+ /** Ключ сервисного аккаунта; выдаётся только при первой установке (или зарегистрированный свой), дальше — null. */
44
+ serviceKey: string | null;
45
+ /** Применённые миграции. */
46
+ migrations: string[];
47
+ }
48
+ export declare const quoteIdent: (name: string) => string;
49
+ /** Файлы ядра по номеру: `10-core.sql` … `99-revision.sql`; сиды демо-домена сюда не входят. */
50
+ export declare function engineFiles(upTo?: number): Promise<string[]>;
51
+ export declare function substitute(text: string, vars: Record<string, string>): string;
52
+ export declare function install(sql: postgres.Sql, opts: InstallOptions): Promise<InstallResult>;
53
+ /** Миграции с номером выше ревизии from и не выше DDL_REVISION: `0004-описание.sql`, по номеру. */
54
+ export declare function migrationFiles(dir: string, from: number): Promise<string[]>;
55
+ export interface UpOptions extends Omit<InstallOptions, 'schema' | 'upTo' | 'migrateFrom'> {
56
+ /** Администраторская строка подключения (роль-установщик). */
57
+ dsn?: string;
58
+ /** Готовый пул postgres.js вместо dsn (база уже существует). */
59
+ sql?: postgres.Sql;
60
+ /** Схема: полное имя v2.<имя> или только <имя> — версия структуры подставится сама. */
61
+ schema: string;
62
+ /** Удалить схему и поставить заново. ДАННЫЕ СХЕМЫ ТЕРЯЮТСЯ. */
30
63
  fresh?: boolean;
31
- /**
32
- * Перекатить `ddl.sql` на СУЩЕСТВУЮЩУЮ схему (сиды не трогаются, данные целы).
33
- * Так доезжают аддитивные правки движка: схема, накатанная старой либой, не имеет новых
34
- * функций/триггеров (например `purge`/`purge_account` из 0.19.0) и падает сырым
35
- * «function … does not exist». О расхождении предупреждает `connect()` (см. `DDL_REVISION`).
36
- * Идемпотентно; на несуществующей схеме — обычный первый накат.
37
- */
64
+ /** Обновить схему отставшей ревизии: миграции и повторный накат; данные сохраняются. */
38
65
  upgrade?: boolean;
39
- /** Без console.log-прогресса. */
66
+ /** Без сообщений в консоль. */
40
67
  quiet?: boolean;
41
- /** Максимум ожидания готовности, мс. Default 120 000 (первый запуск: pull образа + initdb). */
68
+ /** Сколько ждать базу, мс (по умолчанию 60 000). */
42
69
  waitTimeoutMs?: number;
70
+ /**
71
+ * База для разработки без PostgreSQL (решение 6 точки А): PGlite с pgcrypto через pglite-socket;
72
+ * одно соединение — connect({ dsn: r.pglite.dsn, listen: false, max: 1 }); не для гонок и CI.
73
+ */
74
+ pglite?: boolean | PgliteOptions;
75
+ /** Арендатор и его первый пользователь — без своего сида (createTenant). */
76
+ tenant?: TenantOptions;
77
+ }
78
+ export interface UpResult extends InstallResult {
79
+ /** Схемы не было — поставлена. */
80
+ created: boolean;
81
+ /** Схема была отставшей ревизии — обновлена. */
82
+ upgraded: boolean;
83
+ /** Ревизия движка после наката. */
84
+ revision: number;
85
+ /** Таблицы, для которых выполнен ANALYZE (статистики не было). */
86
+ analyzed: string[];
87
+ /** up({ pglite }): запущенный PGlite — строка подключения и остановка. */
88
+ pglite?: PgliteServer;
89
+ /** up({ tenant }): арендатор (и его первый пользователь с сессией). */
90
+ tenant?: TenantResult;
91
+ }
92
+ type Ping = {
93
+ ok: true;
94
+ } | {
95
+ ok: false;
96
+ kind: 'no-server' | 'no-database' | 'starting' | 'fatal';
97
+ err: unknown;
98
+ };
99
+ /** Проба сервера: ok | нет сервера | нет базы | запускается | роковая ошибка (неверный пароль). */
100
+ export declare function pgPing(dsn: string): Promise<Ping>;
101
+ /** Создать базу строки подключения, если её нет (гонка параллельных up() — 42P04 — не ошибка). */
102
+ export declare function ensureDatabase(dsn: string, log?: (m: string) => void): Promise<boolean>;
103
+ /** Версия сервера и кодировка базы: PostgreSQL 18+ и UTF8 (casefold и pg_unicode_fast требуют UTF8). */
104
+ export declare function checkServer(versionNum: number, encoding: string): void;
105
+ /** Ревизия движка схемы по комментарию 'letopis ddl_revision=N'; схемы нет — null. */
106
+ export declare function schemaRevision(sql: postgres.Sql, schema: string): Promise<number | null>;
107
+ /**
108
+ * Поставить или обновить установку letopis. Схема есть и её ревизия совпадает — повторный накат
109
+ * (идемпотентный); ревизия отстала — только с upgrade: true; новее библиотеки — отказ.
110
+ */
111
+ export declare function up(opts: UpOptions): Promise<UpResult>;
112
+ export interface TenantOptions {
113
+ /** Имя арендатора (аккаунт в System; id — v5 от «tenant:<имя>», как у letopis import --tenant). */
114
+ name: string;
115
+ /** Правило арендатора «аутентифицированным можно всё» (READ, WRITE, DELETE; по умолчанию да). */
116
+ grantAll?: boolean;
117
+ /** Первый пользователь: аккаунт, членство в арендаторе с ролями roles, пароль и сессия в арендаторе. */
118
+ user?: {
119
+ name: string;
120
+ login: string;
121
+ password: string;
122
+ kind?: string;
123
+ ttl?: string;
124
+ /** Роли членства (по умолчанию ['owner']); роли уже существующего членства повтор не меняет. */
125
+ roles?: string[];
126
+ };
43
127
  }
44
- export interface RunCfg {
45
- container: string;
46
- image: string;
47
- pgPort: string;
48
- redisPort: number;
49
- user: string;
50
- password: string;
51
- database: string;
52
- dataDir?: string;
128
+ export interface TenantResult {
129
+ /** id аккаунта-арендатора. */
130
+ tenant: string;
131
+ /** id аккаунта пользователя (если задан). */
132
+ user: string | null;
133
+ /** Токен сессии пользователя в арендаторе: connect({ token }) (если задан пользователь). */
134
+ token: string | null;
135
+ /** Арендатор создан этим вызовом (повтор с тем же именем — false). */
136
+ created: boolean;
53
137
  }
54
- /** argv для docker run (чистая функция — покрыта юнитом). dataDir: путь → bind, имя → volume. */
55
- export declare function dockerRunArgs(cfg: RunCfg): string[];
56
- export declare function up(opts: UpOpts): Promise<EntityDb>;
138
+ /**
139
+ * Арендатор и его первый пользователь — то, что раньше делал свой сид функциями владельца
140
+ * (sys_create, sys_grant_all). Нужно администраторское подключение (роль может стать владельцем);
141
+ * всё — одной транзакцией от владельца. Повтор с тем же именем и логином ничего не дублирует:
142
+ * id — v5 от имени и логина, существующие строки пропускаются (пароль и роли членства не меняются),
143
+ * сессия выдаётся заново. Удалённые арендатор, аккаунт пользователя или членство (строки нет, а
144
+ * журнал id есть) — отказ invalid_data, транзакция откатывается целиком: повтор не воскрешает то,
145
+ * что удалил администратор (up({ tenant }) идёт при каждом запуске), а sys_create пишет только
146
+ * версию 1 — её занимает история; вернуть строку — restore() цепочкой.
147
+ */
148
+ export declare function createTenant(sql: postgres.Sql, schema: string, opts: TenantOptions, owner?: string): Promise<TenantResult>;
149
+ export {};