letopis 1.4.2 → 3.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 (123) hide show
  1. package/AGENT-CHEATSHEET.md +516 -398
  2. package/CHANGELOG.md +739 -0
  3. package/LICENSE +75 -21
  4. package/LICENSE-COMMERCIAL.md +49 -0
  5. package/README.md +1312 -1190
  6. package/api-contract.json +381 -0
  7. package/dist/acl.d.ts +81 -1
  8. package/dist/acl.js +281 -13
  9. package/dist/admin.d.ts +11 -141
  10. package/dist/admin.js +28 -186
  11. package/dist/auth.d.ts +20 -5
  12. package/dist/auth.js +80 -21
  13. package/dist/cache.d.ts +8 -1
  14. package/dist/cache.js +30 -8
  15. package/dist/chain.d.ts +46 -48
  16. package/dist/chain.js +556 -223
  17. package/dist/cli.js +73 -96
  18. package/dist/demo/booking.d.ts +352 -36
  19. package/dist/describe.d.ts +47 -0
  20. package/dist/describe.js +195 -0
  21. package/dist/errors.d.ts +77 -13
  22. package/dist/errors.js +231 -30
  23. package/dist/index.d.ts +62 -74
  24. package/dist/index.js +312 -155
  25. package/dist/internal.d.ts +7 -0
  26. package/dist/jsonschema.js +18 -17
  27. package/dist/load.d.ts +29 -17
  28. package/dist/load.js +235 -190
  29. package/dist/log.d.ts +121 -0
  30. package/dist/log.js +633 -0
  31. package/dist/mcp.d.ts +5 -7
  32. package/dist/mcp.js +194 -225
  33. package/dist/messages/access.d.ts +90 -0
  34. package/dist/messages/access.js +113 -0
  35. package/dist/messages/api.d.ts +237 -0
  36. package/dist/messages/api.js +304 -0
  37. package/dist/messages/boot.d.ts +201 -0
  38. package/dist/messages/boot.js +256 -0
  39. package/dist/messages/codes.d.ts +172 -0
  40. package/dist/messages/codes.js +173 -0
  41. package/dist/messages/index.d.ts +98 -0
  42. package/dist/messages/index.js +121 -0
  43. package/dist/messages/log.d.ts +229 -0
  44. package/dist/messages/log.js +102 -0
  45. package/dist/messages/mcp.d.ts +306 -0
  46. package/dist/messages/mcp.js +387 -0
  47. package/dist/messages/model.d.ts +256 -0
  48. package/dist/messages/model.js +314 -0
  49. package/dist/messages/query.d.ts +141 -0
  50. package/dist/messages/query.js +171 -0
  51. package/dist/messages/sql-access.d.ts +70 -0
  52. package/dist/messages/sql-access.js +87 -0
  53. package/dist/messages/sql-core.d.ts +164 -0
  54. package/dist/messages/sql-core.js +198 -0
  55. package/dist/messages/sql-time.d.ts +86 -0
  56. package/dist/messages/sql-time.js +111 -0
  57. package/dist/messages/sql-write.d.ts +246 -0
  58. package/dist/messages/sql-write.js +270 -0
  59. package/dist/messages/time.d.ts +23 -0
  60. package/dist/messages/time.js +29 -0
  61. package/dist/messages/types.d.ts +27 -0
  62. package/dist/messages/types.js +5 -0
  63. package/dist/messages/write.d.ts +452 -0
  64. package/dist/messages/write.js +572 -0
  65. package/dist/model.d.ts +77 -60
  66. package/dist/model.js +43 -34
  67. package/dist/ops.d.ts +35 -0
  68. package/dist/ops.js +101 -0
  69. package/dist/pglite.d.ts +0 -9
  70. package/dist/pglite.js +3 -1
  71. package/dist/registry.d.ts +3 -19
  72. package/dist/registry.js +3 -16
  73. package/dist/signals.d.ts +1 -5
  74. package/dist/signals.js +1 -5
  75. package/dist/sql.d.ts +9 -1
  76. package/dist/sql.js +175 -107
  77. package/dist/sync.d.ts +10 -4
  78. package/dist/sync.js +90 -17
  79. package/dist/tx.d.ts +21 -2
  80. package/dist/tx.js +76 -13
  81. package/dist/typed.d.ts +252 -53
  82. package/dist/types.d.ts +93 -90
  83. package/dist/types.js +17 -14
  84. package/dist/up.d.ts +56 -35
  85. package/dist/up.js +229 -83
  86. package/dist/uuid.d.ts +8 -0
  87. package/dist/uuid.js +14 -6
  88. package/dist/validate.d.ts +13 -1
  89. package/dist/validate.js +82 -33
  90. package/dist/watch.d.ts +10 -16
  91. package/dist/watch.js +36 -77
  92. package/dist/write.d.ts +87 -17
  93. package/dist/write.js +441 -206
  94. package/llms.txt +48 -31
  95. package/package.json +13 -14
  96. package/sql/10-core.sql +7 -50
  97. package/sql/15-errors.sql +64 -10
  98. package/sql/20-context.sql +18 -9
  99. package/sql/30-validate.sql +79 -30
  100. package/sql/40-class.sql +41 -115
  101. package/sql/50-acl.sql +8 -13
  102. package/sql/60-write.sql +220 -676
  103. package/sql/70-read.sql +11 -13
  104. package/sql/80-auth.sql +109 -42
  105. package/sql/90-time.sql +108 -947
  106. package/sql/95-seed.system.sql +7 -14
  107. package/sql/99-revision.sql +6 -1
  108. package/sql/README.md +32 -24
  109. package/sql/migrate/0009-restore-rev.tenants-name.sql +10 -0
  110. package/sql/migrate/0010-impersonation-no-account.sql +5 -0
  111. package/sql/migrate/0011-key-lock.otp-enabled.sql +7 -0
  112. package/sql/migrate/README.md +18 -0
  113. package/AGENT-CHEATSHEET.en.md +0 -488
  114. package/MIGRATION.md +0 -190
  115. package/README.en.md +0 -2910
  116. package/dist/import.d.ts +0 -185
  117. package/dist/import.js +0 -820
  118. package/dist/project.d.ts +0 -359
  119. package/dist/project.js +0 -1258
  120. package/sql/75-history.sql +0 -436
  121. package/sql/88-derived.sql +0 -1236
  122. package/sql/migrate/0006-changed-paths.sql +0 -3
  123. package/sql/migrate/0007-secret-account-fk.sql +0 -12
package/dist/types.js CHANGED
@@ -3,10 +3,15 @@
3
3
  */
4
4
  /**
5
5
  * Ревизия схемы, которую знает эта версия пакета, — номер версии SQL-части letopis (таблиц и функций в схеме установки).
6
- * После `up()` у схемы та же ревизия (`r.revision`); схему отставшей ревизии `up()` обновляет только с `upgrade: true`,
7
- * а `connect()` о ней предупреждает.
6
+ * После `up()` у схемы та же ревизия (`r.revision`); схему отставшей ревизии 2.x `up()` обновляет только с
7
+ * `upgrade: true`, а `connect()` о ней предупреждает.
8
8
  */
9
- export const DDL_REVISION = 7;
9
+ export const DDL_REVISION = 11;
10
+ /**
11
+ * Префикс версии в имени схемы `v<N>.<имя>`: `up({ schema: 'salon' })` и `connect({ schema: 'salon' })` дописывают его к
12
+ * имени без точки — `v2.salon`.
13
+ */
14
+ export const SCHEMA_VERSION = 'v2';
10
15
  /**
11
16
  * Классы, строки которых меняют права и схему: их запись повышает счётчик прав (загрузчик), а сигнал
12
17
  * сбрасывает весь кэш результатов и пропуска прав. Тот же список — в триггерах базы (60-write.sql).
@@ -16,28 +21,26 @@ export const ACL_CLASS_NAMES = ['rule', 'Resource', 'member', 'Account', 'Class'
16
21
  // Методы цепочки — единственный источник зарезервированных имён (план, §2.14, этап 3, п. 10)
17
22
  // ---------------------------------------------------------------------------
18
23
  /**
19
- * Имена методов цепочки: модификаторы, терминалы, глаголы записи и слоты концов, а также `then` и снятые методы прежних
20
- * версий. После шага цепочки эти имена библиотека не ищет среди классов; все они входят в `RESERVED_CLASS_NAMES`.
24
+ * Имена методов цепочки: модификаторы, терминалы, глаголы записи и слоты концов, а также `then`. После шага цепочки эти
25
+ * имена библиотека не ищет среди классов; все они входят в `RESERVED_CLASS_NAMES`.
21
26
  */
22
27
  export const CHAIN_METHODS = [
23
28
  'then', 'entity', 'paths', 'rows', 'first', 'ids', 'count', 'limit', 'offset', 'sort', 'asOf', 'withDeleted',
24
29
  'deep', 'exact', 'sum', 'avg', 'min', 'max', 'countBy', 'after', 'versions', 'create', 'update', 'upsert', 'set',
25
- 'unset', 'add', 'remove', 'delete', 'anonymize', 'reclass', 'restore', 'purge', 'alias', 'tags', 'owner',
26
- 'forUpdate', 'cache', 'rekey', 'run', 'execute', 'account', 'diff', 'blame',
30
+ 'unset', 'add', 'remove', 'delete', 'restore', 'alias', 'tags', 'owner', 'forUpdate', 'cache',
27
31
  ];
28
32
  /** Свойства корня db (и транзакции db.begin()). */
29
33
  export const DB_METHODS = [
30
- 'as', 'begin', 'commit', 'rollback', 'lock', 'batch', 'watch', 'close', 'registry', 'sql', 'load', 'verify',
31
- 'maintain', 'reset', 'describe', 'auth', 'acl', 'idOf', 'refresh', 'transaction', 'flushSignals', 'schema',
32
- 'token', 'tenant', 'reloadSchema', 'accounts', 'credentials', 'resources', 'rules', 'compact',
33
- 'trimHistory', 'rekeyClass', 'cache', 'projector', 'rebuildAggregates',
34
+ 'as', 'begin', 'commit', 'rollback', 'lock', 'batch', 'watch', 'close', 'registry', 'sql', 'load',
35
+ 'maintain', 'auth', 'acl', 'idOf', 'refresh', 'transaction', 'flushSignals', 'schema', 'token', 'tenant', 'cache',
34
36
  ];
35
37
  /** Свойства батча db.batch(name). */
36
- export const BATCH_METHODS = ['discard', 'size'];
38
+ export const BATCH_METHODS = ['run', 'discard', 'size'];
37
39
  /**
38
40
  * Имена методов цепочки, корня `db` и батча. Там, где имя занято методом, библиотека не ищет его среди классов, и шаг с
39
- * таким именем до класса не дойдёт; класс-связь (`link`) с таким именем база не создаст (`invalid_class`). Не давайте
40
- * классам эти имена.
41
+ * таким именем до класса не дойдёт. Хаб с таким именем отклоняют `hub()`, `syncModels` и база, связь (`link`) — база
42
+ * (`invalid_class`; план 2.0, этап 4, п. 2); хаб, заведённый мимо проверки базы, `up()` оставляет и называет в
43
+ * предупреждении.
41
44
  */
42
45
  export const RESERVED_CLASS_NAMES = [...new Set([...CHAIN_METHODS, ...DB_METHODS, ...BATCH_METHODS])];
43
46
  /** Метка операторов фильтра (символ не пересекается с данными). */
package/dist/up.d.ts CHANGED
@@ -1,24 +1,26 @@
1
1
  import postgres from 'postgres';
2
+ import { SCHEMA_VERSION, type LogOptions } from './types.js';
2
3
  import { type PgliteOptions, type PgliteServer } from './pglite.js';
3
4
  import { type SignalMode } from './signals.js';
4
5
  export declare const SYSTEM_ID = "2eba6d0a-1edd-4bb6-a85a-a703dab49035";
5
- export declare const SCHEMA_VERSION = "v2";
6
+ export { SCHEMA_VERSION };
7
+ /**
8
+ * Первая ревизия движка 2.0 (план 2.0, редакция 2): схема ниже неё — letopis 1.x или схема без штампа ревизии. Её
9
+ * `up()` не обновляет, а `connect()` к ней не подключается: 2.0 ставится только заново (`up({ fresh: true })`), данные
10
+ * 1.x не переносятся. Накат миграций `up({ upgrade })` — в пределах 2.x, от этой ревизии до `DDL_REVISION`.
11
+ */
12
+ export declare const FIRST_REVISION = 8;
13
+ /**
14
+ * Отказ на схеме letopis 1.x (план 2.0, 7.10 №5): ревизия из комментария схемы ниже `FIRST_REVISION` — 7 и ниже у 1.x,
15
+ * 0 — штампа ревизии нет. `up()` зовёт её до любых изменений (до общей части `install()`), `connect()` — до входа по
16
+ * ключу: функции схемы 1.x не вызываются.
17
+ */
18
+ export declare function refuse1x(schema: string, rev: number): void;
6
19
  export interface InstallOptions {
7
20
  /** Полное имя схемы с версией, например `v2.salon`. */
8
21
  schema: string;
9
22
  owner?: string;
10
23
  app?: string;
11
- /**
12
- * Разрешить `db.reset()` и `maintain({ now })` — для тестовых установок и стендов; по умолчанию запрещено. Значение
13
- * задаётся при установке и хранится в схеме: каждый `up()` записывает его заново (план, §2.2).
14
- */
15
- allowReset?: boolean;
16
- /**
17
- * Политика хранения истории для классов без своей, например
18
- * `{ all: '1 day', daily: '1 week', weekly: '1 month', monthly: '1 year', yearly: 'forever' }`; не задана — история
19
- * хранится вся. Значение задаётся при установке и хранится в схеме: каждый `up()` записывает его заново (план, §2.11).
20
- */
21
- history?: HistoryPolicy;
22
24
  /** Номер последнего накатываемого файла — для пошаговых тестов. */
23
25
  upTo?: number;
24
26
  /** Сиды после ядра: имена lib/sql/seed.<имя>.sql (например 'booking') или пути к своим файлам .sql. */
@@ -37,20 +39,10 @@ export interface InstallOptions {
37
39
  /**
38
40
  * Что видно в сигналах базы (`NOTIFY`): `'class'` (у новой схемы по умолчанию) — имя класса; `'tenant'` — имя класса и
39
41
  * псевдоним арендатора (токен); `'opaque'` — только псевдонимы класса и арендатора; `'none'` — сигналов нет.
40
- * Режим хранится в схеме: `up()` без опции его не меняет, `reset({ all })` сохраняет (план 1.1, §2.2).
42
+ * Режим хранится в схеме: `up()` без опции его не меняет.
41
43
  */
42
44
  signals?: SignalMode;
43
45
  }
44
- /** Политика хранения истории (§2.11): сроки ярусов по возрастанию, 'forever' — бессрочно. */
45
- export interface HistoryPolicy {
46
- all: string;
47
- daily?: string;
48
- weekly?: string;
49
- monthly?: string;
50
- yearly?: string;
51
- /** Часовой пояс границ периодов (по умолчанию UTC). */
52
- tz?: string;
53
- }
54
46
  export interface InstallResult {
55
47
  schema: string;
56
48
  owner: string;
@@ -75,8 +67,9 @@ export interface EngineStamp {
75
67
  sql: string;
76
68
  }
77
69
  /**
78
- * Штамп движка этого пакета. Хэш — по исходному тексту файлов ядра до подстановок (переводы строк — LF): одна и та же
79
- * сборка даёт один штамп при любых опциях установки, а версия пакета без правок SQL штамп не меняет.
70
+ * Штамп движка этого пакета. Хэш — по исходному тексту файлов ядра до подстановок (переводы строк — LF) и по каталогу
71
+ * сообщений базы (разделы sql-*, подстановка @MESSAGES@): одна и та же сборка даёт один штамп при любых опциях
72
+ * установки, а версия пакета без правок SQL и этих разделов штамп не меняет.
80
73
  */
81
74
  export declare function engineStamp(): Promise<EngineStamp>;
82
75
  /** Сравнение версий semver (метаданные сборки не учитываются): меньше нуля, ноль, больше нуля. */
@@ -92,7 +85,7 @@ export declare function install(sql: postgres.Sql, opts: InstallOptions): Promis
92
85
  }>;
93
86
  /** Миграции с номером выше ревизии from и не выше DDL_REVISION: `0004-описание.sql`, по номеру. */
94
87
  export declare function migrationFiles(dir: string, from: number): Promise<string[]>;
95
- export interface UpOptions extends Omit<InstallOptions, 'schema' | 'upTo' | 'migrateFrom'> {
88
+ export interface UpOptions extends Omit<InstallOptions, 'schema' | 'upTo' | 'migrateFrom'>, LogOptions {
96
89
  /** Администраторская строка подключения (роль-установщик). */
97
90
  dsn?: string;
98
91
  /** Готовый пул postgres.js вместо dsn (база уже существует). */
@@ -101,14 +94,14 @@ export interface UpOptions extends Omit<InstallOptions, 'schema' | 'upTo' | 'mig
101
94
  schema: string;
102
95
  /** Удалить схему и поставить заново. ДАННЫЕ СХЕМЫ ТЕРЯЮТСЯ. */
103
96
  fresh?: boolean;
104
- /** Обновить схему отставшей ревизии: миграции и повторный накат; данные сохраняются. */
97
+ /** Обновить схему отставшей ревизии 2.x: миграции и повторный накат; данные сохраняются. */
105
98
  upgrade?: boolean;
106
99
  /** Без сообщений в консоль. */
107
100
  quiet?: boolean;
108
101
  /** Сколько ждать базу, мс (по умолчанию 60 000). */
109
102
  waitTimeoutMs?: number;
110
103
  /**
111
- * Запустить PGlite — PostgreSQL прямо в процессе Node — для разработки без своего сервера (решение 6 точки А);
104
+ * Запустить PGlite — PostgreSQL прямо в процессе Node — для разработки без своего сервера;
112
105
  * подключение к нему — `connect({ dsn: r.pglite.dsn, schema: r.schema, listen: false, max: 1, allowBypassRls: true })`.
113
106
  * Соединение у PGlite одно, поэтому одновременные транзакции и гонки на нём не проверить: для таких тестов и в CI нужен
114
107
  * настоящий PostgreSQL.
@@ -119,6 +112,19 @@ export interface UpOptions extends Omit<InstallOptions, 'schema' | 'upTo' | 'mig
119
112
  * кладёт итог в `r.tenant` — свой сид для этого не нужен.
120
113
  */
121
114
  tenant?: TenantOptions;
115
+ /**
116
+ * Роль приложения с логином (план 2.0, этап 3): заводится или получает новый пароль и членство в роли приложения
117
+ * (`letopis_app`). Имя и пароль квотирует база (`format` с `%I` и `%L`). Привилегированную роль — суперпользователя,
118
+ * с `CREATEROLE`, `CREATEDB`, `REPLICATION`, `BYPASSRLS`, роль-владельца или её члена — up() не трогает
119
+ * (`invalid_data`). Строка подключения роли — `r.login.dsn`: с ней и `connect({ admin })` малое приложение работает
120
+ * одним процессом.
121
+ */
122
+ login?: LoginOptions;
123
+ }
124
+ /** Роль приложения up({ login }). */
125
+ export interface LoginOptions {
126
+ user: string;
127
+ password: string;
122
128
  }
123
129
  export interface UpResult extends InstallResult {
124
130
  /** Схемы не было — поставлена. */
@@ -127,13 +133,28 @@ export interface UpResult extends InstallResult {
127
133
  upgraded: boolean;
128
134
  /** Ревизия движка после наката. */
129
135
  revision: number;
130
- /** Таблицы, для которых выполнен ANALYZE (статистики не было). */
136
+ /**
137
+ * Таблицы, у которых статистики не было и ANALYZE от роли владельца её собрал; оставшиеся без статистики — в
138
+ * `warnings`.
139
+ */
131
140
  analyzed: string[];
132
141
  /** up({ pglite }): запущенный PGlite — строка подключения и остановка. */
133
142
  pglite?: PgliteServer;
134
143
  /** up({ tenant }): арендатор (и его первый пользователь с сессией). */
135
144
  tenant?: TenantResult;
136
- /** Предупреждения (версия сервера); без quiet каждое уже напечатано через console.warn. */
145
+ /**
146
+ * up({ login }): роль приложения — заведена (`created`) или получила новый пароль; `dsn` — строка подключения роли
147
+ * (из `dsn` установки или PGlite; при готовом пуле `sql` её нет).
148
+ */
149
+ login?: {
150
+ user: string;
151
+ created: boolean;
152
+ dsn?: string;
153
+ };
154
+ /**
155
+ * Предупреждения (версия сервера, таблицы без статистики, хабы с зарезервированными именами); без quiet каждое уже
156
+ * напечатано через console.warn.
157
+ */
137
158
  warnings: string[];
138
159
  }
139
160
  type Ping = {
@@ -152,18 +173,19 @@ export declare function ensureDatabase(dsn: string, log?: (m: string) => void):
152
173
  * иначе отказ. Возвращает предупреждения: с чем установка работает, но рискует.
153
174
  */
154
175
  export declare function checkServer(versionNum: number, encoding: string): string[];
155
- /** Ревизия движка схемы по комментарию 'letopis ddl_revision=N'; схемы нет — null. */
176
+ /** Ревизия движка схемы по комментарию 'letopis ddl_revision=N'; схемы нет — null, штампа ревизии нет — 0. */
156
177
  export declare function schemaRevision(sql: Pick<postgres.Sql, 'unsafe'>, schema: string): Promise<number | null>;
157
178
  /**
158
179
  * Ставит или обновляет установку letopis в схеме. Если схема уже есть и её ревизия та же, что у пакета, `up()` выполняет
159
180
  * повторный накат: заново ставит функции, не трогая данные, — поэтому его можно вызывать при каждом запуске приложения.
160
- * Схему отставшей ревизии `up()` обновляет только с `upgrade: true`, а на схеме новее пакета отказывает.
181
+ * Схему отставшей ревизии 2.x `up()` обновляет только с `upgrade: true`, а на схеме новее пакета отказывает. Схему без
182
+ * штампа ревизии не трогает и отказывает (`invalid_data`): заново её ставит `up({ fresh: true })`.
161
183
  */
162
184
  export declare function up(opts: UpOptions): Promise<UpResult>;
163
185
  export interface TenantOptions {
164
186
  /**
165
187
  * Имя арендатора — его аккаунта в System. Из имени вычисляется id арендатора, поэтому одно имя — всегда один и тот же
166
- * арендатор (так же его находит `letopis import --tenant`).
188
+ * арендатор.
167
189
  */
168
190
  name: string;
169
191
  /** Правило арендатора «аутентифицированным можно всё» (READ, WRITE, DELETE; по умолчанию да). */
@@ -175,7 +197,7 @@ export interface TenantOptions {
175
197
  password: string;
176
198
  /**
177
199
  * Вид пароля (по умолчанию PASSWORD) — как у auth.setPassword: `^[A-Z][A-Z0-9_]{1,31}$`, не служебный вид (SESSION,
178
- * APIKEY, KEYSECRET, OTP, TOTP, KEY, PROJECTOR, LOCK); иначе invalid_data.
200
+ * APIKEY, KEYSECRET, OTP, TOTP, KEY, LOCK); иначе invalid_data.
179
201
  */
180
202
  kind?: string;
181
203
  ttl?: string;
@@ -200,4 +222,3 @@ export interface TenantResult {
200
222
  * пользователь или членство были удалены, повтор их не воскрешает — отказ `invalid_data`.
201
223
  */
202
224
  export declare function createTenant(sql: postgres.Sql, schema: string, opts: TenantOptions, owner?: string): Promise<TenantResult>;
203
- export {};