@lacrous/omnicloud 0.2.22 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lacrous/omnicloud",
3
- "version": "0.2.22",
3
+ "version": "0.2.23",
4
4
  "description": "SDK and core building blocks for OmniCloud — self-hosted cloud storage powered by your Telegram account.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -48,9 +48,9 @@
48
48
  "prisma": "^6.2.0"
49
49
  },
50
50
  "devDependencies": {
51
- "@omnicloud/core": "0.2.22",
52
- "@omnicloud/shared": "0.2.22",
53
- "@omnicloud/telegram": "0.2.22",
51
+ "@omnicloud/core": "0.2.23",
52
+ "@omnicloud/shared": "0.2.23",
53
+ "@omnicloud/telegram": "0.2.23",
54
54
  "@types/node": "^22.10.0",
55
55
  "esbuild": "0.25.12",
56
56
  "tsup": "^8.3.0",
package/server/index.js CHANGED
@@ -1760,11 +1760,11 @@ var FolderService = class {
1760
1760
  const fileIds = await this.collectFileIds(userId, subtree);
1761
1761
  const batchId = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
1762
1762
  const stampedAt = /* @__PURE__ */ new Date();
1763
- await this.folders.updateMany(
1763
+ await this.folders.trashSubtree(
1764
1764
  subtree.map((folder) => folder.id),
1765
+ fileIds,
1765
1766
  { deletedAt: stampedAt, trashBatchId: batchId }
1766
1767
  );
1767
- await this.files.updateMany(fileIds, { deletedAt: stampedAt, trashBatchId: batchId });
1768
1768
  await this.activity.record({
1769
1769
  userId,
1770
1770
  action: "trash",
@@ -1833,9 +1833,16 @@ var FolderService = class {
1833
1833
  );
1834
1834
  const engine = await this.engineFor(userId);
1835
1835
  const removedFileIds = [];
1836
+ const versionsByFile = await this.files.listVersionsForFiles(affected.map((file) => file.id));
1836
1837
  for (const file of affected) {
1837
1838
  try {
1838
- await engine.remove({ messageId: String(file.telegramMessageId) });
1839
+ const messageIds = /* @__PURE__ */ new Set([String(file.telegramMessageId)]);
1840
+ for (const version of versionsByFile.get(file.id) ?? []) {
1841
+ messageIds.add(String(version.telegramMessageId));
1842
+ }
1843
+ for (const messageId of messageIds) {
1844
+ await engine.remove({ messageId });
1845
+ }
1839
1846
  removedFileIds.push(file.id);
1840
1847
  } catch {
1841
1848
  }
@@ -2478,6 +2485,13 @@ function mapTelegramError(error, fallbackMessage) {
2478
2485
  case "CHANNEL_INVALID":
2479
2486
  case "CHAT_ID_INVALID":
2480
2487
  return new StorageNotInitializedError();
2488
+ // Permanent: the account cannot write to the channel. Retrying cannot help.
2489
+ case "CHAT_WRITE_FORBIDDEN":
2490
+ case "CHAT_ADMIN_REQUIRED":
2491
+ return new ForbiddenError("OmniCloud cannot write to the storage channel for this account");
2492
+ // Permanent: the stored channel reference is stale. Retrying with the same reference fails too.
2493
+ case "PEER_ID_INVALID":
2494
+ return new StorageNotInitializedError();
2481
2495
  case "MSG_ID_INVALID":
2482
2496
  case "MESSAGE_ID_INVALID":
2483
2497
  return new TelegramFileNotFoundError();
@@ -3784,6 +3798,22 @@ function createFolderRepo(prisma) {
3784
3798
  });
3785
3799
  return mapFolder(folder);
3786
3800
  },
3801
+ async trashSubtree(folderIds, fileIds, stamp) {
3802
+ await prisma.$transaction(async (tx) => {
3803
+ if (folderIds.length > 0) {
3804
+ await tx.folder.updateMany({
3805
+ where: { id: { in: folderIds } },
3806
+ data: { deletedAt: stamp.deletedAt, trashBatchId: stamp.trashBatchId }
3807
+ });
3808
+ }
3809
+ if (fileIds.length > 0) {
3810
+ await tx.file.updateMany({
3811
+ where: { id: { in: fileIds } },
3812
+ data: { deletedAt: stamp.deletedAt, trashBatchId: stamp.trashBatchId }
3813
+ });
3814
+ }
3815
+ });
3816
+ },
3787
3817
  async updateMany(ids, patch) {
3788
3818
  const result = await prisma.folder.updateMany({
3789
3819
  where: { id: { in: ids } },
@@ -5038,7 +5068,7 @@ function encryptionCheck(configured) {
5038
5068
  }
5039
5069
 
5040
5070
  // ../../apps/api/src/routes/storage.ts
5041
- var VERSION = "0.2.22";
5071
+ var VERSION = "0.2.23";
5042
5072
  function registerStorageRoutes(app2, container2) {
5043
5073
  app2.get("/api/health", async () => {
5044
5074
  const database = await probeDatabase(container2);