@leemour/cli-messaging 0.147.0 → 0.148.1

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 (306) hide show
  1. package/dist/background/index.d.ts +1 -1
  2. package/dist/background/index.d.ts.map +1 -1
  3. package/dist/background/index.js +1 -1
  4. package/dist/background/index.js.map +1 -1
  5. package/dist/background/lock.d.ts +6 -0
  6. package/dist/background/lock.d.ts.map +1 -1
  7. package/dist/background/lock.js +31 -1
  8. package/dist/background/lock.js.map +1 -1
  9. package/dist/cli/config-command.d.ts.map +1 -1
  10. package/dist/cli/config-command.js +17 -3
  11. package/dist/cli/config-command.js.map +1 -1
  12. package/dist/cli/index.d.ts +7 -1
  13. package/dist/cli/index.d.ts.map +1 -1
  14. package/dist/cli/index.js +6 -0
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/cli/messenger/chats-command.d.ts.map +1 -1
  17. package/dist/cli/messenger/chats-command.js +2 -2
  18. package/dist/cli/messenger/chats-command.js.map +1 -1
  19. package/dist/cli/messenger/contacts-command.d.ts.map +1 -1
  20. package/dist/cli/messenger/contacts-command.js +45 -1
  21. package/dist/cli/messenger/contacts-command.js.map +1 -1
  22. package/dist/cli/messenger/context.d.ts +8 -1
  23. package/dist/cli/messenger/context.d.ts.map +1 -1
  24. package/dist/cli/messenger/context.js +21 -2
  25. package/dist/cli/messenger/context.js.map +1 -1
  26. package/dist/cli/messenger/conversations-command.d.ts.map +1 -1
  27. package/dist/cli/messenger/conversations-command.js +6 -20
  28. package/dist/cli/messenger/conversations-command.js.map +1 -1
  29. package/dist/cli/messenger/doctor-command.d.ts +14 -0
  30. package/dist/cli/messenger/doctor-command.d.ts.map +1 -1
  31. package/dist/cli/messenger/doctor-command.js +117 -6
  32. package/dist/cli/messenger/doctor-command.js.map +1 -1
  33. package/dist/cli/messenger/flood-command.d.ts +8 -0
  34. package/dist/cli/messenger/flood-command.d.ts.map +1 -0
  35. package/dist/cli/messenger/flood-command.js +31 -0
  36. package/dist/cli/messenger/flood-command.js.map +1 -0
  37. package/dist/cli/messenger/flooded.d.ts +12 -0
  38. package/dist/cli/messenger/flooded.d.ts.map +1 -0
  39. package/dist/cli/messenger/flooded.js +77 -0
  40. package/dist/cli/messenger/flooded.js.map +1 -0
  41. package/dist/cli/messenger/inbox.d.ts +1 -0
  42. package/dist/cli/messenger/inbox.d.ts.map +1 -1
  43. package/dist/cli/messenger/inbox.js +4 -3
  44. package/dist/cli/messenger/inbox.js.map +1 -1
  45. package/dist/cli/messenger/mcp-command.d.ts +12 -0
  46. package/dist/cli/messenger/mcp-command.d.ts.map +1 -1
  47. package/dist/cli/messenger/mcp-command.js +49 -3
  48. package/dist/cli/messenger/mcp-command.js.map +1 -1
  49. package/dist/cli/messenger/messages-search-command.d.ts +2 -0
  50. package/dist/cli/messenger/messages-search-command.d.ts.map +1 -1
  51. package/dist/cli/messenger/messages-search-command.js +46 -15
  52. package/dist/cli/messenger/messages-search-command.js.map +1 -1
  53. package/dist/cli/messenger/messages-stats-command.d.ts +2 -0
  54. package/dist/cli/messenger/messages-stats-command.d.ts.map +1 -1
  55. package/dist/cli/messenger/messages-stats-command.js +35 -11
  56. package/dist/cli/messenger/messages-stats-command.js.map +1 -1
  57. package/dist/cli/messenger/port.d.ts +25 -1
  58. package/dist/cli/messenger/port.d.ts.map +1 -1
  59. package/dist/cli/messenger/port.js.map +1 -1
  60. package/dist/cli/messenger/private-files.d.ts +25 -0
  61. package/dist/cli/messenger/private-files.d.ts.map +1 -0
  62. package/dist/cli/messenger/private-files.js +28 -0
  63. package/dist/cli/messenger/private-files.js.map +1 -0
  64. package/dist/cli/messenger/replies-command.d.ts +5 -0
  65. package/dist/cli/messenger/replies-command.d.ts.map +1 -0
  66. package/dist/cli/messenger/replies-command.js +78 -0
  67. package/dist/cli/messenger/replies-command.js.map +1 -0
  68. package/dist/cli/messenger/report.d.ts +5 -0
  69. package/dist/cli/messenger/report.d.ts.map +1 -1
  70. package/dist/cli/messenger/report.js +25 -7
  71. package/dist/cli/messenger/report.js.map +1 -1
  72. package/dist/cli/messenger/review.d.ts.map +1 -1
  73. package/dist/cli/messenger/review.js +5 -3
  74. package/dist/cli/messenger/review.js.map +1 -1
  75. package/dist/cli/messenger/searches-command.d.ts +5 -0
  76. package/dist/cli/messenger/searches-command.d.ts.map +1 -0
  77. package/dist/cli/messenger/searches-command.js +117 -0
  78. package/dist/cli/messenger/searches-command.js.map +1 -0
  79. package/dist/cli/messenger/serve-command.d.ts.map +1 -1
  80. package/dist/cli/messenger/serve-command.js +87 -8
  81. package/dist/cli/messenger/serve-command.js.map +1 -1
  82. package/dist/cli/messenger/server-command.d.ts.map +1 -1
  83. package/dist/cli/messenger/server-command.js +7 -0
  84. package/dist/cli/messenger/server-command.js.map +1 -1
  85. package/dist/cli/messenger/store-maintenance-command.d.ts.map +1 -1
  86. package/dist/cli/messenger/store-maintenance-command.js +105 -4
  87. package/dist/cli/messenger/store-maintenance-command.js.map +1 -1
  88. package/dist/cli/messenger/tags-command.d.ts +5 -0
  89. package/dist/cli/messenger/tags-command.d.ts.map +1 -0
  90. package/dist/cli/messenger/tags-command.js +76 -0
  91. package/dist/cli/messenger/tags-command.js.map +1 -0
  92. package/dist/cli/messenger/watch-command.d.ts +4 -1
  93. package/dist/cli/messenger/watch-command.d.ts.map +1 -1
  94. package/dist/cli/messenger/watch-command.js +2 -1
  95. package/dist/cli/messenger/watch-command.js.map +1 -1
  96. package/dist/cli/store-settings.d.ts +26 -0
  97. package/dist/cli/store-settings.d.ts.map +1 -0
  98. package/dist/cli/store-settings.js +59 -0
  99. package/dist/cli/store-settings.js.map +1 -0
  100. package/dist/domain/models.d.ts +1 -1
  101. package/dist/domain/models.d.ts.map +1 -1
  102. package/dist/domain/tags.d.ts +6 -0
  103. package/dist/domain/tags.d.ts.map +1 -0
  104. package/dist/domain/tags.js +15 -0
  105. package/dist/domain/tags.js.map +1 -0
  106. package/dist/index.d.ts +1 -0
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +1 -0
  109. package/dist/index.js.map +1 -1
  110. package/dist/kit/contract.d.ts.map +1 -1
  111. package/dist/kit/contract.js +6 -2
  112. package/dist/kit/contract.js.map +1 -1
  113. package/dist/mcp/personal.d.ts.map +1 -1
  114. package/dist/mcp/personal.js +2 -1
  115. package/dist/mcp/personal.js.map +1 -1
  116. package/dist/mcp/server.d.ts.map +1 -1
  117. package/dist/mcp/server.js +8 -1
  118. package/dist/mcp/server.js.map +1 -1
  119. package/dist/mcp/tool.d.ts +7 -0
  120. package/dist/mcp/tool.d.ts.map +1 -1
  121. package/dist/mcp/tool.js +12 -1
  122. package/dist/mcp/tool.js.map +1 -1
  123. package/dist/mcp/tools/chats.js +3 -3
  124. package/dist/mcp/tools/chats.js.map +1 -1
  125. package/dist/mcp/tools/contacts.d.ts.map +1 -1
  126. package/dist/mcp/tools/contacts.js +21 -1
  127. package/dist/mcp/tools/contacts.js.map +1 -1
  128. package/dist/mcp/tools/conversations.d.ts.map +1 -1
  129. package/dist/mcp/tools/conversations.js +2 -7
  130. package/dist/mcp/tools/conversations.js.map +1 -1
  131. package/dist/mcp/tools/messages.d.ts.map +1 -1
  132. package/dist/mcp/tools/messages.js +14 -2
  133. package/dist/mcp/tools/messages.js.map +1 -1
  134. package/dist/mcp/tools/search.d.ts +6 -3
  135. package/dist/mcp/tools/search.d.ts.map +1 -1
  136. package/dist/mcp/tools/search.js +48 -11
  137. package/dist/mcp/tools/search.js.map +1 -1
  138. package/dist/mcp/tools/searches.d.ts +4 -0
  139. package/dist/mcp/tools/searches.d.ts.map +1 -0
  140. package/dist/mcp/tools/searches.js +77 -0
  141. package/dist/mcp/tools/searches.js.map +1 -0
  142. package/dist/mcp/tools/tags.d.ts +4 -0
  143. package/dist/mcp/tools/tags.d.ts.map +1 -0
  144. package/dist/mcp/tools/tags.js +57 -0
  145. package/dist/mcp/tools/tags.js.map +1 -0
  146. package/dist/mcp/tools.d.ts +2 -0
  147. package/dist/mcp/tools.d.ts.map +1 -1
  148. package/dist/mcp/tools.js +7 -0
  149. package/dist/mcp/tools.js.map +1 -1
  150. package/dist/replies/decide.d.ts +3 -0
  151. package/dist/replies/decide.d.ts.map +1 -1
  152. package/dist/replies/decide.js +3 -0
  153. package/dist/replies/decide.js.map +1 -1
  154. package/dist/replies/dry-run.d.ts +51 -0
  155. package/dist/replies/dry-run.d.ts.map +1 -0
  156. package/dist/replies/dry-run.js +116 -0
  157. package/dist/replies/dry-run.js.map +1 -0
  158. package/dist/replies/rules.d.ts +12 -0
  159. package/dist/replies/rules.d.ts.map +1 -1
  160. package/dist/replies/rules.js +15 -6
  161. package/dist/replies/rules.js.map +1 -1
  162. package/dist/replies/serve.d.ts +44 -0
  163. package/dist/replies/serve.d.ts.map +1 -0
  164. package/dist/replies/serve.js +70 -0
  165. package/dist/replies/serve.js.map +1 -0
  166. package/dist/search/lucene/automaton.d.ts +5 -0
  167. package/dist/search/lucene/automaton.d.ts.map +1 -1
  168. package/dist/search/lucene/automaton.js +116 -0
  169. package/dist/search/lucene/automaton.js.map +1 -1
  170. package/dist/search/lucene/parser.d.ts.map +1 -1
  171. package/dist/search/lucene/parser.js +6 -2
  172. package/dist/search/lucene/parser.js.map +1 -1
  173. package/dist/search/lucene/registry.d.ts +5 -5
  174. package/dist/search/lucene/registry.d.ts.map +1 -1
  175. package/dist/search/lucene/registry.js +12 -7
  176. package/dist/search/lucene/registry.js.map +1 -1
  177. package/dist/sends/flood.d.ts +57 -0
  178. package/dist/sends/flood.d.ts.map +1 -0
  179. package/dist/sends/flood.js +90 -0
  180. package/dist/sends/flood.js.map +1 -0
  181. package/dist/sends/guard.d.ts +4 -1
  182. package/dist/sends/guard.d.ts.map +1 -1
  183. package/dist/sends/guard.js +9 -1
  184. package/dist/sends/guard.js.map +1 -1
  185. package/dist/sends/index.d.ts +1 -0
  186. package/dist/sends/index.d.ts.map +1 -1
  187. package/dist/sends/index.js +1 -0
  188. package/dist/sends/index.js.map +1 -1
  189. package/dist/sends/journal.d.ts +2 -0
  190. package/dist/sends/journal.d.ts.map +1 -1
  191. package/dist/sends/journal.js.map +1 -1
  192. package/dist/sends/permissions.d.ts +1 -1
  193. package/dist/sends/permissions.d.ts.map +1 -1
  194. package/dist/sends/permissions.js +14 -1
  195. package/dist/sends/permissions.js.map +1 -1
  196. package/dist/services/chats.d.ts +3 -3
  197. package/dist/services/chats.d.ts.map +1 -1
  198. package/dist/services/chats.js +2 -2
  199. package/dist/services/chats.js.map +1 -1
  200. package/dist/services/deps.d.ts +2 -0
  201. package/dist/services/deps.d.ts.map +1 -1
  202. package/dist/services/deps.js.map +1 -1
  203. package/dist/services/inbox.d.ts +0 -2
  204. package/dist/services/inbox.d.ts.map +1 -1
  205. package/dist/services/inbox.js +13 -8
  206. package/dist/services/inbox.js.map +1 -1
  207. package/dist/services/index.d.ts +8 -0
  208. package/dist/services/index.d.ts.map +1 -1
  209. package/dist/services/index.js +6 -0
  210. package/dist/services/index.js.map +1 -1
  211. package/dist/services/messages-search.d.ts +2 -2
  212. package/dist/services/messages-search.d.ts.map +1 -1
  213. package/dist/services/messages-search.js +11 -3
  214. package/dist/services/messages-search.js.map +1 -1
  215. package/dist/services/messages.d.ts +10 -3
  216. package/dist/services/messages.d.ts.map +1 -1
  217. package/dist/services/messages.js +47 -4
  218. package/dist/services/messages.js.map +1 -1
  219. package/dist/services/people.d.ts +7 -0
  220. package/dist/services/people.d.ts.map +1 -1
  221. package/dist/services/people.js +18 -0
  222. package/dist/services/people.js.map +1 -1
  223. package/dist/services/person-context.d.ts +69 -0
  224. package/dist/services/person-context.d.ts.map +1 -0
  225. package/dist/services/person-context.js +130 -0
  226. package/dist/services/person-context.js.map +1 -0
  227. package/dist/services/searches.d.ts +50 -0
  228. package/dist/services/searches.d.ts.map +1 -0
  229. package/dist/services/searches.js +127 -0
  230. package/dist/services/searches.js.map +1 -0
  231. package/dist/services/tags.d.ts +40 -0
  232. package/dist/services/tags.d.ts.map +1 -0
  233. package/dist/services/tags.js +56 -0
  234. package/dist/services/tags.js.map +1 -0
  235. package/dist/store/index.d.ts +1 -1
  236. package/dist/store/index.d.ts.map +1 -1
  237. package/dist/store/index.js.map +1 -1
  238. package/dist/store/normalize.d.ts +2 -0
  239. package/dist/store/normalize.d.ts.map +1 -1
  240. package/dist/store/normalize.js +7 -5
  241. package/dist/store/normalize.js.map +1 -1
  242. package/dist/store/repair.d.ts +55 -0
  243. package/dist/store/repair.d.ts.map +1 -0
  244. package/dist/store/repair.js +313 -0
  245. package/dist/store/repair.js.map +1 -0
  246. package/dist/store/sqlite/accounts.d.ts.map +1 -1
  247. package/dist/store/sqlite/accounts.js +3 -1
  248. package/dist/store/sqlite/accounts.js.map +1 -1
  249. package/dist/store/sqlite/chats.d.ts.map +1 -1
  250. package/dist/store/sqlite/chats.js +3 -1
  251. package/dist/store/sqlite/chats.js.map +1 -1
  252. package/dist/store/sqlite/drizzle/bun.js +1 -1
  253. package/dist/store/sqlite/drizzle/core.d.ts +1 -1
  254. package/dist/store/sqlite/drizzle/core.d.ts.map +1 -1
  255. package/dist/store/sqlite/drizzle/core.js +3 -1
  256. package/dist/store/sqlite/drizzle/core.js.map +1 -1
  257. package/dist/store/sqlite/drizzle/node.js +1 -1
  258. package/dist/store/sqlite/drizzle/{shared-WZFJ4TMA.js → shared-IZ6QGA7N.js} +2 -1
  259. package/dist/store/sqlite/lucene.d.ts.map +1 -1
  260. package/dist/store/sqlite/lucene.js +17 -3
  261. package/dist/store/sqlite/lucene.js.map +1 -1
  262. package/dist/store/sqlite/manifest.d.ts.map +1 -1
  263. package/dist/store/sqlite/manifest.js +6 -0
  264. package/dist/store/sqlite/manifest.js.map +1 -1
  265. package/dist/store/sqlite/migrations.generated.d.ts.map +1 -1
  266. package/dist/store/sqlite/migrations.generated.js +53 -0
  267. package/dist/store/sqlite/migrations.generated.js.map +1 -1
  268. package/dist/store/sqlite/person-links.d.ts +18 -0
  269. package/dist/store/sqlite/person-links.d.ts.map +1 -0
  270. package/dist/store/sqlite/person-links.js +122 -0
  271. package/dist/store/sqlite/person-links.js.map +1 -0
  272. package/dist/store/sqlite/roster.d.ts +57 -0
  273. package/dist/store/sqlite/roster.d.ts.map +1 -0
  274. package/dist/store/sqlite/roster.js +179 -0
  275. package/dist/store/sqlite/roster.js.map +1 -0
  276. package/dist/store/sqlite/schema.d.ts +753 -0
  277. package/dist/store/sqlite/schema.d.ts.map +1 -1
  278. package/dist/store/sqlite/schema.js +99 -0
  279. package/dist/store/sqlite/schema.js.map +1 -1
  280. package/dist/store/sqlite/search-index.d.ts +3 -0
  281. package/dist/store/sqlite/search-index.d.ts.map +1 -1
  282. package/dist/store/sqlite/search-index.js +8 -6
  283. package/dist/store/sqlite/search-index.js.map +1 -1
  284. package/dist/store/sqlite/search.d.ts +2 -0
  285. package/dist/store/sqlite/search.d.ts.map +1 -1
  286. package/dist/store/sqlite/search.js +5 -0
  287. package/dist/store/sqlite/search.js.map +1 -1
  288. package/dist/store/sqlite/searches.d.ts +35 -0
  289. package/dist/store/sqlite/searches.d.ts.map +1 -0
  290. package/dist/store/sqlite/searches.js +77 -0
  291. package/dist/store/sqlite/searches.js.map +1 -0
  292. package/dist/store/sqlite/stems.d.ts +61 -0
  293. package/dist/store/sqlite/stems.d.ts.map +1 -0
  294. package/dist/store/sqlite/stems.js +215 -0
  295. package/dist/store/sqlite/stems.js.map +1 -0
  296. package/dist/store/sqlite/tags.d.ts +38 -0
  297. package/dist/store/sqlite/tags.d.ts.map +1 -0
  298. package/dist/store/sqlite/tags.js +85 -0
  299. package/dist/store/sqlite/tags.js.map +1 -0
  300. package/dist/store/store.d.ts +97 -0
  301. package/dist/store/store.d.ts.map +1 -1
  302. package/dist/store/store.js +106 -0
  303. package/dist/store/store.js.map +1 -1
  304. package/package.json +1 -1
  305. package/parity.json +238 -30
  306. /package/dist/store/sqlite/drizzle/{shared-WZFJ4TMA.js.map → shared-IZ6QGA7N.js.map} +0 -0
@@ -0,0 +1,127 @@
1
+ import { CliError, singleLine } from "@leemour/cli-core";
2
+ import { parseLucene } from "../search/lucene/parser.js";
3
+ import { FIELD_VERSION, validateAst, validateFields } from "../search/lucene/registry.js";
4
+ import { QUERY_VERSION } from "../search/lucene/types.js";
5
+ const NAME = /^[a-z0-9][a-z0-9-]{0,63}$/;
6
+ const nameOf = (value) => {
7
+ const name = value.trim().toLowerCase();
8
+ if (!NAME.test(name) || /^\d+$/.test(name))
9
+ throw new CliError("validation_error", `"${singleLine(value)}" cannot name a saved search — use up to 64 letters a–z, digits and hyphens, not only digits`, { reason: "invalid_name" });
10
+ return name;
11
+ };
12
+ const canonical = (value) => Array.isArray(value)
13
+ ? value.map(canonical)
14
+ : value !== null && typeof value === "object"
15
+ ? Object.fromEntries(Object.entries(value)
16
+ .filter(([, one]) => one !== undefined && one !== false)
17
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
18
+ .map(([key, one]) => [key, canonical(one)]))
19
+ : value;
20
+ /** One run or one saved search as the store keeps it; the same parameters always give the same text. */
21
+ export const searchRecordOf = (command, params) => ({
22
+ command,
23
+ params: JSON.stringify(canonical({ ...params, language: languageOf(params) })),
24
+ language: languageOf(params) === "lucene" ? "lucene-v1" : "legacy",
25
+ version: QUERY_VERSION,
26
+ fieldsVersion: FIELD_VERSION,
27
+ });
28
+ const languageOf = ({ language, regex, ast }) => language ?? (regex ? "legacy" : ast !== undefined ? "lucene" : "lucene");
29
+ const patternOf = (source) => {
30
+ try {
31
+ return new RegExp(source, "iu");
32
+ }
33
+ catch {
34
+ throw new CliError("validation_error", "not a regular expression — check JavaScript syntax or use Lucene regex");
35
+ }
36
+ };
37
+ /** The query checked as a search would check it, without the store: syntax, fields, values. */
38
+ const checked = (params) => {
39
+ if (params.text !== undefined && params.ast !== undefined)
40
+ throw new CliError("validation_error", "give query text or an AST, not both");
41
+ if (params.regex) {
42
+ if (params.text === undefined)
43
+ throw new CliError("validation_error", "--regex needs the expression");
44
+ patternOf(params.text);
45
+ }
46
+ else if (languageOf(params) === "lucene") {
47
+ if (params.ast !== undefined)
48
+ validateAst(params.ast);
49
+ else if (params.text !== undefined)
50
+ validateFields(parseLucene(params.text));
51
+ }
52
+ return params;
53
+ };
54
+ const named = (search, check) => {
55
+ try {
56
+ check();
57
+ }
58
+ catch (error) {
59
+ if (!(error instanceof CliError))
60
+ throw error;
61
+ const label = search.name === null ? `search run ${search.id}` : `saved search "${search.name}"`;
62
+ throw new CliError(error.code, `${label}: ${error.message}`, error.details);
63
+ }
64
+ };
65
+ const both = (stored, words) => ({
66
+ version: 1,
67
+ language: "lucene-v1",
68
+ root: {
69
+ kind: "boolean",
70
+ clauses: [
71
+ { occur: "must", node: stored.root },
72
+ { occur: "must", node: parseLucene(words).root },
73
+ ],
74
+ span: { start: 0, end: 0 },
75
+ },
76
+ });
77
+ export const searchesService = (deps) => {
78
+ const inStore = async (work) => work(await deps.store());
79
+ const found = async (store, reference) => {
80
+ const search = await store.storedSearch(reference.trim().toLowerCase());
81
+ if (!search)
82
+ throw new CliError("not_found", `no saved search or run "${singleLine(reference)}"`);
83
+ return search;
84
+ };
85
+ return {
86
+ create: (name, params, { replace = false } = {}) => inStore((store) => store.saveSearch(nameOf(name), searchRecordOf(params.by === undefined ? "search" : "stats", checked(params)), {
87
+ replace,
88
+ })),
89
+ show: (reference) => inStore((store) => found(store, reference)),
90
+ list: () => inStore((store) => store.savedSearches()),
91
+ history: (limit) => inStore(async (store) => {
92
+ const rows = await store.searchHistory(limit);
93
+ return { items: rows.slice(0, limit), hasMore: rows.length > limit };
94
+ }),
95
+ delete: (reference) => inStore(async (store) => store.deleteSearch((await found(store, reference)).id)),
96
+ clear: () => inStore(async (store) => ({ cleared: await store.clearSearchHistory() })),
97
+ resolve: (reference, { text: words, ...typed }) => inStore(async (store) => {
98
+ const search = await found(store, reference);
99
+ const stored = search.params;
100
+ const params = {
101
+ ...stored,
102
+ ...Object.fromEntries(Object.entries(typed).filter(([, one]) => one !== undefined)),
103
+ };
104
+ const language = languageOf(params);
105
+ if (language === "lucene" && !params.regex)
106
+ named(search, () => checked({ ...stored, language }));
107
+ const extra = words?.trim() ? words.trim() : undefined;
108
+ if (extra !== undefined) {
109
+ if (params.regex)
110
+ throw new CliError("validation_error", `saved search "${search.name}" is a --regex search; it takes no more words`);
111
+ if (params.ast !== undefined)
112
+ params.ast = both(validateAst(params.ast), extra);
113
+ else if (params.text === undefined)
114
+ params.text = extra;
115
+ else
116
+ params.text = language === "lucene" ? `(${params.text}) AND (${extra})` : `${params.text} ${extra}`;
117
+ }
118
+ return {
119
+ id: search.id,
120
+ name: search.name,
121
+ params,
122
+ ...(params.regex && params.text !== undefined ? { pattern: patternOf(params.text) } : {}),
123
+ };
124
+ }),
125
+ };
126
+ };
127
+ //# sourceMappingURL=searches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searches.js","sourceRoot":"","sources":["../../src/services/searches.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AACzF,OAAO,EAAE,aAAa,EAAiB,MAAM,2BAA2B,CAAA;AA4CxE,MAAM,IAAI,GAAG,2BAA2B,CAAA;AAExC,MAAM,MAAM,GAAG,CAAC,KAAa,EAAU,EAAE;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACvC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QACxC,MAAM,IAAI,QAAQ,CAChB,kBAAkB,EAClB,IAAI,UAAU,CAAC,KAAK,CAAC,8FAA8F,EACnH,EAAE,MAAM,EAAE,cAAc,EAAE,CAC3B,CAAA;IACH,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,KAAc,EAAW,EAAE,CAC5C,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;IAClB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC;IACtB,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAC3C,CAAC,CAAC,MAAM,CAAC,WAAW,CAChB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,KAAK,CAAC;aACvD,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aAChD,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAC9C;QACH,CAAC,CAAC,KAAK,CAAA;AAEb,wGAAwG;AACxG,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAsB,EAAE,MAAoB,EAAgB,EAAE,CAAC,CAAC;IAC7F,OAAO;IACP,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9E,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ;IAClE,OAAO,EAAE,aAAa;IACtB,aAAa,EAAE,aAAa;CAC7B,CAAC,CAAA;AAEF,MAAM,UAAU,GAAG,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAgB,EAAuB,EAAE,CACjF,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;AAE1E,MAAM,SAAS,GAAG,CAAC,MAAc,EAAU,EAAE;IAC3C,IAAI,CAAC;QACH,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,wEAAwE,CAAC,CAAA;IAClH,CAAC;AACH,CAAC,CAAA;AAED,+FAA+F;AAC/F,MAAM,OAAO,GAAG,CAAC,MAAoB,EAAgB,EAAE;IACrD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;QACvD,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,qCAAqC,CAAC,CAAA;IAC/E,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;YAAE,MAAM,IAAI,QAAQ,CAAC,kBAAkB,EAAE,8BAA8B,CAAC,CAAA;QACrG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;SAAM,IAAI,UAAU,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC3C,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;YAAE,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;aAChD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;YAAE,cAAc,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IAC9E,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,MAAM,KAAK,GAAG,CAAC,MAAoB,EAAE,KAAiB,EAAE,EAAE;IACxD,IAAI,CAAC;QACH,KAAK,EAAE,CAAA;IACT,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,QAAQ,CAAC;YAAE,MAAM,KAAK,CAAA;QAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,cAAc,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,iBAAiB,MAAM,CAAC,IAAI,GAAG,CAAA;QAChG,MAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;IAC7E,CAAC;AACH,CAAC,CAAA;AAED,MAAM,IAAI,GAAG,CAAC,MAAgB,EAAE,KAAa,EAAY,EAAE,CAAC,CAAC;IAC3D,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,WAAW;IACrB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;YACpC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE;SACjD;QACD,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;KAC3B;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAiB,EAAmB,EAAE;IACpE,MAAM,OAAO,GAAG,KAAK,EAAK,IAAyC,EAAc,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;IAC5G,MAAM,KAAK,GAAG,KAAK,EAAE,KAAmB,EAAE,SAAiB,EAAyB,EAAE;QACpF,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAA;QACvE,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,QAAQ,CAAC,WAAW,EAAE,2BAA2B,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACjG,OAAO,MAAM,CAAA;IACf,CAAC,CAAA;IAED,OAAO;QACL,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,CACjD,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAChB,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE;YAC5G,OAAO;SACR,CAAC,CACH;QAEH,IAAI,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAEhE,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QAErD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACjB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;YAC7C,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,EAAE,CAAA;QACtE,CAAC,CAAC;QAEJ,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAEvG,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QAEtF,OAAO,EAAE,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,CAChD,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACtB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;YAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAsB,CAAA;YAC5C,MAAM,MAAM,GAAiB;gBAC3B,GAAG,MAAM;gBACT,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC;aACpF,CAAA;YACD,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAA;YACnC,IAAI,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK;gBAAE,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAA;YACjG,MAAM,KAAK,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;YACtD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,IAAI,MAAM,CAAC,KAAK;oBACd,MAAM,IAAI,QAAQ,CAChB,kBAAkB,EAClB,iBAAiB,MAAM,CAAC,IAAI,+CAA+C,CAC5E,CAAA;gBACH,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;oBAAE,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAA;qBAC1E,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;oBAAE,MAAM,CAAC,IAAI,GAAG,KAAK,CAAA;;oBAClD,MAAM,CAAC,IAAI,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,KAAK,EAAE,CAAA;YAC1G,CAAC;YACD,OAAO;gBACL,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,MAAM;gBACN,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1F,CAAA;QACH,CAAC,CAAC;KACL,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,40 @@
1
+ import type { Id } from "../domain/models.js";
2
+ import { type TagType } from "../domain/tags.js";
3
+ import type { StoredTag } from "../store/store.js";
4
+ import type { ServiceDeps } from "./deps.js";
5
+ /** As typed: `chat` alone is the chat; with `message`, a message in it. `message` may be a locator instead. */
6
+ export interface TagTargetInput {
7
+ chat?: string;
8
+ contact?: string;
9
+ message?: string;
10
+ }
11
+ export interface TagTargetView {
12
+ type: TagType;
13
+ chatId?: Id;
14
+ personId?: Id;
15
+ messageId?: Id;
16
+ locator?: string;
17
+ }
18
+ export interface TagsAdded {
19
+ target: TagTargetView;
20
+ added: string[];
21
+ /** Given, and already on it. */
22
+ unchanged: string[];
23
+ }
24
+ export interface TagsRemoved {
25
+ target: TagTargetView;
26
+ removed: string[];
27
+ /** Given, and not on it. */
28
+ unchanged: string[];
29
+ }
30
+ /** The owner's labels in the local store; never sent to the messenger. */
31
+ export interface TagsService {
32
+ add(target: TagTargetInput, tags: string[]): Promise<TagsAdded>;
33
+ remove(target: TagTargetInput, tags: string[]): Promise<TagsRemoved>;
34
+ list(filter?: {
35
+ tag?: string;
36
+ type?: TagType;
37
+ }): Promise<StoredTag[]>;
38
+ }
39
+ export declare const tagsService: (deps: ServiceDeps) => TagsService;
40
+ //# sourceMappingURL=tags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../src/services/tags.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE9D,OAAO,KAAK,EAA4B,SAAS,EAAa,MAAM,mBAAmB,CAAA;AACvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAG5C,+GAA+G;AAC/G,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,CAAC,EAAE,EAAE,CAAA;IACX,QAAQ,CAAC,EAAE,EAAE,CAAA;IACb,SAAS,CAAC,EAAE,EAAE,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,aAAa,CAAA;IACrB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,gCAAgC;IAChC,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,aAAa,CAAA;IACrB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/D,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IACpE,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;CACtE;AAsCD,eAAO,MAAM,WAAW,SAAU,WAAW,KAAG,WA6B/C,CAAA"}
@@ -0,0 +1,56 @@
1
+ import { CliError } from "@leemour/cli-core";
2
+ import { formatLocator, isLocator, parseLocator } from "../domain/locator.js";
3
+ import { normalizeTag } from "../domain/tags.js";
4
+ import { pickPerson } from "../resolve.js";
5
+ import { storedChatId } from "./messages.js";
6
+ const ONE_TARGET = "name one thing: --chat <chat>, --contact <person>, or --message <message> with --chat (or a msg: locator alone)";
7
+ const tagsOf = (given) => {
8
+ if (given.length === 0)
9
+ throw new CliError("validation_error", "name at least one tag");
10
+ return [...new Set(given.map(normalizeTag))];
11
+ };
12
+ const targetOf = async (deps, store, account, { chat, contact, message }) => {
13
+ if (contact !== undefined) {
14
+ if (chat !== undefined || message !== undefined)
15
+ throw new CliError("validation_error", ONE_TARGET);
16
+ const person = pickPerson(contact, await store.people(account.provider, { account: account.account }));
17
+ return { type: "contact", personId: person.id };
18
+ }
19
+ if (message !== undefined && isLocator(message)) {
20
+ if (chat !== undefined)
21
+ throw new CliError("validation_error", "a locator already names the chat — drop --chat");
22
+ const locator = parseLocator(message);
23
+ if (locator.provider !== account.provider || locator.account !== account.account)
24
+ throw new CliError("validation_error", "that locator belongs to another account; select its profile first");
25
+ return { type: "message", chatId: locator.chat, messageId: locator.message };
26
+ }
27
+ if (chat === undefined)
28
+ throw new CliError("validation_error", ONE_TARGET);
29
+ const chatId = await storedChatId(deps.messenger, chat, store, account);
30
+ return message === undefined ? { type: "chat", chatId } : { type: "message", chatId, messageId: message.trim() };
31
+ };
32
+ const viewOf = (account, target) => target.type === "message"
33
+ ? { ...target, locator: formatLocator({ ...account, chat: target.chatId, message: target.messageId }) }
34
+ : target;
35
+ export const tagsService = (deps) => {
36
+ const inStore = async (work) => work(await deps.store(), await deps.account());
37
+ return {
38
+ add: (given, list) => inStore(async (store, account) => {
39
+ const tags = tagsOf(list);
40
+ const target = await targetOf(deps, store, account, given);
41
+ const added = await store.addTags(account, target, tags);
42
+ return { target: viewOf(account, target), added, unchanged: tags.filter((tag) => !added.includes(tag)) };
43
+ }),
44
+ remove: (given, list) => inStore(async (store, account) => {
45
+ const tags = tagsOf(list);
46
+ const target = await targetOf(deps, store, account, given);
47
+ const removed = await store.removeTags(account, target, tags);
48
+ return { target: viewOf(account, target), removed, unchanged: tags.filter((tag) => !removed.includes(tag)) };
49
+ }),
50
+ list: (filter = {}) => inStore((store, account) => store.tags(account, {
51
+ ...(filter.tag === undefined ? {} : { tag: normalizeTag(filter.tag) }),
52
+ ...(filter.type === undefined ? {} : { type: filter.type }),
53
+ })),
54
+ };
55
+ };
56
+ //# sourceMappingURL=tags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tags.js","sourceRoot":"","sources":["../../src/services/tags.ts"],"names":[],"mappings":"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"}
@@ -5,5 +5,5 @@ export { openCache } from "./open.js";
5
5
  export { storePath } from "./path.js";
6
6
  export { backfillNormalized, pendingNormalization } from "./sqlite/backfill.js";
7
7
  export { fillSearchIndex, resetSearchIndex, type SearchIndexFill, type SearchIndexState, searchIndexState, } from "./sqlite/search-index.js";
8
- export { type AccountKey, type ChatStats, type DeletionScope, type Delta, type IngestedVia, type MessageFilter, type MessageStore, openStore, type PersonFacts, type Range, type StoredChatFilter, type StoredHit, type StoreOptions, } from "./store.js";
8
+ export { type AccountKey, type ChatStats, type DeletionScope, type Delta, type IdentityRef, type IngestedVia, type LinkedIdentity, type LinkOptions, type MessageFilter, type MessageStore, openStore, type PersonFacts, type PersonRecord, type Range, type SearchCommand, type SearchRecord, type StoredChatFilter, type StoredHit, type StoredSearch, type StoredTag, type StoreOptions, type TagFilter, type TagTarget, } from "./store.js";
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC/E,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,gBAAgB,GACjB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,KAAK,EACV,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,YAAY,GAClB,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC/E,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,gBAAgB,GACjB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,SAAS,GACf,MAAM,YAAY,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,UAAU,EAAkB,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC/E,OAAO,EACL,eAAe,EACf,gBAAgB,EAGhB,gBAAgB,GACjB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAQL,SAAS,GAMV,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,UAAU,EAAkB,OAAO,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC/E,OAAO,EACL,eAAe,EACf,gBAAgB,EAGhB,gBAAgB,GACjB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAWL,SAAS,GAaV,MAAM,YAAY,CAAA"}
@@ -1,5 +1,7 @@
1
1
  /** Bump when the output changes for any input: rows carry the version that produced their copy. */
2
2
  export declare const NORMALIZER_VERSION = 1;
3
+ /** The letter part of `normalize`, without its whitespace folding, so one character of a pattern can be folded. */
4
+ export declare const fold: (text: string) => string;
3
5
  /**
4
6
  * The searchable copy of a message's text; the original is kept as it was. Stripping marks after
5
7
  * NFKD also folds ё into е and й into и, which merges real words (мой/мои, año/ano) — the ruling
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/store/normalize.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC;;;;GAIG;AACH,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,MAQ9B,CAAA"}
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/store/normalize.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,eAAO,MAAM,kBAAkB,IAAI,CAAA;AAEnC,mHAAmH;AACnH,eAAO,MAAM,IAAI,SAAU,MAAM,KAAG,MAKlB,CAAA;AAElB;;;;GAIG;AACH,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,MAI9B,CAAA"}
@@ -1,15 +1,17 @@
1
1
  /** Bump when the output changes for any input: rows carry the version that produced their copy. */
2
2
  export const NORMALIZER_VERSION = 1;
3
+ /** The letter part of `normalize`, without its whitespace folding, so one character of a pattern can be folded. */
4
+ export const fold = (text) => text
5
+ .normalize("NFKD")
6
+ .replace(/\p{M}+/gu, "")
7
+ .normalize("NFC")
8
+ .toLowerCase();
3
9
  /**
4
10
  * The searchable copy of a message's text; the original is kept as it was. Stripping marks after
5
11
  * NFKD also folds ё into е and й into и, which merges real words (мой/мои, año/ano) — the ruling
6
12
  * accepts that price for search that ignores accents.
7
13
  */
8
- export const normalize = (text) => text
9
- .normalize("NFKD")
10
- .replace(/\p{M}+/gu, "")
11
- .normalize("NFC")
12
- .toLowerCase()
14
+ export const normalize = (text) => fold(text)
13
15
  .replace(/\p{Cc}/gu, " ")
14
16
  .replace(/\s+/gu, " ")
15
17
  .trim();
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/store/normalize.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAA;AAEnC;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAU,EAAE,CAChD,IAAI;KACD,SAAS,CAAC,MAAM,CAAC;KACjB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;KACvB,SAAS,CAAC,KAAK,CAAC;KAChB,WAAW,EAAE;KACb,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;KACxB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;KACrB,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/store/normalize.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAA;AAEnC,mHAAmH;AACnH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAU,EAAE,CAC3C,IAAI;KACD,SAAS,CAAC,MAAM,CAAC;KACjB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;KACvB,SAAS,CAAC,KAAK,CAAC;KAChB,WAAW,EAAE,CAAA;AAElB;;;;GAIG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAU,EAAE,CAChD,IAAI,CAAC,IAAI,CAAC;KACP,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;KACxB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;KACrB,IAAI,EAAE,CAAA"}
@@ -0,0 +1,55 @@
1
+ import type { CacheDatabase } from "./driver.js";
2
+ export declare const COPY_MARK = "__repair_";
3
+ export interface TableRepair {
4
+ table: string;
5
+ action: "created" | "columns-added" | "rebuilt";
6
+ columnsAdded?: string[];
7
+ copy?: string;
8
+ rowsInCopy?: number;
9
+ rowsCopied?: number;
10
+ /** Columns the copy holds that the new table does not: their data is only in the copy. */
11
+ onlyInCopy?: string[];
12
+ /** Indexes and triggers of the copy dropped because the new table needs their names; they hold no data. */
13
+ droppedFromCopy?: string[];
14
+ }
15
+ export interface Mismatch {
16
+ table: string;
17
+ what: string;
18
+ }
19
+ export interface RepairReport {
20
+ dryRun: boolean;
21
+ repaired: TableRepair[];
22
+ indexesCreated: string[];
23
+ triggersCreated: string[];
24
+ mismatches: Mismatch[];
25
+ foreignKeyViolations: {
26
+ table: string;
27
+ rows: number;
28
+ }[];
29
+ copies: {
30
+ name: string;
31
+ rows: number;
32
+ }[];
33
+ }
34
+ /**
35
+ * **Brings each table of the file to the shape this build's migrations give it, deleting nothing**
36
+ * (NEED-626). A table only missing columns it can take gets them added; any other difference keeps
37
+ * the table as a copy named `<table>__repair_<hash>` beside a new one holding every row that fits.
38
+ * `messages` is never renamed — its search index and triggers hang off it — so a difference there
39
+ * is reported, not rebuilt. With `dryRun` the same work runs and is rolled back, so the report is
40
+ * exact.
41
+ */
42
+ export declare const repairStore: (database: CacheDatabase, fresh: CacheDatabase, { dryRun }?: {
43
+ dryRun?: boolean;
44
+ }) => RepairReport;
45
+ /** Every repair copy in the file, with its rows. */
46
+ export declare const copiesIn: (database: CacheDatabase) => {
47
+ name: string;
48
+ rows: number;
49
+ }[];
50
+ /** Deletes one repair copy, named exactly; refuses anything else. */
51
+ export declare const deleteCopy: (database: CacheDatabase, name: string) => {
52
+ name: string;
53
+ rows: number;
54
+ };
55
+ //# sourceMappingURL=repair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repair.d.ts","sourceRoot":"","sources":["../../src/store/repair.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAGhD,eAAO,MAAM,SAAS,cAAc,CAAA;AAuBpC,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,SAAS,GAAG,eAAe,GAAG,SAAS,CAAA;IAC/C,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,0FAA0F;IAC1F,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,2GAA2G;IAC3G,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,UAAU,EAAE,QAAQ,EAAE,CAAA;IACtB,oBAAoB,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACvD,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CACzC;AAyID;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,aACZ,aAAa,SAChB,aAAa,eACA;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,KACvC,YAmKF,CAAA;AAED,oDAAoD;AACpD,eAAO,MAAM,QAAQ,aAAc,aAAa,KAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAKtB,CAAA;AAE3D,qEAAqE;AACrE,eAAO,MAAM,UAAU,aAAc,aAAa,QAAQ,MAAM,KAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAe9F,CAAA"}