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.
Files changed (113) hide show
  1. package/AGENT-CHEATSHEET.md +329 -278
  2. package/CHANGELOG.md +558 -1
  3. package/README.md +606 -1037
  4. package/dist/acl.d.ts +78 -1
  5. package/dist/acl.js +264 -13
  6. package/dist/admin.d.ts +10 -141
  7. package/dist/admin.js +24 -175
  8. package/dist/auth.d.ts +2 -2
  9. package/dist/auth.js +5 -15
  10. package/dist/cache.d.ts +8 -1
  11. package/dist/cache.js +33 -10
  12. package/dist/chain.d.ts +19 -41
  13. package/dist/chain.js +169 -201
  14. package/dist/cli.js +51 -88
  15. package/dist/demo/booking.d.ts +352 -36
  16. package/dist/describe.d.ts +47 -0
  17. package/dist/describe.js +195 -0
  18. package/dist/errors.d.ts +59 -13
  19. package/dist/errors.js +190 -29
  20. package/dist/index.d.ts +52 -71
  21. package/dist/index.js +245 -130
  22. package/dist/internal.d.ts +12 -0
  23. package/dist/internal.js +5 -0
  24. package/dist/jsonschema.js +18 -17
  25. package/dist/load.d.ts +20 -12
  26. package/dist/load.js +225 -186
  27. package/dist/mcp.d.ts +5 -7
  28. package/dist/mcp.js +171 -215
  29. package/dist/messages/access.d.ts +90 -0
  30. package/dist/messages/access.js +113 -0
  31. package/dist/messages/api.d.ts +171 -0
  32. package/dist/messages/api.js +215 -0
  33. package/dist/messages/boot.d.ts +201 -0
  34. package/dist/messages/boot.js +256 -0
  35. package/dist/messages/codes.d.ts +172 -0
  36. package/dist/messages/codes.js +173 -0
  37. package/dist/messages/index.d.ts +95 -0
  38. package/dist/messages/index.js +118 -0
  39. package/dist/messages/mcp.d.ts +306 -0
  40. package/dist/messages/mcp.js +387 -0
  41. package/dist/messages/model.d.ts +233 -0
  42. package/dist/messages/model.js +283 -0
  43. package/dist/messages/query.d.ts +131 -0
  44. package/dist/messages/query.js +158 -0
  45. package/dist/messages/sql-access.d.ts +70 -0
  46. package/dist/messages/sql-access.js +87 -0
  47. package/dist/messages/sql-core.d.ts +150 -0
  48. package/dist/messages/sql-core.js +181 -0
  49. package/dist/messages/sql-time.d.ts +71 -0
  50. package/dist/messages/sql-time.js +88 -0
  51. package/dist/messages/sql-write.d.ts +246 -0
  52. package/dist/messages/sql-write.js +270 -0
  53. package/dist/messages/time.d.ts +23 -0
  54. package/dist/messages/time.js +29 -0
  55. package/dist/messages/types.d.ts +27 -0
  56. package/dist/messages/types.js +5 -0
  57. package/dist/messages/write.d.ts +405 -0
  58. package/dist/messages/write.js +509 -0
  59. package/dist/model.d.ts +73 -60
  60. package/dist/model.js +26 -29
  61. package/dist/ops.d.ts +35 -0
  62. package/dist/ops.js +101 -0
  63. package/dist/pglite.d.ts +0 -9
  64. package/dist/pglite.js +3 -1
  65. package/dist/registry.d.ts +3 -19
  66. package/dist/registry.js +3 -16
  67. package/dist/signals.d.ts +5 -9
  68. package/dist/signals.js +5 -9
  69. package/dist/sql.d.ts +13 -6
  70. package/dist/sql.js +176 -83
  71. package/dist/sync.d.ts +9 -3
  72. package/dist/sync.js +51 -21
  73. package/dist/tx.d.ts +26 -1
  74. package/dist/tx.js +44 -14
  75. package/dist/typed.d.ts +240 -45
  76. package/dist/types.d.ts +23 -91
  77. package/dist/types.js +12 -14
  78. package/dist/up.d.ts +53 -32
  79. package/dist/up.js +184 -73
  80. package/dist/uuid.js +5 -5
  81. package/dist/validate.d.ts +13 -1
  82. package/dist/validate.js +61 -29
  83. package/dist/watch.d.ts +11 -10
  84. package/dist/watch.js +33 -70
  85. package/dist/write.d.ts +9 -16
  86. package/dist/write.js +118 -187
  87. package/llms.txt +22 -25
  88. package/package.json +8 -11
  89. package/sql/10-core.sql +7 -50
  90. package/sql/15-errors.sql +64 -10
  91. package/sql/20-context.sql +7 -6
  92. package/sql/30-validate.sql +35 -27
  93. package/sql/40-class.sql +20 -114
  94. package/sql/50-acl.sql +8 -13
  95. package/sql/60-write.sql +220 -667
  96. package/sql/70-read.sql +20 -16
  97. package/sql/80-auth.sql +24 -27
  98. package/sql/90-time.sql +70 -859
  99. package/sql/95-seed.system.sql +7 -14
  100. package/sql/99-revision.sql +2 -1
  101. package/sql/README.md +32 -24
  102. package/sql/migrate/README.md +14 -0
  103. package/AGENT-CHEATSHEET.en.md +0 -485
  104. package/MIGRATION.md +0 -190
  105. package/README.en.md +0 -2859
  106. package/dist/import.d.ts +0 -185
  107. package/dist/import.js +0 -820
  108. package/dist/project.d.ts +0 -350
  109. package/dist/project.js +0 -1224
  110. package/sql/75-history.sql +0 -358
  111. package/sql/88-derived.sql +0 -1235
  112. package/sql/migrate/0006-changed-paths.sql +0 -3
  113. package/sql/migrate/0007-secret-account-fk.sql +0 -12
@@ -0,0 +1,158 @@
1
+ export const query = {
2
+ // sql.ts, sortSpec: поле sort() не из списка
3
+ 'query.sort_field': {
4
+ code: 'invalid_query',
5
+ ru: "sort: поле 'at', 'rev', 'id' или 'data.<путь>', а не '{field}'",
6
+ },
7
+ // sql.ts, checkField: поле фильтра, sort() или агрегата не описано ни в одном классе шага (в 1.5 — предупреждение, с 2.0 —
8
+ // отказ); where — шаг или вызов, как в коде: Shop({ nmae }), sort('data.nmae'), sum('data.nmae')
9
+ 'query.unknown_field': {
10
+ code: 'invalid_query',
11
+ ru: '{where}: поле {field} не описано в классе {cls}',
12
+ hint: 'проверить имя поля: похожие названы в тексте, поля класса — db.registry.resolve(класс).schema',
13
+ },
14
+ // sql.ts, resolveHop: классы соседних шагов не ссылаются друг на друга; from, to — имена шагов
15
+ 'query.no_path': {
16
+ code: 'no_path',
17
+ ru: 'нет перехода {from} → {to}: ни один класс не ссылается на другой',
18
+ },
19
+ // sql.ts, compileOp: оператор фильтра, которого построитель не знает
20
+ 'query.unknown_op': {
21
+ code: 'invalid_query',
22
+ ru: 'неизвестный оператор {op}',
23
+ },
24
+ // sql.ts, compileTags: значение tags()
25
+ 'query.tags_arg': {
26
+ code: 'invalid_query',
27
+ ru: 'tags() принимает строку, список или has/hasAny/hasAll',
28
+ },
29
+ // sql.ts, compileFilter: оператор, кроме or(…), вместо фильтра шага
30
+ 'query.step_op': {
31
+ code: 'invalid_query',
32
+ ru: 'оператор {op} на уровне фильтра шага — допустим только or(…)',
33
+ },
34
+ // sql.ts, compileFilter: фильтр — список, а в нём не id
35
+ 'query.id_list': {
36
+ code: 'invalid_query',
37
+ ru: 'список id: ожидались строки',
38
+ },
39
+ // sql.ts, compileFilter: { id: […] } — в списке не id
40
+ 'query.filter_id_list': {
41
+ code: 'invalid_query',
42
+ ru: 'filter.id: ожидались строки',
43
+ },
44
+ // sql.ts, compileFilter: { id } — не строка и не список
45
+ 'query.filter_id': {
46
+ code: 'invalid_query',
47
+ ru: 'filter.id принимает строку или список строк',
48
+ },
49
+ // sql.ts, compileFilter: значение конца в фильтре шага; role — имя конца
50
+ 'query.end_value': {
51
+ code: 'invalid_query',
52
+ ru: 'конец {role}: ожидался id, строка ответа или null',
53
+ },
54
+ // sql.ts, cursorParams: курсор — не объект со значением v; field — поле sort()
55
+ 'query.cursor_shape': {
56
+ code: 'invalid_query',
57
+ ru: "after(cursor): курсор — объект { v, id } из cursorOf(строка, '{field}')",
58
+ },
59
+ // sql.ts, cursorParams: id курсора — не uuid; id — значение, как его печатает shown() (JSON, длинное — с многоточием)
60
+ 'query.cursor_id': {
61
+ code: 'invalid_query',
62
+ ru: 'after(cursor): id курсора — uuid строки, а не {id}',
63
+ },
64
+ // sql.ts, cursorParams: значение курсора не подходит к типу поля sort(); value — как печатает shown(), expect — текст
65
+ // записи query.cursor_expect_* (lmsg)
66
+ 'query.cursor_value': {
67
+ code: 'invalid_query',
68
+ ru: "after(cursor): значение курсора {value} не подходит к sort('{field}') — ожидалось: {expect}; курсор снят с другого поля? Нужен cursorOf(строка, '{field}')",
69
+ },
70
+ // то же у поля данных, которого в строке может не быть: подходит и курсор null
71
+ 'query.cursor_value_nullable': {
72
+ code: 'invalid_query',
73
+ ru: "after(cursor): значение курсора {value} не подходит к sort('{field}') — ожидалось: {expect} или null; курсор снят с другого поля? Нужен cursorOf(строка, '{field}')",
74
+ },
75
+ // sql.ts, CURSOR_EXPECT: какое значение курсора ждёт поле sort() по своему типу — параметр expect двух записей выше
76
+ 'query.cursor_expect_numeric': {
77
+ code: 'invalid_query',
78
+ ru: 'число',
79
+ },
80
+ 'query.cursor_expect_int': {
81
+ code: 'invalid_query',
82
+ ru: 'целое число',
83
+ },
84
+ 'query.cursor_expect_boolean': {
85
+ code: 'invalid_query',
86
+ ru: 'true/false',
87
+ },
88
+ 'query.cursor_expect_text': {
89
+ code: 'invalid_query',
90
+ ru: 'строка',
91
+ },
92
+ 'query.cursor_expect_uuid': {
93
+ code: 'invalid_query',
94
+ ru: 'uuid строкой',
95
+ },
96
+ 'query.cursor_expect_timestamptz': {
97
+ code: 'invalid_query',
98
+ ru: 'время строкой вида 2026-10-07T10:00:00Z',
99
+ },
100
+ 'query.cursor_expect_date': {
101
+ code: 'invalid_query',
102
+ ru: 'дата строкой вида 2026-10-07',
103
+ },
104
+ 'query.cursor_expect_jsonb': {
105
+ code: 'invalid_query',
106
+ ru: 'строка, число, true/false',
107
+ },
108
+ // sql.ts, cursorRev: rev курсора versions(); rev — как печатает shown()
109
+ 'query.cursor_rev': {
110
+ code: 'invalid_query',
111
+ ru: 'after(cursor): rev курсора — номер версии (целое ≥ 1), а не {rev}',
112
+ },
113
+ // sql.ts, cursorPath: в курсоре paths() нет id узла; key — ключ узла в пути
114
+ 'query.cursor_path': {
115
+ code: 'invalid_query',
116
+ ru: 'after(cursor): в курсоре пути нет id узла {key} — нужен cursorOf(путь, поле) из paths() этой же цепочки',
117
+ },
118
+ // sql.ts, cursorOf(): поле не из списка
119
+ 'query.cursor_of_field': {
120
+ code: 'invalid_query',
121
+ ru: "cursorOf: поле 'at', 'rev', 'id' или 'data.<путь>', а не '{field}'",
122
+ },
123
+ // sql.ts, buildRead: цепочка без шагов
124
+ 'query.empty_chain': {
125
+ code: 'invalid_query',
126
+ ru: 'пустая цепочка',
127
+ },
128
+ // sql.ts, buildRead: возврат к узлу, которого нет в пути; name — имя шага
129
+ 'query.pivot_missing': {
130
+ code: 'invalid_query',
131
+ ru: 'возврат к узлу {name}: узла нет в этом пути',
132
+ },
133
+ // sql.ts, buildRead: deep() на первом шаге
134
+ 'query.deep_first_step': {
135
+ code: 'invalid_query',
136
+ ru: 'deep() — на шаге перехода к тому же классу, а не на первом шаге',
137
+ },
138
+ // sql.ts, buildRead: deep() на переходе к другому классу; from, to — имена шагов
139
+ 'query.deep_hop': {
140
+ code: 'invalid_query',
141
+ ru: 'deep() — только на переходе к тому же классу (дети любой глубины): {from} → {to}',
142
+ },
143
+ // sql.ts, buildRead: deep() вместе с withDeleted()
144
+ 'query.deep_with_deleted': {
145
+ code: 'invalid_query',
146
+ ru: 'deep() и withDeleted() не сочетаются',
147
+ },
148
+ // sql.ts, buildRead: after() без sort()
149
+ 'query.after_without_sort': {
150
+ code: 'invalid_query',
151
+ ru: 'after(cursor) требует sort(поле)',
152
+ },
153
+ // sql.ts, buildRead: агрегат не по полю данных
154
+ 'query.agg_field': {
155
+ code: 'invalid_query',
156
+ ru: "агрегат по полю 'data.<путь>'",
157
+ },
158
+ };
@@ -0,0 +1,70 @@
1
+ export declare const sqlAccess: {
2
+ 'sql-access.no_session': {
3
+ code: "no_session";
4
+ ru: string;
5
+ };
6
+ 'sql-access.no_membership': {
7
+ code: "tenant_denied";
8
+ ru: string;
9
+ };
10
+ 'sql-access.acl_bad_op': {
11
+ code: "invalid_data";
12
+ ru: string;
13
+ };
14
+ 'sql-access.account_unavailable': {
15
+ code: "target_not_found";
16
+ ru: string;
17
+ };
18
+ 'sql-access.no_right': {
19
+ code: "acl_denied";
20
+ ru: string;
21
+ };
22
+ 'sql-access.default_deny': {
23
+ code: "acl_denied";
24
+ ru: string;
25
+ };
26
+ 'sql-access.bind_denied': {
27
+ code: "acl_denied";
28
+ ru: string;
29
+ };
30
+ 'sql-access.self_or_sysadmin': {
31
+ code: "acl_denied";
32
+ ru: string;
33
+ };
34
+ 'sql-access.no_sessions_for_account': {
35
+ code: "acl_denied";
36
+ ru: string;
37
+ };
38
+ 'sql-access.password_args': {
39
+ code: "invalid_data";
40
+ ru: string;
41
+ };
42
+ 'sql-access.apikey_prefix_conflict': {
43
+ code: "conflict";
44
+ ru: string;
45
+ };
46
+ 'sql-access.otp_args': {
47
+ code: "invalid_data";
48
+ ru: string;
49
+ };
50
+ 'sql-access.account_not_found': {
51
+ code: "target_not_found";
52
+ ru: string;
53
+ };
54
+ 'sql-access.otp_sysadmin_only': {
55
+ code: "acl_denied";
56
+ ru: string;
57
+ };
58
+ 'sql-access.identity_args': {
59
+ code: "invalid_data";
60
+ ru: string;
61
+ };
62
+ 'sql-access.last_service_key': {
63
+ code: "acl_denied";
64
+ ru: string;
65
+ };
66
+ 'sql-access.switch_impersonating': {
67
+ code: "acl_denied";
68
+ ru: string;
69
+ };
70
+ };
@@ -0,0 +1,87 @@
1
+ export const sqlAccess = {
2
+ // 50-acl.sql (acl_check, acl_require), 80-auth.sql (auth_session_required, auth_can_manage, auth_switch): сессии нет
3
+ 'sql-access.no_session': {
4
+ code: 'no_session',
5
+ ru: 'нет действующей сессии',
6
+ },
7
+ // 50-acl.sql, acl_subject(); 80-auth.sql, auth_switch(): аккаунт не член арендатора-цели
8
+ 'sql-access.no_membership': {
9
+ code: 'tenant_denied',
10
+ ru: 'нет членства в арендаторе',
11
+ },
12
+ // 50-acl.sql, acl_plan(): op — переданная операция
13
+ 'sql-access.acl_bad_op': {
14
+ code: 'invalid_data',
15
+ ru: 'операция {op}: нужна READ, WRITE или DELETE',
16
+ },
17
+ // 50-acl.sql, acl_subject()
18
+ 'sql-access.account_unavailable': {
19
+ code: 'target_not_found',
20
+ ru: 'аккаунт не найден или отключён',
21
+ },
22
+ // 50-acl.sql, acl_require(): endpoint — эндпоинт API
23
+ 'sql-access.no_right': {
24
+ code: 'acl_denied',
25
+ ru: 'нет права {endpoint}',
26
+ },
27
+ // 50-acl.sql, acl_api_for(): message решения по эндпоинту без подходящего правила — текст не для ошибки (lt_text)
28
+ 'sql-access.default_deny': {
29
+ code: 'acl_denied',
30
+ ru: 'нет подходящего правила (запрет по умолчанию)',
31
+ },
32
+ // 80-auth.sql (auth_can_manage, auth_set_password, auth_link): нет недавнего входа и права auth.credential
33
+ 'sql-access.bind_denied': {
34
+ code: 'acl_denied',
35
+ ru: 'привязка отклонена: нужен недавний вход или право auth.credential',
36
+ },
37
+ // 80-auth.sql, auth_guard()
38
+ 'sql-access.self_or_sysadmin': {
39
+ code: 'acl_denied',
40
+ ru: 'креды и сессии этого аккаунта меняет только он сам или системный администратор',
41
+ },
42
+ // 80-auth.sql, issue_session()
43
+ 'sql-access.no_sessions_for_account': {
44
+ code: 'acl_denied',
45
+ ru: 'сессии для этого аккаунта не выпускаются',
46
+ },
47
+ // 80-auth.sql, auth_set_password()
48
+ 'sql-access.password_args': {
49
+ code: 'invalid_data',
50
+ ru: 'пароль: вид, идентификатор и хэш scrypt$… обязательны',
51
+ },
52
+ // 80-auth.sql, auth_issue_apikey(): SQLSTATE 40001 — повторяемый конфликт
53
+ 'sql-access.apikey_prefix_conflict': {
54
+ code: 'conflict',
55
+ ru: 'не удалось выпустить ключ с уникальным префиксом',
56
+ },
57
+ // 80-auth.sql, auth_issue_otp()
58
+ 'sql-access.otp_args': {
59
+ code: 'invalid_data',
60
+ ru: 'код: вид OTP или OTP_<имя>, идентификатор, 4–10 знаков',
61
+ },
62
+ // 80-auth.sql, auth_issue_otp()
63
+ 'sql-access.account_not_found': {
64
+ code: 'target_not_found',
65
+ ru: 'аккаунт не найден',
66
+ },
67
+ // 80-auth.sql, auth_issue_otp()
68
+ 'sql-access.otp_sysadmin_only': {
69
+ code: 'acl_denied',
70
+ ru: 'коды входа для System, сервисов и системных администраторов выпускает только системный администратор',
71
+ },
72
+ // 80-auth.sql, auth_link()
73
+ 'sql-access.identity_args': {
74
+ code: 'invalid_data',
75
+ ru: 'identity: вид (TELEGRAM, GOOGLE, …) и идентификатор обязательны',
76
+ },
77
+ // 80-auth.sql, auth_revoke_credential()
78
+ 'sql-access.last_service_key': {
79
+ code: 'acl_denied',
80
+ ru: 'последний действующий ключ сервиса не отзывается: сначала выпустите новый',
81
+ },
82
+ // 80-auth.sql, auth_switch()
83
+ 'sql-access.switch_impersonating': {
84
+ code: 'acl_denied',
85
+ ru: 'auth.switch — для собственной сессии, не при имперсонации',
86
+ },
87
+ };
@@ -0,0 +1,150 @@
1
+ export declare const sqlCore: {
2
+ 'sql-core.no_membership': {
3
+ code: "tenant_denied";
4
+ ru: string;
5
+ };
6
+ 'sql-core.account_not_id': {
7
+ code: "acl_denied";
8
+ ru: string;
9
+ };
10
+ 'sql-core.no_impersonate_right': {
11
+ code: "acl_denied";
12
+ ru: string;
13
+ };
14
+ 'sql-core.impersonation_denied': {
15
+ code: "acl_denied";
16
+ ru: string;
17
+ };
18
+ 'sql-core.tenant_not_id': {
19
+ code: "tenant_denied";
20
+ ru: string;
21
+ };
22
+ 'sql-core.bad_api_key': {
23
+ code: "no_session";
24
+ ru: string;
25
+ };
26
+ 'sql-core.pattern_trailing_backslash': {
27
+ code: "invalid_class";
28
+ ru: string;
29
+ };
30
+ 'sql-core.pattern_escape_in_set': {
31
+ code: "invalid_class";
32
+ ru: string;
33
+ };
34
+ 'sql-core.pattern_word_boundary': {
35
+ code: "invalid_class";
36
+ ru: string;
37
+ };
38
+ 'sql-core.pattern_unicode_property': {
39
+ code: "invalid_class";
40
+ ru: string;
41
+ };
42
+ 'sql-core.pattern_backreference': {
43
+ code: "invalid_class";
44
+ ru: string;
45
+ };
46
+ 'sql-core.pattern_named_group': {
47
+ code: "invalid_class";
48
+ ru: string;
49
+ };
50
+ 'sql-core.schema_node_not_object': {
51
+ code: "invalid_class";
52
+ ru: string;
53
+ };
54
+ 'sql-core.keyword_unsupported': {
55
+ code: "invalid_class";
56
+ ru: string;
57
+ };
58
+ 'sql-core.unknown_type': {
59
+ code: "invalid_class";
60
+ ru: string;
61
+ };
62
+ 'sql-core.enum_objects_in_any_of': {
63
+ code: "invalid_class";
64
+ ru: string;
65
+ };
66
+ 'sql-core.format_unsupported': {
67
+ code: "invalid_class";
68
+ ru: string;
69
+ };
70
+ 'sql-core.format_in_any_of': {
71
+ code: "invalid_class";
72
+ ru: string;
73
+ };
74
+ 'sql-core.string_length_in_any_of': {
75
+ code: "invalid_class";
76
+ ru: string;
77
+ };
78
+ 'sql-core.unique_items_in_any_of': {
79
+ code: "invalid_class";
80
+ ru: string;
81
+ };
82
+ 'sql-core.min_properties_in_any_of': {
83
+ code: "invalid_class";
84
+ ru: string;
85
+ };
86
+ 'sql-core.issue_string_length': {
87
+ code: "invalid_data";
88
+ ru: string;
89
+ };
90
+ 'sql-core.issue_unique_items': {
91
+ code: "invalid_data";
92
+ ru: string;
93
+ };
94
+ 'sql-core.issue_date': {
95
+ code: "invalid_data";
96
+ ru: string;
97
+ };
98
+ 'sql-core.issue_property_count': {
99
+ code: "invalid_data";
100
+ ru: string;
101
+ };
102
+ 'sql-core.issue_enum': {
103
+ code: "invalid_data";
104
+ ru: string;
105
+ };
106
+ 'sql-core.issue_rule': {
107
+ code: "invalid_data";
108
+ ru: string;
109
+ };
110
+ 'sql-core.issue_schema': {
111
+ code: "invalid_data";
112
+ ru: string;
113
+ };
114
+ 'sql-core.parent_not_found': {
115
+ code: "invalid_class";
116
+ ru: string;
117
+ };
118
+ 'sql-core.inheritance_cycle': {
119
+ code: "invalid_class";
120
+ ru: string;
121
+ };
122
+ 'sql-core.class_metaschema': {
123
+ code: "invalid_data";
124
+ ru: string;
125
+ };
126
+ 'sql-core.meta_too_large': {
127
+ code: "invalid_class";
128
+ ru: string;
129
+ };
130
+ 'sql-core.key_field_type': {
131
+ code: "invalid_class";
132
+ ru: string;
133
+ };
134
+ 'sql-core.key_end_type': {
135
+ code: "invalid_class";
136
+ ru: string;
137
+ };
138
+ 'sql-core.key_unknown_name': {
139
+ code: "invalid_class";
140
+ ru: string;
141
+ };
142
+ 'sql-core.unset_required_end': {
143
+ code: "invalid_class";
144
+ ru: string;
145
+ };
146
+ 'sql-core.system_history_off': {
147
+ code: "invalid_class";
148
+ ru: string;
149
+ };
150
+ };
@@ -0,0 +1,181 @@
1
+ export const sqlCore = {
2
+ // 20-context.sql, ctx(): рабочий арендатор чужой, а членства в нём нет (или арендатор выключен)
3
+ 'sql-core.no_membership': {
4
+ code: 'tenant_denied',
5
+ ru: 'нет членства в арендаторе',
6
+ },
7
+ // 20-context.sql, ctx(): настройка letopis.account — не uuid включённого аккаунта
8
+ 'sql-core.account_not_id': {
9
+ code: 'acl_denied',
10
+ ru: 'letopis.account — не id аккаунта',
11
+ },
12
+ // 20-context.sql, ctx(): имперсонация без права auth.impersonate
13
+ 'sql-core.no_impersonate_right': {
14
+ code: 'acl_denied',
15
+ ru: 'нет права auth.impersonate',
16
+ },
17
+ // 20-context.sql, ctx(): имперсонация System, сервиса или системного администратора не системным администратором
18
+ 'sql-core.impersonation_denied': {
19
+ code: 'acl_denied',
20
+ ru: 'действовать от имени этого аккаунта нельзя',
21
+ },
22
+ // 20-context.sql, ctx(): настройка letopis.tenant — не uuid
23
+ 'sql-core.tenant_not_id': {
24
+ code: 'tenant_denied',
25
+ ru: 'letopis.tenant — не id арендатора',
26
+ },
27
+ // 20-context.sql, login_apikey(): ключа нет, он отозван, истёк или аккаунт выключен
28
+ 'sql-core.bad_api_key': {
29
+ code: 'no_session',
30
+ ru: 'неверный ключ',
31
+ },
32
+ // 30-validate.sql, jp_pattern(): pattern JSON Schema не переводится в регулярное выражение PostgreSQL
33
+ 'sql-core.pattern_trailing_backslash': {
34
+ code: 'invalid_class',
35
+ ru: 'шаблон {pattern} несовместим с регулярными выражениями PostgreSQL (обратная косая черта в конце шаблона)',
36
+ },
37
+ // 30-validate.sql, jp_pattern(): \D, \W, \S внутри [ ]; escape — сама последовательность
38
+ 'sql-core.pattern_escape_in_set': {
39
+ code: 'invalid_class',
40
+ ru: 'шаблон {pattern} несовместим с регулярными выражениями PostgreSQL ({escape} внутри набора [ ] не переводится)',
41
+ },
42
+ // 30-validate.sql, jp_pattern(): \b, \B; escape — сама последовательность
43
+ 'sql-core.pattern_word_boundary': {
44
+ code: 'invalid_class',
45
+ ru: 'шаблон {pattern} несовместим с регулярными выражениями PostgreSQL ({escape} в PostgreSQL значит другое)',
46
+ },
47
+ // 30-validate.sql, jp_pattern(): \p, \P
48
+ 'sql-core.pattern_unicode_property': {
49
+ code: 'invalid_class',
50
+ ru: 'шаблон {pattern} несовместим с регулярными выражениями PostgreSQL (\\p{…} не поддерживается)',
51
+ },
52
+ // 30-validate.sql, jp_pattern(): \k и \1–\9
53
+ 'sql-core.pattern_backreference': {
54
+ code: 'invalid_class',
55
+ ru: 'шаблон {pattern} несовместим с регулярными выражениями PostgreSQL (обратные ссылки не поддерживаются)',
56
+ },
57
+ // 30-validate.sql, jp_pattern(): (?<имя>…)
58
+ 'sql-core.pattern_named_group': {
59
+ code: 'invalid_class',
60
+ ru: 'шаблон {pattern} несовместим с регулярными выражениями PostgreSQL (именованные группы не поддерживаются)',
61
+ },
62
+ // 30-validate.sql, jp_compile(): node — путь узла описания массивом JSON
63
+ 'sql-core.schema_node_not_object': {
64
+ code: 'invalid_class',
65
+ ru: 'описание узла {node} — не объект',
66
+ },
67
+ // 30-validate.sql, jp_compile()
68
+ 'sql-core.keyword_unsupported': {
69
+ code: 'invalid_class',
70
+ ru: 'ключевое слово {keyword} не поддерживается (узел {node})',
71
+ },
72
+ // 30-validate.sql, jp_compile()
73
+ 'sql-core.unknown_type': {
74
+ code: 'invalid_class',
75
+ ru: 'неизвестный тип в узле {node}',
76
+ },
77
+ // 30-validate.sql, jp_compile()
78
+ 'sql-core.enum_objects_in_any_of': {
79
+ code: 'invalid_class',
80
+ ru: 'перечисление объектов внутри anyOf не поддерживается (узел {node})',
81
+ },
82
+ // 30-validate.sql, jp_compile()
83
+ 'sql-core.format_unsupported': {
84
+ code: 'invalid_class',
85
+ ru: 'format {format} не поддерживается (узел {node})',
86
+ },
87
+ // 30-validate.sql, jp_compile()
88
+ 'sql-core.format_in_any_of': {
89
+ code: 'invalid_class',
90
+ ru: 'format {format} внутри anyOf не поддерживается (узел {node})',
91
+ },
92
+ // 30-validate.sql, jp_compile()
93
+ 'sql-core.string_length_in_any_of': {
94
+ code: 'invalid_class',
95
+ ru: 'длина строки внутри anyOf не поддерживается (узел {node})',
96
+ },
97
+ // 30-validate.sql, jp_compile()
98
+ 'sql-core.unique_items_in_any_of': {
99
+ code: 'invalid_class',
100
+ ru: 'uniqueItems внутри anyOf не поддерживается (узел {node})',
101
+ },
102
+ // 30-validate.sql, jp_compile()
103
+ 'sql-core.min_properties_in_any_of': {
104
+ code: 'invalid_class',
105
+ ru: 'minProperties внутри anyOf не поддерживается (узел {node})',
106
+ },
107
+ // 30-validate.sql, validate_data(): сообщения нарушений issues[].message — тексты не для ошибки (lt_text)
108
+ 'sql-core.issue_string_length': {
109
+ code: 'invalid_data',
110
+ ru: 'длина строки вне границ',
111
+ },
112
+ 'sql-core.issue_unique_items': {
113
+ code: 'invalid_data',
114
+ ru: 'элементы повторяются',
115
+ },
116
+ 'sql-core.issue_date': {
117
+ code: 'invalid_data',
118
+ ru: 'такой даты не бывает',
119
+ },
120
+ 'sql-core.issue_property_count': {
121
+ code: 'invalid_data',
122
+ ru: 'число ключей вне границ',
123
+ },
124
+ 'sql-core.issue_enum': {
125
+ code: 'invalid_data',
126
+ ru: 'значение не из перечисления',
127
+ },
128
+ 'sql-core.issue_rule': {
129
+ code: 'invalid_data',
130
+ ru: 'нарушено правило {keyword}',
131
+ },
132
+ 'sql-core.issue_schema': {
133
+ code: 'invalid_data',
134
+ ru: 'данные не проходят описание',
135
+ },
136
+ // 40-class.sql, class_resolve(): предка из parent нет ни у арендатора, ни в System
137
+ 'sql-core.parent_not_found': {
138
+ code: 'invalid_class',
139
+ ru: 'предок {parent} не найден',
140
+ },
141
+ // 40-class.sql, class_resolve(): cls — класс, на котором замкнулась цепочка предков
142
+ 'sql-core.inheritance_cycle': {
143
+ code: 'invalid_class',
144
+ ru: 'цикл в наследовании через {cls}',
145
+ },
146
+ // 40-class.sql, class_prepare(): detail.issues — нарушения метасхемы
147
+ 'sql-core.class_metaschema': {
148
+ code: 'invalid_data',
149
+ ru: 'описание класса не проходит метасхему',
150
+ },
151
+ // 40-class.sql, class_prepare()
152
+ 'sql-core.meta_too_large': {
153
+ code: 'invalid_class',
154
+ ru: 'meta класса больше 64 КБ',
155
+ },
156
+ // 40-class.sql, class_prepare()
157
+ 'sql-core.key_field_type': {
158
+ code: 'invalid_class',
159
+ ru: 'поле ключа {field} должно быть обязательной строкой',
160
+ },
161
+ // 40-class.sql, class_prepare()
162
+ 'sql-core.key_end_type': {
163
+ code: 'invalid_class',
164
+ ru: 'конец ключа {end} должен быть обязательным и одиночным',
165
+ },
166
+ // 40-class.sql, class_prepare()
167
+ 'sql-core.key_unknown_name': {
168
+ code: 'invalid_class',
169
+ ru: 'ключ ссылается на неизвестное поле или конец {name}',
170
+ },
171
+ // 40-class.sql, class_prepare()
172
+ 'sql-core.unset_required_end': {
173
+ code: 'invalid_class',
174
+ ru: 'onDelete unset недопустим для обязательного конца {end}',
175
+ },
176
+ // 40-class.sql, class_prepare()
177
+ 'sql-core.system_history_off': {
178
+ code: 'invalid_class',
179
+ ru: 'history: false для системных классов запрещён',
180
+ },
181
+ };