@atproto/bsync 0.0.24 → 0.0.26-next.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 (137) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/bin/migration-create.ts +1 -1
  3. package/dist/client.d.ts +1 -1
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js +7 -12
  6. package/dist/client.js.map +1 -1
  7. package/dist/config.js +16 -24
  8. package/dist/config.js.map +1 -1
  9. package/dist/context.d.ts +6 -6
  10. package/dist/context.d.ts.map +1 -1
  11. package/dist/context.js +8 -36
  12. package/dist/context.js.map +1 -1
  13. package/dist/db/index.d.ts +6 -4
  14. package/dist/db/index.d.ts.map +1 -1
  15. package/dist/db/index.js +26 -101
  16. package/dist/db/index.js.map +1 -1
  17. package/dist/db/migrations/20240108T220751294Z-init.js +4 -8
  18. package/dist/db/migrations/20240108T220751294Z-init.js.map +1 -1
  19. package/dist/db/migrations/20240717T224303472Z-notif-ops.js +4 -8
  20. package/dist/db/migrations/20240717T224303472Z-notif-ops.js.map +1 -1
  21. package/dist/db/migrations/20250527T022203400Z-add-operation.js +5 -9
  22. package/dist/db/migrations/20250527T022203400Z-add-operation.js.map +1 -1
  23. package/dist/db/migrations/20250603T163446567Z-alter-operation.js +2 -6
  24. package/dist/db/migrations/20250603T163446567Z-alter-operation.js.map +1 -1
  25. package/dist/db/migrations/index.d.ts +4 -4
  26. package/dist/db/migrations/index.d.ts.map +1 -1
  27. package/dist/db/migrations/index.js +4 -40
  28. package/dist/db/migrations/index.js.map +1 -1
  29. package/dist/db/migrations/provider.js +2 -11
  30. package/dist/db/migrations/provider.js.map +1 -1
  31. package/dist/db/schema/index.d.ts +5 -5
  32. package/dist/db/schema/index.d.ts.map +1 -1
  33. package/dist/db/schema/index.js +1 -2
  34. package/dist/db/schema/index.js.map +1 -1
  35. package/dist/db/schema/mute_item.js +1 -4
  36. package/dist/db/schema/mute_item.js.map +1 -1
  37. package/dist/db/schema/mute_op.d.ts +1 -1
  38. package/dist/db/schema/mute_op.d.ts.map +1 -1
  39. package/dist/db/schema/mute_op.js +2 -5
  40. package/dist/db/schema/mute_op.js.map +1 -1
  41. package/dist/db/schema/notif_item.js +1 -4
  42. package/dist/db/schema/notif_item.js.map +1 -1
  43. package/dist/db/schema/notif_op.js +2 -5
  44. package/dist/db/schema/notif_op.js.map +1 -1
  45. package/dist/db/schema/operation.d.ts +2 -2
  46. package/dist/db/schema/operation.d.ts.map +1 -1
  47. package/dist/db/schema/operation.js +2 -5
  48. package/dist/db/schema/operation.js.map +1 -1
  49. package/dist/db/types.d.ts +3 -1
  50. package/dist/db/types.d.ts.map +1 -1
  51. package/dist/db/types.js +1 -2
  52. package/dist/db/types.js.map +1 -1
  53. package/dist/index.d.ts +7 -7
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +37 -88
  56. package/dist/index.js.map +1 -1
  57. package/dist/logger.js +8 -11
  58. package/dist/logger.js.map +1 -1
  59. package/dist/proto/bsync_connect.d.ts +10 -1
  60. package/dist/proto/bsync_connect.d.ts.map +1 -1
  61. package/dist/proto/bsync_connect.js +33 -27
  62. package/dist/proto/bsync_connect.js.map +1 -1
  63. package/dist/proto/bsync_pb.d.ts +38 -0
  64. package/dist/proto/bsync_pb.d.ts.map +1 -1
  65. package/dist/proto/bsync_pb.js +260 -680
  66. package/dist/proto/bsync_pb.js.map +1 -1
  67. package/dist/routes/add-mute-operation.d.ts +2 -2
  68. package/dist/routes/add-mute-operation.d.ts.map +1 -1
  69. package/dist/routes/add-mute-operation.js +28 -30
  70. package/dist/routes/add-mute-operation.js.map +1 -1
  71. package/dist/routes/add-notif-operation.d.ts +2 -2
  72. package/dist/routes/add-notif-operation.d.ts.map +1 -1
  73. package/dist/routes/add-notif-operation.js +14 -16
  74. package/dist/routes/add-notif-operation.js.map +1 -1
  75. package/dist/routes/auth.d.ts +1 -1
  76. package/dist/routes/auth.d.ts.map +1 -1
  77. package/dist/routes/auth.js +4 -8
  78. package/dist/routes/auth.js.map +1 -1
  79. package/dist/routes/delete-operations.d.ts +6 -0
  80. package/dist/routes/delete-operations.d.ts.map +1 -0
  81. package/dist/routes/delete-operations.js +36 -0
  82. package/dist/routes/delete-operations.js.map +1 -0
  83. package/dist/routes/index.d.ts +1 -1
  84. package/dist/routes/index.d.ts.map +1 -1
  85. package/dist/routes/index.js +19 -22
  86. package/dist/routes/index.js.map +1 -1
  87. package/dist/routes/put-operation.d.ts +2 -2
  88. package/dist/routes/put-operation.d.ts.map +1 -1
  89. package/dist/routes/put-operation.js +24 -37
  90. package/dist/routes/put-operation.js.map +1 -1
  91. package/dist/routes/scan-mute-operations.d.ts +2 -2
  92. package/dist/routes/scan-mute-operations.d.ts.map +1 -1
  93. package/dist/routes/scan-mute-operations.js +13 -15
  94. package/dist/routes/scan-mute-operations.js.map +1 -1
  95. package/dist/routes/scan-notif-operations.d.ts +2 -2
  96. package/dist/routes/scan-notif-operations.d.ts.map +1 -1
  97. package/dist/routes/scan-notif-operations.js +13 -15
  98. package/dist/routes/scan-notif-operations.js.map +1 -1
  99. package/dist/routes/scan-operations.d.ts +2 -2
  100. package/dist/routes/scan-operations.d.ts.map +1 -1
  101. package/dist/routes/scan-operations.js +13 -15
  102. package/dist/routes/scan-operations.js.map +1 -1
  103. package/dist/routes/util.d.ts +1 -0
  104. package/dist/routes/util.d.ts.map +1 -1
  105. package/dist/routes/util.js +21 -17
  106. package/dist/routes/util.js.map +1 -1
  107. package/{jest.config.js → jest.config.cjs} +8 -1
  108. package/package.json +14 -9
  109. package/proto/bsync.proto +10 -0
  110. package/src/client.ts +1 -1
  111. package/src/context.ts +7 -7
  112. package/src/db/index.ts +12 -8
  113. package/src/db/migrations/index.ts +4 -4
  114. package/src/db/schema/index.ts +5 -5
  115. package/src/db/schema/mute_op.ts +1 -1
  116. package/src/db/schema/operation.ts +2 -2
  117. package/src/db/types.ts +3 -1
  118. package/src/index.ts +17 -13
  119. package/src/proto/bsync_connect.ts +10 -1
  120. package/src/proto/bsync_pb.ts +80 -0
  121. package/src/routes/add-mute-operation.ts +10 -7
  122. package/src/routes/add-notif-operation.ts +7 -7
  123. package/src/routes/auth.ts +1 -1
  124. package/src/routes/delete-operations.ts +45 -0
  125. package/src/routes/index.ts +10 -8
  126. package/src/routes/put-operation.ts +12 -24
  127. package/src/routes/scan-mute-operations.ts +6 -6
  128. package/src/routes/scan-notif-operations.ts +6 -6
  129. package/src/routes/scan-operations.ts +6 -6
  130. package/src/routes/util.ts +16 -0
  131. package/tests/delete-operations.test.ts +108 -0
  132. package/tests/mutes.test.ts +2 -2
  133. package/tests/notifications.test.ts +2 -2
  134. package/tests/operations.test.ts +2 -2
  135. package/tsconfig.build.json +1 -1
  136. package/tsconfig.build.tsbuildinfo +1 -1
  137. package/tsconfig.tests.json +1 -1
@@ -0,0 +1,36 @@
1
+ import { Code, ConnectError } from '@connectrpc/connect';
2
+ import { DeleteOperationsByActorAndNamespaceResponse } from '../proto/bsync_pb.js';
3
+ import { authWithApiKey } from './auth.js';
4
+ import { isValidDid, validateNamespace } from './util.js';
5
+ export default (ctx) => ({
6
+ /**
7
+ * This method is responsible for deleting log rows from the bsync db, it has
8
+ * no other downstream effects. This method is called from the dataplane in
9
+ * response to a data deletion request initiated by a moderator in Ozone.
10
+ * It's the final step of the deletion process, basically cleaning up the
11
+ * breadcrumbs that resulted in the state we store in the dataplane.
12
+ */
13
+ async deleteOperationsByActorAndNamespace(req, handlerCtx) {
14
+ authWithApiKey(ctx, handlerCtx);
15
+ const { db } = ctx;
16
+ try {
17
+ validateNamespace(req.namespace);
18
+ }
19
+ catch (error) {
20
+ throw new ConnectError('requested namespace for deletion is invalid NSID', Code.InvalidArgument);
21
+ }
22
+ if (!isValidDid(req.actorDid)) {
23
+ throw new ConnectError('requested actor_did for deletion is invalid DID', Code.InvalidArgument);
24
+ }
25
+ const deletedRows = await db.db
26
+ .deleteFrom('operation')
27
+ .where('actorDid', '=', req.actorDid)
28
+ .where('namespace', '=', req.namespace)
29
+ .returning('id')
30
+ .execute();
31
+ return new DeleteOperationsByActorAndNamespaceResponse({
32
+ deletedCount: deletedRows.length,
33
+ });
34
+ },
35
+ });
36
+ //# sourceMappingURL=delete-operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-operations.js","sourceRoot":"","sources":["../../src/routes/delete-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,YAAY,EAAe,MAAM,qBAAqB,CAAA;AAGrE,OAAO,EAAE,2CAA2C,EAAE,MAAM,sBAAsB,CAAA;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAEzD,eAAe,CAAC,GAAe,EAAwC,EAAE,CAAC,CAAC;IACzE;;;;;;OAMG;IACH,KAAK,CAAC,mCAAmC,CAAC,GAAG,EAAE,UAAU;QACvD,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAC/B,MAAM,EAAE,EAAE,EAAE,GAAG,GAAG,CAAA;QAElB,IAAI,CAAC;YACH,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QAClC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,YAAY,CACpB,kDAAkD,EAClD,IAAI,CAAC,eAAe,CACrB,CAAA;QACH,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,YAAY,CACpB,iDAAiD,EACjD,IAAI,CAAC,eAAe,CACrB,CAAA;QACH,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,EAAE;aAC5B,UAAU,CAAC,WAAW,CAAC;aACvB,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC;aACpC,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,GAAG,CAAC,SAAS,CAAC;aACtC,SAAS,CAAC,IAAI,CAAC;aACf,OAAO,EAAE,CAAA;QACZ,OAAO,IAAI,2CAA2C,CAAC;YACrD,YAAY,EAAE,WAAW,CAAC,MAAM;SACjC,CAAC,CAAA;IACJ,CAAC;CACF,CAAC,CAAA","sourcesContent":["import { Code, ConnectError, ServiceImpl } from '@connectrpc/connect'\nimport { AppContext } from '../context.js'\nimport { Service } from '../proto/bsync_connect.js'\nimport { DeleteOperationsByActorAndNamespaceResponse } from '../proto/bsync_pb.js'\nimport { authWithApiKey } from './auth.js'\nimport { isValidDid, validateNamespace } from './util.js'\n\nexport default (ctx: AppContext): Partial<ServiceImpl<typeof Service>> => ({\n /**\n * This method is responsible for deleting log rows from the bsync db, it has\n * no other downstream effects. This method is called from the dataplane in\n * response to a data deletion request initiated by a moderator in Ozone.\n * It's the final step of the deletion process, basically cleaning up the\n * breadcrumbs that resulted in the state we store in the dataplane.\n */\n async deleteOperationsByActorAndNamespace(req, handlerCtx) {\n authWithApiKey(ctx, handlerCtx)\n const { db } = ctx\n\n try {\n validateNamespace(req.namespace)\n } catch (error) {\n throw new ConnectError(\n 'requested namespace for deletion is invalid NSID',\n Code.InvalidArgument,\n )\n }\n if (!isValidDid(req.actorDid)) {\n throw new ConnectError(\n 'requested actor_did for deletion is invalid DID',\n Code.InvalidArgument,\n )\n }\n\n const deletedRows = await db.db\n .deleteFrom('operation')\n .where('actorDid', '=', req.actorDid)\n .where('namespace', '=', req.namespace)\n .returning('id')\n .execute()\n return new DeleteOperationsByActorAndNamespaceResponse({\n deletedCount: deletedRows.length,\n })\n },\n})\n"]}
@@ -1,5 +1,5 @@
1
1
  import { ConnectRouter } from '@connectrpc/connect';
2
- import { AppContext } from '../context';
2
+ import { AppContext } from '../context.js';
3
3
  declare const _default: (ctx: AppContext) => (router: ConnectRouter) => ConnectRouter;
4
4
  export default _default;
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;yBASvB,KAAK,UAAU,MAAM,QAAQ,aAAa;AAA1D,wBAcC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;yBAU1B,KAAK,UAAU,MAAM,QAAQ,aAAa;AAA1D,wBAeC"}
@@ -1,27 +1,24 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const kysely_1 = require("kysely");
7
- const bsync_connect_1 = require("../proto/bsync_connect");
8
- const add_mute_operation_1 = __importDefault(require("./add-mute-operation"));
9
- const add_notif_operation_1 = __importDefault(require("./add-notif-operation"));
10
- const put_operation_1 = __importDefault(require("./put-operation"));
11
- const scan_mute_operations_1 = __importDefault(require("./scan-mute-operations"));
12
- const scan_notif_operations_1 = __importDefault(require("./scan-notif-operations"));
13
- const scan_operations_1 = __importDefault(require("./scan-operations"));
14
- exports.default = (ctx) => (router) => {
15
- return router.service(bsync_connect_1.Service, {
16
- ...(0, add_mute_operation_1.default)(ctx),
17
- ...(0, scan_mute_operations_1.default)(ctx),
18
- ...(0, add_notif_operation_1.default)(ctx),
19
- ...(0, scan_notif_operations_1.default)(ctx),
20
- ...(0, put_operation_1.default)(ctx),
21
- ...(0, scan_operations_1.default)(ctx),
1
+ import { sql } from 'kysely';
2
+ import { Service } from '../proto/bsync_connect.js';
3
+ import addMuteOperation from './add-mute-operation.js';
4
+ import addNotifOperation from './add-notif-operation.js';
5
+ import deleteOperations from './delete-operations.js';
6
+ import putOperation from './put-operation.js';
7
+ import scanMuteOperations from './scan-mute-operations.js';
8
+ import scanNotifOperations from './scan-notif-operations.js';
9
+ import scanOperations from './scan-operations.js';
10
+ export default (ctx) => (router) => {
11
+ return router.service(Service, {
12
+ ...addMuteOperation(ctx),
13
+ ...scanMuteOperations(ctx),
14
+ ...addNotifOperation(ctx),
15
+ ...scanNotifOperations(ctx),
16
+ ...putOperation(ctx),
17
+ ...scanOperations(ctx),
18
+ ...deleteOperations(ctx),
22
19
  async ping() {
23
20
  const { db } = ctx;
24
- await (0, kysely_1.sql) `select 1`.execute(db.db);
21
+ await sql `select 1`.execute(db.db);
25
22
  return {};
26
23
  },
27
24
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":";;;;;AACA,mCAA4B;AAE5B,0DAAgD;AAChD,8EAAmD;AACnD,gFAAqD;AACrD,oEAA0C;AAC1C,kFAAuD;AACvD,oFAAyD;AACzD,wEAA8C;AAE9C,kBAAe,CAAC,GAAe,EAAE,EAAE,CAAC,CAAC,MAAqB,EAAE,EAAE;IAC5D,OAAO,MAAM,CAAC,OAAO,CAAC,uBAAO,EAAE;QAC7B,GAAG,IAAA,4BAAgB,EAAC,GAAG,CAAC;QACxB,GAAG,IAAA,8BAAkB,EAAC,GAAG,CAAC;QAC1B,GAAG,IAAA,6BAAiB,EAAC,GAAG,CAAC;QACzB,GAAG,IAAA,+BAAmB,EAAC,GAAG,CAAC;QAC3B,GAAG,IAAA,uBAAY,EAAC,GAAG,CAAC;QACpB,GAAG,IAAA,yBAAc,EAAC,GAAG,CAAC;QACtB,KAAK,CAAC,IAAI;YACR,MAAM,EAAE,EAAE,EAAE,GAAG,GAAG,CAAA;YAClB,MAAM,IAAA,YAAG,EAAA,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;YAClC,OAAO,EAAE,CAAA;QACX,CAAC;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { ConnectRouter } from '@connectrpc/connect'\nimport { sql } from 'kysely'\nimport { AppContext } from '../context'\nimport { Service } from '../proto/bsync_connect'\nimport addMuteOperation from './add-mute-operation'\nimport addNotifOperation from './add-notif-operation'\nimport putOperation from './put-operation'\nimport scanMuteOperations from './scan-mute-operations'\nimport scanNotifOperations from './scan-notif-operations'\nimport scanOperations from './scan-operations'\n\nexport default (ctx: AppContext) => (router: ConnectRouter) => {\n return router.service(Service, {\n ...addMuteOperation(ctx),\n ...scanMuteOperations(ctx),\n ...addNotifOperation(ctx),\n ...scanNotifOperations(ctx),\n ...putOperation(ctx),\n ...scanOperations(ctx),\n async ping() {\n const { db } = ctx\n await sql`select 1`.execute(db.db)\n return {}\n },\n })\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA;AAE5B,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AACnD,OAAO,gBAAgB,MAAM,yBAAyB,CAAA;AACtD,OAAO,iBAAiB,MAAM,0BAA0B,CAAA;AACxD,OAAO,gBAAgB,MAAM,wBAAwB,CAAA;AACrD,OAAO,YAAY,MAAM,oBAAoB,CAAA;AAC7C,OAAO,kBAAkB,MAAM,2BAA2B,CAAA;AAC1D,OAAO,mBAAmB,MAAM,4BAA4B,CAAA;AAC5D,OAAO,cAAc,MAAM,sBAAsB,CAAA;AAEjD,eAAe,CAAC,GAAe,EAAE,EAAE,CAAC,CAAC,MAAqB,EAAE,EAAE;IAC5D,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE;QAC7B,GAAG,gBAAgB,CAAC,GAAG,CAAC;QACxB,GAAG,kBAAkB,CAAC,GAAG,CAAC;QAC1B,GAAG,iBAAiB,CAAC,GAAG,CAAC;QACzB,GAAG,mBAAmB,CAAC,GAAG,CAAC;QAC3B,GAAG,YAAY,CAAC,GAAG,CAAC;QACpB,GAAG,cAAc,CAAC,GAAG,CAAC;QACtB,GAAG,gBAAgB,CAAC,GAAG,CAAC;QACxB,KAAK,CAAC,IAAI;YACR,MAAM,EAAE,EAAE,EAAE,GAAG,GAAG,CAAA;YAClB,MAAM,GAAG,CAAA,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;YAClC,OAAO,EAAE,CAAA;QACX,CAAC;KACF,CAAC,CAAA;AACJ,CAAC,CAAA","sourcesContent":["import { ConnectRouter } from '@connectrpc/connect'\nimport { sql } from 'kysely'\nimport { AppContext } from '../context.js'\nimport { Service } from '../proto/bsync_connect.js'\nimport addMuteOperation from './add-mute-operation.js'\nimport addNotifOperation from './add-notif-operation.js'\nimport deleteOperations from './delete-operations.js'\nimport putOperation from './put-operation.js'\nimport scanMuteOperations from './scan-mute-operations.js'\nimport scanNotifOperations from './scan-notif-operations.js'\nimport scanOperations from './scan-operations.js'\n\nexport default (ctx: AppContext) => (router: ConnectRouter) => {\n return router.service(Service, {\n ...addMuteOperation(ctx),\n ...scanMuteOperations(ctx),\n ...addNotifOperation(ctx),\n ...scanNotifOperations(ctx),\n ...putOperation(ctx),\n ...scanOperations(ctx),\n ...deleteOperations(ctx),\n async ping() {\n const { db } = ctx\n await sql`select 1`.execute(db.db)\n return {}\n },\n })\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { ServiceImpl } from '@connectrpc/connect';
2
- import { AppContext } from '../context';
3
- import { Service } from '../proto/bsync_connect';
2
+ import { AppContext } from '../context.js';
3
+ import { Service } from '../proto/bsync_connect.js';
4
4
  declare const _default: (ctx: AppContext) => Partial<ServiceImpl<typeof Service>>;
5
5
  export default _default;
6
6
  //# sourceMappingURL=put-operation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"put-operation.d.ts","sourceRoot":"","sources":["../../src/routes/put-operation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAGrE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAGvC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;yBAShC,KAAK,UAAU,KAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AAAtE,wBAmBE"}
1
+ {"version":3,"file":"put-operation.d.ts","sourceRoot":"","sources":["../../src/routes/put-operation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAGrE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAM1C,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;yBASnC,KAAK,UAAU,KAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AAAtE,wBAmBE"}
@@ -1,21 +1,19 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const connect_1 = require("@connectrpc/connect");
4
- const kysely_1 = require("kysely");
5
- const syntax_1 = require("@atproto/syntax");
6
- const operation_1 = require("../db/schema/operation");
7
- const bsync_pb_1 = require("../proto/bsync_pb");
8
- const auth_1 = require("./auth");
9
- const util_1 = require("./util");
10
- exports.default = (ctx) => ({
1
+ import { Code, ConnectError } from '@connectrpc/connect';
2
+ import { sql } from 'kysely';
3
+ import { ensureValidRecordKey } from '@atproto/syntax';
4
+ import { createOperationChannel, } from '../db/schema/operation.js';
5
+ import { Method, PutOperationResponse, } from '../proto/bsync_pb.js';
6
+ import { authWithApiKey } from './auth.js';
7
+ import { isValidDid, validateNamespace } from './util.js';
8
+ export default (ctx) => ({
11
9
  async putOperation(req, handlerCtx) {
12
- (0, auth_1.authWithApiKey)(ctx, handlerCtx);
10
+ authWithApiKey(ctx, handlerCtx);
13
11
  const { db } = ctx;
14
12
  const op = validateOp(req);
15
13
  const id = await db.transaction(async (txn) => {
16
14
  return putOp(txn, op);
17
15
  });
18
- return new bsync_pb_1.PutOperationResponse({
16
+ return new PutOperationResponse({
19
17
  operation: {
20
18
  id: String(id),
21
19
  actorDid: op.actorDid,
@@ -40,7 +38,7 @@ const putOp = async (db, op) => {
40
38
  })
41
39
  .returning('id')
42
40
  .executeTakeFirstOrThrow();
43
- await (0, kysely_1.sql) `notify ${ref(operation_1.createOperationChannel)}`.execute(db.db); // emitted transactionally
41
+ await sql `notify ${ref(createOperationChannel)}`.execute(db.db); // emitted transactionally
44
42
  return id;
45
43
  };
46
44
  const validateOp = (req) => {
@@ -48,44 +46,33 @@ const validateOp = (req) => {
48
46
  validateNamespace(req.namespace);
49
47
  }
50
48
  catch (error) {
51
- throw new connect_1.ConnectError('operation namespace is invalid NSID', connect_1.Code.InvalidArgument);
49
+ throw new ConnectError('operation namespace is invalid NSID', Code.InvalidArgument);
52
50
  }
53
- if (!(0, util_1.isValidDid)(req.actorDid)) {
54
- throw new connect_1.ConnectError('operation actor_did is invalid DID', connect_1.Code.InvalidArgument);
51
+ if (!isValidDid(req.actorDid)) {
52
+ throw new ConnectError('operation actor_did is invalid DID', Code.InvalidArgument);
55
53
  }
56
54
  try {
57
- (0, syntax_1.ensureValidRecordKey)(req.key);
55
+ ensureValidRecordKey(req.key);
58
56
  }
59
57
  catch (error) {
60
- throw new connect_1.ConnectError('operation key is required', connect_1.Code.InvalidArgument);
58
+ throw new ConnectError('operation key is required', Code.InvalidArgument);
61
59
  }
62
- if (req.method !== bsync_pb_1.Method.CREATE &&
63
- req.method !== bsync_pb_1.Method.UPDATE &&
64
- req.method !== bsync_pb_1.Method.DELETE) {
65
- throw new connect_1.ConnectError('operation method is invalid', connect_1.Code.InvalidArgument);
60
+ if (req.method !== Method.CREATE &&
61
+ req.method !== Method.UPDATE &&
62
+ req.method !== Method.DELETE) {
63
+ throw new ConnectError('operation method is invalid', Code.InvalidArgument);
66
64
  }
67
- if (req.method === bsync_pb_1.Method.CREATE || req.method === bsync_pb_1.Method.UPDATE) {
65
+ if (req.method === Method.CREATE || req.method === Method.UPDATE) {
68
66
  try {
69
67
  JSON.parse(new TextDecoder().decode(req.payload));
70
68
  }
71
69
  catch (error) {
72
- throw new connect_1.ConnectError('payload must be a valid JSON when method is CREATE or UPDATE', connect_1.Code.InvalidArgument);
70
+ throw new ConnectError('payload must be a valid JSON when method is CREATE or UPDATE', Code.InvalidArgument);
73
71
  }
74
72
  }
75
- if (req.method === bsync_pb_1.Method.DELETE && req.payload.length > 0) {
76
- throw new connect_1.ConnectError('cannot specify a payload when method is DELETE', connect_1.Code.InvalidArgument);
73
+ if (req.method === Method.DELETE && req.payload.length > 0) {
74
+ throw new ConnectError('cannot specify a payload when method is DELETE', Code.InvalidArgument);
77
75
  }
78
76
  return req;
79
77
  };
80
- const validateNamespace = (namespace) => {
81
- const parts = namespace.split('#');
82
- if (parts.length !== 1 && parts.length !== 2) {
83
- throw new Error('namespace must be in the format "nsid[#fragment]"');
84
- }
85
- const [nsid, fragment] = parts;
86
- (0, syntax_1.ensureValidNsid)(nsid);
87
- if (fragment && !/^[a-zA-Z][a-zA-Z0-9]*$/.test(fragment)) {
88
- throw new Error('namespace fragment must be a valid identifier');
89
- }
90
- };
91
78
  //# sourceMappingURL=put-operation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"put-operation.js","sourceRoot":"","sources":["../../src/routes/put-operation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Code, ConnectError, ServiceImpl } from '@connectrpc/connect'\nimport { sql } from 'kysely'\nimport { ensureValidNsid, ensureValidRecordKey } from '@atproto/syntax'\nimport { AppContext } from '../context'\nimport { Database } from '../db'\nimport { OperationMethod, createOperationChannel } from '../db/schema/operation'\nimport { Service } from '../proto/bsync_connect'\nimport {\n Method,\n PutOperationRequest,\n PutOperationResponse,\n} from '../proto/bsync_pb'\nimport { authWithApiKey } from './auth'\nimport { isValidDid } from './util'\n\nexport default (ctx: AppContext): Partial<ServiceImpl<typeof Service>> => ({\n async putOperation(req, handlerCtx) {\n authWithApiKey(ctx, handlerCtx)\n const { db } = ctx\n const op = validateOp(req)\n const id = await db.transaction(async (txn) => {\n return putOp(txn, op)\n })\n return new PutOperationResponse({\n operation: {\n id: String(id),\n actorDid: op.actorDid,\n namespace: op.namespace,\n key: op.key,\n method: op.method,\n payload: op.payload,\n },\n })\n },\n})\n\nconst putOp = async (db: Database, op: Operation) => {\n const { ref } = db.db.dynamic\n const { id } = await db.db\n .insertInto('operation')\n .values({\n actorDid: op.actorDid,\n namespace: op.namespace,\n key: op.key,\n method: op.method,\n payload: op.payload,\n })\n .returning('id')\n .executeTakeFirstOrThrow()\n await sql`notify ${ref(createOperationChannel)}`.execute(db.db) // emitted transactionally\n return id\n}\n\nconst validateOp = (req: PutOperationRequest): Operation => {\n try {\n validateNamespace(req.namespace)\n } catch (error) {\n throw new ConnectError(\n 'operation namespace is invalid NSID',\n Code.InvalidArgument,\n )\n }\n\n if (!isValidDid(req.actorDid)) {\n throw new ConnectError(\n 'operation actor_did is invalid DID',\n Code.InvalidArgument,\n )\n }\n\n try {\n ensureValidRecordKey(req.key)\n } catch (error) {\n throw new ConnectError('operation key is required', Code.InvalidArgument)\n }\n\n if (\n req.method !== Method.CREATE &&\n req.method !== Method.UPDATE &&\n req.method !== Method.DELETE\n ) {\n throw new ConnectError('operation method is invalid', Code.InvalidArgument)\n }\n\n if (req.method === Method.CREATE || req.method === Method.UPDATE) {\n try {\n JSON.parse(new TextDecoder().decode(req.payload))\n } catch (error) {\n throw new ConnectError(\n 'payload must be a valid JSON when method is CREATE or UPDATE',\n Code.InvalidArgument,\n )\n }\n }\n\n if (req.method === Method.DELETE && req.payload.length > 0) {\n throw new ConnectError(\n 'cannot specify a payload when method is DELETE',\n Code.InvalidArgument,\n )\n }\n\n return req as Operation\n}\n\nconst validateNamespace = (namespace: string): void => {\n const parts = namespace.split('#')\n\n if (parts.length !== 1 && parts.length !== 2) {\n throw new Error('namespace must be in the format \"nsid[#fragment]\"')\n }\n\n const [nsid, fragment] = parts\n\n ensureValidNsid(nsid)\n if (fragment && !/^[a-zA-Z][a-zA-Z0-9]*$/.test(fragment)) {\n throw new Error('namespace fragment must be a valid identifier')\n }\n}\n\ntype Operation = {\n actorDid: string\n namespace: string\n key: string\n payload: Uint8Array\n method: OperationMethod\n}\n"]}
1
+ {"version":3,"file":"put-operation.js","sourceRoot":"","sources":["../../src/routes/put-operation.ts"],"names":[],"mappings":"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","sourcesContent":["import { Code, ConnectError, ServiceImpl } from '@connectrpc/connect'\nimport { sql } from 'kysely'\nimport { ensureValidRecordKey } from '@atproto/syntax'\nimport { AppContext } from '../context.js'\nimport { Database } from '../db/index.js'\nimport {\n OperationMethod,\n createOperationChannel,\n} from '../db/schema/operation.js'\nimport { Service } from '../proto/bsync_connect.js'\nimport {\n Method,\n PutOperationRequest,\n PutOperationResponse,\n} from '../proto/bsync_pb.js'\nimport { authWithApiKey } from './auth.js'\nimport { isValidDid, validateNamespace } from './util.js'\n\nexport default (ctx: AppContext): Partial<ServiceImpl<typeof Service>> => ({\n async putOperation(req, handlerCtx) {\n authWithApiKey(ctx, handlerCtx)\n const { db } = ctx\n const op = validateOp(req)\n const id = await db.transaction(async (txn) => {\n return putOp(txn, op)\n })\n return new PutOperationResponse({\n operation: {\n id: String(id),\n actorDid: op.actorDid,\n namespace: op.namespace,\n key: op.key,\n method: op.method,\n payload: op.payload,\n },\n })\n },\n})\n\nconst putOp = async (db: Database, op: Operation) => {\n const { ref } = db.db.dynamic\n const { id } = await db.db\n .insertInto('operation')\n .values({\n actorDid: op.actorDid,\n namespace: op.namespace,\n key: op.key,\n method: op.method,\n payload: op.payload,\n })\n .returning('id')\n .executeTakeFirstOrThrow()\n await sql`notify ${ref(createOperationChannel)}`.execute(db.db) // emitted transactionally\n return id\n}\n\nconst validateOp = (req: PutOperationRequest): Operation => {\n try {\n validateNamespace(req.namespace)\n } catch (error) {\n throw new ConnectError(\n 'operation namespace is invalid NSID',\n Code.InvalidArgument,\n )\n }\n\n if (!isValidDid(req.actorDid)) {\n throw new ConnectError(\n 'operation actor_did is invalid DID',\n Code.InvalidArgument,\n )\n }\n\n try {\n ensureValidRecordKey(req.key)\n } catch (error) {\n throw new ConnectError('operation key is required', Code.InvalidArgument)\n }\n\n if (\n req.method !== Method.CREATE &&\n req.method !== Method.UPDATE &&\n req.method !== Method.DELETE\n ) {\n throw new ConnectError('operation method is invalid', Code.InvalidArgument)\n }\n\n if (req.method === Method.CREATE || req.method === Method.UPDATE) {\n try {\n JSON.parse(new TextDecoder().decode(req.payload))\n } catch (error) {\n throw new ConnectError(\n 'payload must be a valid JSON when method is CREATE or UPDATE',\n Code.InvalidArgument,\n )\n }\n }\n\n if (req.method === Method.DELETE && req.payload.length > 0) {\n throw new ConnectError(\n 'cannot specify a payload when method is DELETE',\n Code.InvalidArgument,\n )\n }\n\n return req as Operation\n}\n\ntype Operation = {\n actorDid: string\n namespace: string\n key: string\n payload: Uint8Array<ArrayBuffer>\n method: OperationMethod\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { ServiceImpl } from '@connectrpc/connect';
2
- import { AppContext } from '../context';
3
- import { Service } from '../proto/bsync_connect';
2
+ import { AppContext } from '../context.js';
3
+ import { Service } from '../proto/bsync_connect.js';
4
4
  declare const _default: (ctx: AppContext) => Partial<ServiceImpl<typeof Service>>;
5
5
  export default _default;
6
6
  //# sourceMappingURL=scan-mute-operations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scan-mute-operations.d.ts","sourceRoot":"","sources":["../../src/routes/scan-mute-operations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;yBAKhC,KAAK,UAAU,KAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AAAtE,wBAuDE"}
1
+ {"version":3,"file":"scan-mute-operations.d.ts","sourceRoot":"","sources":["../../src/routes/scan-mute-operations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;yBAKnC,KAAK,UAAU,KAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AAAtE,wBAuDE"}
@@ -1,18 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const node_events_1 = require("node:events");
4
- const mute_op_1 = require("../db/schema/mute_op");
5
- const bsync_pb_1 = require("../proto/bsync_pb");
6
- const auth_1 = require("./auth");
7
- const util_1 = require("./util");
8
- exports.default = (ctx) => ({
1
+ import { once } from 'node:events';
2
+ import { createMuteOpChannel } from '../db/schema/mute_op.js';
3
+ import { ScanMuteOperationsResponse } from '../proto/bsync_pb.js';
4
+ import { authWithApiKey } from './auth.js';
5
+ import { combineSignals, validCursor } from './util.js';
6
+ export default (ctx) => ({
9
7
  async scanMuteOperations(req, handlerCtx) {
10
- (0, auth_1.authWithApiKey)(ctx, handlerCtx);
8
+ authWithApiKey(ctx, handlerCtx);
11
9
  const { db, events } = ctx;
12
10
  const limit = req.limit || 1000;
13
- const cursor = (0, util_1.validCursor)(req.cursor);
14
- const nextMuteOpPromise = (0, node_events_1.once)(events, mute_op_1.createMuteOpChannel, {
15
- signal: (0, util_1.combineSignals)(ctx.shutdown, AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs)),
11
+ const cursor = validCursor(req.cursor);
12
+ const nextMuteOpPromise = once(events, createMuteOpChannel, {
13
+ signal: combineSignals(ctx.shutdown, AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs)),
16
14
  });
17
15
  nextMuteOpPromise.catch(() => null); // ensure timeout is always handled
18
16
  const nextMuteOpPageQb = db.db
@@ -29,21 +27,21 @@ exports.default = (ctx) => ({
29
27
  }
30
28
  catch (err) {
31
29
  ctx.shutdown.throwIfAborted();
32
- return new bsync_pb_1.ScanMuteOperationsResponse({
30
+ return new ScanMuteOperationsResponse({
33
31
  operations: [],
34
32
  cursor: req.cursor,
35
33
  });
36
34
  }
37
35
  ops = await nextMuteOpPageQb.execute();
38
36
  if (!ops.length) {
39
- return new bsync_pb_1.ScanMuteOperationsResponse({
37
+ return new ScanMuteOperationsResponse({
40
38
  operations: [],
41
39
  cursor: req.cursor,
42
40
  });
43
41
  }
44
42
  }
45
43
  const lastOp = ops[ops.length - 1];
46
- return new bsync_pb_1.ScanMuteOperationsResponse({
44
+ return new ScanMuteOperationsResponse({
47
45
  operations: ops.map((op) => ({
48
46
  id: op.id.toString(),
49
47
  type: op.type,
@@ -1 +1 @@
1
- {"version":3,"file":"scan-mute-operations.js","sourceRoot":"","sources":["../../src/routes/scan-mute-operations.ts"],"names":[],"mappings":";;AAAA,6CAAkC;AAGlC,kDAA0D;AAE1D,gDAA8D;AAC9D,iCAAuC;AACvC,iCAAoD;AAEpD,kBAAe,CAAC,GAAe,EAAwC,EAAE,CAAC,CAAC;IACzE,KAAK,CAAC,kBAAkB,CAAC,GAAG,EAAE,UAAU;QACtC,IAAA,qBAAc,EAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAC/B,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;QAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,CAAA;QAC/B,MAAM,MAAM,GAAG,IAAA,kBAAW,EAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,iBAAiB,GAAG,IAAA,kBAAI,EAAC,MAAM,EAAE,6BAAmB,EAAE;YAC1D,MAAM,EAAE,IAAA,qBAAc,EACpB,GAAG,CAAC,QAAQ,EACZ,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CACvD;SACF,CAAC,CAAA;QACF,iBAAiB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA,CAAC,mCAAmC;QAEvE,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE;aAC3B,UAAU,CAAC,SAAS,CAAC;aACrB,SAAS,EAAE;aACX,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;aAC9B,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;aACpB,KAAK,CAAC,KAAK,CAAC,CAAA;QAEf,IAAI,GAAG,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAA;QAE1C,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAChB,sEAAsE;YACtE,IAAI,CAAC;gBACH,MAAM,iBAAiB,CAAA;YACzB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAA;gBAC7B,OAAO,IAAI,qCAA0B,CAAC;oBACpC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;YACD,GAAG,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAA;YACtC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;gBAChB,OAAO,IAAI,qCAA0B,CAAC;oBACpC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAElC,OAAO,IAAI,qCAA0B,CAAC;YACpC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC3B,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE;gBACpB,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,OAAO,EAAE,EAAE,CAAC,OAAO;aACpB,CAAC,CAAC;YACH,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE;SAC7B,CAAC,CAAA;IACJ,CAAC;CACF,CAAC,CAAA","sourcesContent":["import { once } from 'node:events'\nimport { ServiceImpl } from '@connectrpc/connect'\nimport { AppContext } from '../context'\nimport { createMuteOpChannel } from '../db/schema/mute_op'\nimport { Service } from '../proto/bsync_connect'\nimport { ScanMuteOperationsResponse } from '../proto/bsync_pb'\nimport { authWithApiKey } from './auth'\nimport { combineSignals, validCursor } from './util'\n\nexport default (ctx: AppContext): Partial<ServiceImpl<typeof Service>> => ({\n async scanMuteOperations(req, handlerCtx) {\n authWithApiKey(ctx, handlerCtx)\n const { db, events } = ctx\n const limit = req.limit || 1000\n const cursor = validCursor(req.cursor)\n const nextMuteOpPromise = once(events, createMuteOpChannel, {\n signal: combineSignals(\n ctx.shutdown,\n AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs),\n ),\n })\n nextMuteOpPromise.catch(() => null) // ensure timeout is always handled\n\n const nextMuteOpPageQb = db.db\n .selectFrom('mute_op')\n .selectAll()\n .where('id', '>', cursor ?? -1)\n .orderBy('id', 'asc')\n .limit(limit)\n\n let ops = await nextMuteOpPageQb.execute()\n\n if (!ops.length) {\n // if there were no ops on the page, wait for an event then try again.\n try {\n await nextMuteOpPromise\n } catch (err) {\n ctx.shutdown.throwIfAborted()\n return new ScanMuteOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n ops = await nextMuteOpPageQb.execute()\n if (!ops.length) {\n return new ScanMuteOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n }\n\n const lastOp = ops[ops.length - 1]\n\n return new ScanMuteOperationsResponse({\n operations: ops.map((op) => ({\n id: op.id.toString(),\n type: op.type,\n actorDid: op.actorDid,\n subject: op.subject,\n })),\n cursor: lastOp.id.toString(),\n })\n },\n})\n"]}
1
+ {"version":3,"file":"scan-mute-operations.js","sourceRoot":"","sources":["../../src/routes/scan-mute-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAGlC,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAE7D,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAA;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvD,eAAe,CAAC,GAAe,EAAwC,EAAE,CAAC,CAAC;IACzE,KAAK,CAAC,kBAAkB,CAAC,GAAG,EAAE,UAAU;QACtC,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAC/B,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;QAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,CAAA;QAC/B,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,iBAAiB,GAAG,IAAI,CAAC,MAAM,EAAE,mBAAmB,EAAE;YAC1D,MAAM,EAAE,cAAc,CACpB,GAAG,CAAC,QAAQ,EACZ,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CACvD;SACF,CAAC,CAAA;QACF,iBAAiB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA,CAAC,mCAAmC;QAEvE,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE;aAC3B,UAAU,CAAC,SAAS,CAAC;aACrB,SAAS,EAAE;aACX,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;aAC9B,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;aACpB,KAAK,CAAC,KAAK,CAAC,CAAA;QAEf,IAAI,GAAG,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAA;QAE1C,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAChB,sEAAsE;YACtE,IAAI,CAAC;gBACH,MAAM,iBAAiB,CAAA;YACzB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAA;gBAC7B,OAAO,IAAI,0BAA0B,CAAC;oBACpC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;YACD,GAAG,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,CAAA;YACtC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;gBAChB,OAAO,IAAI,0BAA0B,CAAC;oBACpC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAElC,OAAO,IAAI,0BAA0B,CAAC;YACpC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC3B,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE;gBACpB,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,OAAO,EAAE,EAAE,CAAC,OAAO;aACpB,CAAC,CAAC;YACH,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE;SAC7B,CAAC,CAAA;IACJ,CAAC;CACF,CAAC,CAAA","sourcesContent":["import { once } from 'node:events'\nimport { ServiceImpl } from '@connectrpc/connect'\nimport { AppContext } from '../context.js'\nimport { createMuteOpChannel } from '../db/schema/mute_op.js'\nimport { Service } from '../proto/bsync_connect.js'\nimport { ScanMuteOperationsResponse } from '../proto/bsync_pb.js'\nimport { authWithApiKey } from './auth.js'\nimport { combineSignals, validCursor } from './util.js'\n\nexport default (ctx: AppContext): Partial<ServiceImpl<typeof Service>> => ({\n async scanMuteOperations(req, handlerCtx) {\n authWithApiKey(ctx, handlerCtx)\n const { db, events } = ctx\n const limit = req.limit || 1000\n const cursor = validCursor(req.cursor)\n const nextMuteOpPromise = once(events, createMuteOpChannel, {\n signal: combineSignals(\n ctx.shutdown,\n AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs),\n ),\n })\n nextMuteOpPromise.catch(() => null) // ensure timeout is always handled\n\n const nextMuteOpPageQb = db.db\n .selectFrom('mute_op')\n .selectAll()\n .where('id', '>', cursor ?? -1)\n .orderBy('id', 'asc')\n .limit(limit)\n\n let ops = await nextMuteOpPageQb.execute()\n\n if (!ops.length) {\n // if there were no ops on the page, wait for an event then try again.\n try {\n await nextMuteOpPromise\n } catch (err) {\n ctx.shutdown.throwIfAborted()\n return new ScanMuteOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n ops = await nextMuteOpPageQb.execute()\n if (!ops.length) {\n return new ScanMuteOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n }\n\n const lastOp = ops[ops.length - 1]\n\n return new ScanMuteOperationsResponse({\n operations: ops.map((op) => ({\n id: op.id.toString(),\n type: op.type,\n actorDid: op.actorDid,\n subject: op.subject,\n })),\n cursor: lastOp.id.toString(),\n })\n },\n})\n"]}
@@ -1,6 +1,6 @@
1
1
  import { ServiceImpl } from '@connectrpc/connect';
2
- import { AppContext } from '../context';
3
- import { Service } from '../proto/bsync_connect';
2
+ import { AppContext } from '../context.js';
3
+ import { Service } from '../proto/bsync_connect.js';
4
4
  declare const _default: (ctx: AppContext) => Partial<ServiceImpl<typeof Service>>;
5
5
  export default _default;
6
6
  //# sourceMappingURL=scan-notif-operations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scan-notif-operations.d.ts","sourceRoot":"","sources":["../../src/routes/scan-notif-operations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;yBAKhC,KAAK,UAAU,KAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AAAtE,wBAsDE"}
1
+ {"version":3,"file":"scan-notif-operations.d.ts","sourceRoot":"","sources":["../../src/routes/scan-notif-operations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;yBAKnC,KAAK,UAAU,KAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AAAtE,wBAsDE"}
@@ -1,18 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const node_events_1 = require("node:events");
4
- const notif_op_1 = require("../db/schema/notif_op");
5
- const bsync_pb_1 = require("../proto/bsync_pb");
6
- const auth_1 = require("./auth");
7
- const util_1 = require("./util");
8
- exports.default = (ctx) => ({
1
+ import { once } from 'node:events';
2
+ import { createNotifOpChannel } from '../db/schema/notif_op.js';
3
+ import { ScanNotifOperationsResponse } from '../proto/bsync_pb.js';
4
+ import { authWithApiKey } from './auth.js';
5
+ import { combineSignals, validCursor } from './util.js';
6
+ export default (ctx) => ({
9
7
  async scanNotifOperations(req, handlerCtx) {
10
- (0, auth_1.authWithApiKey)(ctx, handlerCtx);
8
+ authWithApiKey(ctx, handlerCtx);
11
9
  const { db, events } = ctx;
12
10
  const limit = req.limit || 1000;
13
- const cursor = (0, util_1.validCursor)(req.cursor);
14
- const nextNotifOpPromise = (0, node_events_1.once)(events, notif_op_1.createNotifOpChannel, {
15
- signal: (0, util_1.combineSignals)(ctx.shutdown, AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs)),
11
+ const cursor = validCursor(req.cursor);
12
+ const nextNotifOpPromise = once(events, createNotifOpChannel, {
13
+ signal: combineSignals(ctx.shutdown, AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs)),
16
14
  });
17
15
  nextNotifOpPromise.catch(() => null); // ensure timeout is always handled
18
16
  const nextNotifOpPageQb = db.db
@@ -29,21 +27,21 @@ exports.default = (ctx) => ({
29
27
  }
30
28
  catch (err) {
31
29
  ctx.shutdown.throwIfAborted();
32
- return new bsync_pb_1.ScanNotifOperationsResponse({
30
+ return new ScanNotifOperationsResponse({
33
31
  operations: [],
34
32
  cursor: req.cursor,
35
33
  });
36
34
  }
37
35
  ops = await nextNotifOpPageQb.execute();
38
36
  if (!ops.length) {
39
- return new bsync_pb_1.ScanNotifOperationsResponse({
37
+ return new ScanNotifOperationsResponse({
40
38
  operations: [],
41
39
  cursor: req.cursor,
42
40
  });
43
41
  }
44
42
  }
45
43
  const lastOp = ops[ops.length - 1];
46
- return new bsync_pb_1.ScanNotifOperationsResponse({
44
+ return new ScanNotifOperationsResponse({
47
45
  operations: ops.map((op) => ({
48
46
  id: op.id.toString(),
49
47
  actorDid: op.actorDid,
@@ -1 +1 @@
1
- {"version":3,"file":"scan-notif-operations.js","sourceRoot":"","sources":["../../src/routes/scan-notif-operations.ts"],"names":[],"mappings":";;AAAA,6CAAkC;AAGlC,oDAA4D;AAE5D,gDAA+D;AAC/D,iCAAuC;AACvC,iCAAoD;AAEpD,kBAAe,CAAC,GAAe,EAAwC,EAAE,CAAC,CAAC;IACzE,KAAK,CAAC,mBAAmB,CAAC,GAAG,EAAE,UAAU;QACvC,IAAA,qBAAc,EAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAC/B,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;QAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,CAAA;QAC/B,MAAM,MAAM,GAAG,IAAA,kBAAW,EAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,kBAAkB,GAAG,IAAA,kBAAI,EAAC,MAAM,EAAE,+BAAoB,EAAE;YAC5D,MAAM,EAAE,IAAA,qBAAc,EACpB,GAAG,CAAC,QAAQ,EACZ,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CACvD;SACF,CAAC,CAAA;QACF,kBAAkB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA,CAAC,mCAAmC;QAExE,MAAM,iBAAiB,GAAG,EAAE,CAAC,EAAE;aAC5B,UAAU,CAAC,UAAU,CAAC;aACtB,SAAS,EAAE;aACX,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;aAC9B,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;aACpB,KAAK,CAAC,KAAK,CAAC,CAAA;QAEf,IAAI,GAAG,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,CAAA;QAE3C,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAChB,sEAAsE;YACtE,IAAI,CAAC;gBACH,MAAM,kBAAkB,CAAA;YAC1B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAA;gBAC7B,OAAO,IAAI,sCAA2B,CAAC;oBACrC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;YACD,GAAG,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,CAAA;YACvC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;gBAChB,OAAO,IAAI,sCAA2B,CAAC;oBACrC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAElC,OAAO,IAAI,sCAA2B,CAAC;YACrC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC3B,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE;gBACpB,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,QAAQ,EAAE,EAAE,CAAC,QAAQ,IAAI,SAAS;aACnC,CAAC,CAAC;YACH,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE;SAC7B,CAAC,CAAA;IACJ,CAAC;CACF,CAAC,CAAA","sourcesContent":["import { once } from 'node:events'\nimport { ServiceImpl } from '@connectrpc/connect'\nimport { AppContext } from '../context'\nimport { createNotifOpChannel } from '../db/schema/notif_op'\nimport { Service } from '../proto/bsync_connect'\nimport { ScanNotifOperationsResponse } from '../proto/bsync_pb'\nimport { authWithApiKey } from './auth'\nimport { combineSignals, validCursor } from './util'\n\nexport default (ctx: AppContext): Partial<ServiceImpl<typeof Service>> => ({\n async scanNotifOperations(req, handlerCtx) {\n authWithApiKey(ctx, handlerCtx)\n const { db, events } = ctx\n const limit = req.limit || 1000\n const cursor = validCursor(req.cursor)\n const nextNotifOpPromise = once(events, createNotifOpChannel, {\n signal: combineSignals(\n ctx.shutdown,\n AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs),\n ),\n })\n nextNotifOpPromise.catch(() => null) // ensure timeout is always handled\n\n const nextNotifOpPageQb = db.db\n .selectFrom('notif_op')\n .selectAll()\n .where('id', '>', cursor ?? -1)\n .orderBy('id', 'asc')\n .limit(limit)\n\n let ops = await nextNotifOpPageQb.execute()\n\n if (!ops.length) {\n // if there were no ops on the page, wait for an event then try again.\n try {\n await nextNotifOpPromise\n } catch (err) {\n ctx.shutdown.throwIfAborted()\n return new ScanNotifOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n ops = await nextNotifOpPageQb.execute()\n if (!ops.length) {\n return new ScanNotifOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n }\n\n const lastOp = ops[ops.length - 1]\n\n return new ScanNotifOperationsResponse({\n operations: ops.map((op) => ({\n id: op.id.toString(),\n actorDid: op.actorDid,\n priority: op.priority ?? undefined,\n })),\n cursor: lastOp.id.toString(),\n })\n },\n})\n"]}
1
+ {"version":3,"file":"scan-notif-operations.js","sourceRoot":"","sources":["../../src/routes/scan-notif-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAGlC,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAA;AAE/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvD,eAAe,CAAC,GAAe,EAAwC,EAAE,CAAC,CAAC;IACzE,KAAK,CAAC,mBAAmB,CAAC,GAAG,EAAE,UAAU;QACvC,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAC/B,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;QAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,CAAA;QAC/B,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,kBAAkB,GAAG,IAAI,CAAC,MAAM,EAAE,oBAAoB,EAAE;YAC5D,MAAM,EAAE,cAAc,CACpB,GAAG,CAAC,QAAQ,EACZ,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CACvD;SACF,CAAC,CAAA;QACF,kBAAkB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA,CAAC,mCAAmC;QAExE,MAAM,iBAAiB,GAAG,EAAE,CAAC,EAAE;aAC5B,UAAU,CAAC,UAAU,CAAC;aACtB,SAAS,EAAE;aACX,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;aAC9B,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;aACpB,KAAK,CAAC,KAAK,CAAC,CAAA;QAEf,IAAI,GAAG,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,CAAA;QAE3C,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAChB,sEAAsE;YACtE,IAAI,CAAC;gBACH,MAAM,kBAAkB,CAAA;YAC1B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAA;gBAC7B,OAAO,IAAI,2BAA2B,CAAC;oBACrC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;YACD,GAAG,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,CAAA;YACvC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;gBAChB,OAAO,IAAI,2BAA2B,CAAC;oBACrC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAElC,OAAO,IAAI,2BAA2B,CAAC;YACrC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC3B,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE;gBACpB,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,QAAQ,EAAE,EAAE,CAAC,QAAQ,IAAI,SAAS;aACnC,CAAC,CAAC;YACH,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE;SAC7B,CAAC,CAAA;IACJ,CAAC;CACF,CAAC,CAAA","sourcesContent":["import { once } from 'node:events'\nimport { ServiceImpl } from '@connectrpc/connect'\nimport { AppContext } from '../context.js'\nimport { createNotifOpChannel } from '../db/schema/notif_op.js'\nimport { Service } from '../proto/bsync_connect.js'\nimport { ScanNotifOperationsResponse } from '../proto/bsync_pb.js'\nimport { authWithApiKey } from './auth.js'\nimport { combineSignals, validCursor } from './util.js'\n\nexport default (ctx: AppContext): Partial<ServiceImpl<typeof Service>> => ({\n async scanNotifOperations(req, handlerCtx) {\n authWithApiKey(ctx, handlerCtx)\n const { db, events } = ctx\n const limit = req.limit || 1000\n const cursor = validCursor(req.cursor)\n const nextNotifOpPromise = once(events, createNotifOpChannel, {\n signal: combineSignals(\n ctx.shutdown,\n AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs),\n ),\n })\n nextNotifOpPromise.catch(() => null) // ensure timeout is always handled\n\n const nextNotifOpPageQb = db.db\n .selectFrom('notif_op')\n .selectAll()\n .where('id', '>', cursor ?? -1)\n .orderBy('id', 'asc')\n .limit(limit)\n\n let ops = await nextNotifOpPageQb.execute()\n\n if (!ops.length) {\n // if there were no ops on the page, wait for an event then try again.\n try {\n await nextNotifOpPromise\n } catch (err) {\n ctx.shutdown.throwIfAborted()\n return new ScanNotifOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n ops = await nextNotifOpPageQb.execute()\n if (!ops.length) {\n return new ScanNotifOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n }\n\n const lastOp = ops[ops.length - 1]\n\n return new ScanNotifOperationsResponse({\n operations: ops.map((op) => ({\n id: op.id.toString(),\n actorDid: op.actorDid,\n priority: op.priority ?? undefined,\n })),\n cursor: lastOp.id.toString(),\n })\n },\n})\n"]}
@@ -1,6 +1,6 @@
1
1
  import { ServiceImpl } from '@connectrpc/connect';
2
- import { AppContext } from '../context';
3
- import { Service } from '../proto/bsync_connect';
2
+ import { AppContext } from '../context.js';
3
+ import { Service } from '../proto/bsync_connect.js';
4
4
  declare const _default: (ctx: AppContext) => Partial<ServiceImpl<typeof Service>>;
5
5
  export default _default;
6
6
  //# sourceMappingURL=scan-operations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scan-operations.d.ts","sourceRoot":"","sources":["../../src/routes/scan-operations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAEvC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAA;yBAKhC,KAAK,UAAU,KAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AAAtE,wBAyDE"}
1
+ {"version":3,"file":"scan-operations.d.ts","sourceRoot":"","sources":["../../src/routes/scan-operations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;yBAKnC,KAAK,UAAU,KAAG,OAAO,CAAC,WAAW,CAAC,OAAO,OAAO,CAAC,CAAC;AAAtE,wBAyDE"}
@@ -1,18 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const node_events_1 = require("node:events");
4
- const operation_1 = require("../db/schema/operation");
5
- const bsync_pb_1 = require("../proto/bsync_pb");
6
- const auth_1 = require("./auth");
7
- const util_1 = require("./util");
8
- exports.default = (ctx) => ({
1
+ import { once } from 'node:events';
2
+ import { createOperationChannel } from '../db/schema/operation.js';
3
+ import { ScanOperationsResponse } from '../proto/bsync_pb.js';
4
+ import { authWithApiKey } from './auth.js';
5
+ import { combineSignals, validCursor } from './util.js';
6
+ export default (ctx) => ({
9
7
  async scanOperations(req, handlerCtx) {
10
- (0, auth_1.authWithApiKey)(ctx, handlerCtx);
8
+ authWithApiKey(ctx, handlerCtx);
11
9
  const { db, events } = ctx;
12
10
  const limit = req.limit || 1000;
13
- const cursor = (0, util_1.validCursor)(req.cursor);
14
- const nextOpPromise = (0, node_events_1.once)(events, operation_1.createOperationChannel, {
15
- signal: (0, util_1.combineSignals)(ctx.shutdown, AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs)),
11
+ const cursor = validCursor(req.cursor);
12
+ const nextOpPromise = once(events, createOperationChannel, {
13
+ signal: combineSignals(ctx.shutdown, AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs)),
16
14
  });
17
15
  nextOpPromise.catch(() => null); // ensure timeout is always handled
18
16
  const nextOpPageQb = db.db
@@ -29,21 +27,21 @@ exports.default = (ctx) => ({
29
27
  }
30
28
  catch (err) {
31
29
  ctx.shutdown.throwIfAborted();
32
- return new bsync_pb_1.ScanOperationsResponse({
30
+ return new ScanOperationsResponse({
33
31
  operations: [],
34
32
  cursor: req.cursor,
35
33
  });
36
34
  }
37
35
  ops = await nextOpPageQb.execute();
38
36
  if (!ops.length) {
39
- return new bsync_pb_1.ScanOperationsResponse({
37
+ return new ScanOperationsResponse({
40
38
  operations: [],
41
39
  cursor: req.cursor,
42
40
  });
43
41
  }
44
42
  }
45
43
  const lastOp = ops[ops.length - 1];
46
- return new bsync_pb_1.ScanOperationsResponse({
44
+ return new ScanOperationsResponse({
47
45
  operations: ops.map((op) => ({
48
46
  id: op.id.toString(),
49
47
  actorDid: op.actorDid,
@@ -1 +1 @@
1
- {"version":3,"file":"scan-operations.js","sourceRoot":"","sources":["../../src/routes/scan-operations.ts"],"names":[],"mappings":";;AAAA,6CAAkC;AAGlC,sDAA+D;AAE/D,gDAA0D;AAC1D,iCAAuC;AACvC,iCAAoD;AAEpD,kBAAe,CAAC,GAAe,EAAwC,EAAE,CAAC,CAAC;IACzE,KAAK,CAAC,cAAc,CAAC,GAAG,EAAE,UAAU;QAClC,IAAA,qBAAc,EAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAC/B,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;QAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,CAAA;QAC/B,MAAM,MAAM,GAAG,IAAA,kBAAW,EAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,aAAa,GAAG,IAAA,kBAAI,EAAC,MAAM,EAAE,kCAAsB,EAAE;YACzD,MAAM,EAAE,IAAA,qBAAc,EACpB,GAAG,CAAC,QAAQ,EACZ,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CACvD;SACF,CAAC,CAAA;QACF,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA,CAAC,mCAAmC;QAEnE,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE;aACvB,UAAU,CAAC,WAAW,CAAC;aACvB,SAAS,EAAE;aACX,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;aAC9B,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;aACpB,KAAK,CAAC,KAAK,CAAC,CAAA;QAEf,IAAI,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,CAAA;QAEtC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAChB,sEAAsE;YACtE,IAAI,CAAC;gBACH,MAAM,aAAa,CAAA;YACrB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAA;gBAC7B,OAAO,IAAI,iCAAsB,CAAC;oBAChC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;YACD,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,CAAA;YAClC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;gBAChB,OAAO,IAAI,iCAAsB,CAAC;oBAChC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAElC,OAAO,IAAI,iCAAsB,CAAC;YAChC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC3B,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE;gBACpB,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,SAAS,EAAE,EAAE,CAAC,SAAS;gBACvB,GAAG,EAAE,EAAE,CAAC,GAAG;gBACX,MAAM,EAAE,EAAE,CAAC,MAAM;gBACjB,OAAO,EAAE,EAAE,CAAC,OAAO;aACpB,CAAC,CAAC;YACH,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE;SAC7B,CAAC,CAAA;IACJ,CAAC;CACF,CAAC,CAAA","sourcesContent":["import { once } from 'node:events'\nimport { ServiceImpl } from '@connectrpc/connect'\nimport { AppContext } from '../context'\nimport { createOperationChannel } from '../db/schema/operation'\nimport { Service } from '../proto/bsync_connect'\nimport { ScanOperationsResponse } from '../proto/bsync_pb'\nimport { authWithApiKey } from './auth'\nimport { combineSignals, validCursor } from './util'\n\nexport default (ctx: AppContext): Partial<ServiceImpl<typeof Service>> => ({\n async scanOperations(req, handlerCtx) {\n authWithApiKey(ctx, handlerCtx)\n const { db, events } = ctx\n const limit = req.limit || 1000\n const cursor = validCursor(req.cursor)\n const nextOpPromise = once(events, createOperationChannel, {\n signal: combineSignals(\n ctx.shutdown,\n AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs),\n ),\n })\n nextOpPromise.catch(() => null) // ensure timeout is always handled\n\n const nextOpPageQb = db.db\n .selectFrom('operation')\n .selectAll()\n .where('id', '>', cursor ?? -1)\n .orderBy('id', 'asc')\n .limit(limit)\n\n let ops = await nextOpPageQb.execute()\n\n if (!ops.length) {\n // if there were no ops on the page, wait for an event then try again.\n try {\n await nextOpPromise\n } catch (err) {\n ctx.shutdown.throwIfAborted()\n return new ScanOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n ops = await nextOpPageQb.execute()\n if (!ops.length) {\n return new ScanOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n }\n\n const lastOp = ops[ops.length - 1]\n\n return new ScanOperationsResponse({\n operations: ops.map((op) => ({\n id: op.id.toString(),\n actorDid: op.actorDid,\n namespace: op.namespace,\n key: op.key,\n method: op.method,\n payload: op.payload,\n })),\n cursor: lastOp.id.toString(),\n })\n },\n})\n"]}
1
+ {"version":3,"file":"scan-operations.js","sourceRoot":"","sources":["../../src/routes/scan-operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAGlC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAElE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvD,eAAe,CAAC,GAAe,EAAwC,EAAE,CAAC,CAAC;IACzE,KAAK,CAAC,cAAc,CAAC,GAAG,EAAE,UAAU;QAClC,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;QAC/B,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,CAAA;QAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,IAAI,CAAA;QAC/B,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACtC,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,EAAE,sBAAsB,EAAE;YACzD,MAAM,EAAE,cAAc,CACpB,GAAG,CAAC,QAAQ,EACZ,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CACvD;SACF,CAAC,CAAA;QACF,aAAa,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA,CAAC,mCAAmC;QAEnE,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE;aACvB,UAAU,CAAC,WAAW,CAAC;aACvB,SAAS,EAAE;aACX,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;aAC9B,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;aACpB,KAAK,CAAC,KAAK,CAAC,CAAA;QAEf,IAAI,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,CAAA;QAEtC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAChB,sEAAsE;YACtE,IAAI,CAAC;gBACH,MAAM,aAAa,CAAA;YACrB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAA;gBAC7B,OAAO,IAAI,sBAAsB,CAAC;oBAChC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;YACD,GAAG,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,CAAA;YAClC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;gBAChB,OAAO,IAAI,sBAAsB,CAAC;oBAChC,UAAU,EAAE,EAAE;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAElC,OAAO,IAAI,sBAAsB,CAAC;YAChC,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC3B,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE;gBACpB,QAAQ,EAAE,EAAE,CAAC,QAAQ;gBACrB,SAAS,EAAE,EAAE,CAAC,SAAS;gBACvB,GAAG,EAAE,EAAE,CAAC,GAAG;gBACX,MAAM,EAAE,EAAE,CAAC,MAAM;gBACjB,OAAO,EAAE,EAAE,CAAC,OAAO;aACpB,CAAC,CAAC;YACH,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE;SAC7B,CAAC,CAAA;IACJ,CAAC;CACF,CAAC,CAAA","sourcesContent":["import { once } from 'node:events'\nimport { ServiceImpl } from '@connectrpc/connect'\nimport { AppContext } from '../context.js'\nimport { createOperationChannel } from '../db/schema/operation.js'\nimport { Service } from '../proto/bsync_connect.js'\nimport { ScanOperationsResponse } from '../proto/bsync_pb.js'\nimport { authWithApiKey } from './auth.js'\nimport { combineSignals, validCursor } from './util.js'\n\nexport default (ctx: AppContext): Partial<ServiceImpl<typeof Service>> => ({\n async scanOperations(req, handlerCtx) {\n authWithApiKey(ctx, handlerCtx)\n const { db, events } = ctx\n const limit = req.limit || 1000\n const cursor = validCursor(req.cursor)\n const nextOpPromise = once(events, createOperationChannel, {\n signal: combineSignals(\n ctx.shutdown,\n AbortSignal.timeout(ctx.cfg.service.longPollTimeoutMs),\n ),\n })\n nextOpPromise.catch(() => null) // ensure timeout is always handled\n\n const nextOpPageQb = db.db\n .selectFrom('operation')\n .selectAll()\n .where('id', '>', cursor ?? -1)\n .orderBy('id', 'asc')\n .limit(limit)\n\n let ops = await nextOpPageQb.execute()\n\n if (!ops.length) {\n // if there were no ops on the page, wait for an event then try again.\n try {\n await nextOpPromise\n } catch (err) {\n ctx.shutdown.throwIfAborted()\n return new ScanOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n ops = await nextOpPageQb.execute()\n if (!ops.length) {\n return new ScanOperationsResponse({\n operations: [],\n cursor: req.cursor,\n })\n }\n }\n\n const lastOp = ops[ops.length - 1]\n\n return new ScanOperationsResponse({\n operations: ops.map((op) => ({\n id: op.id.toString(),\n actorDid: op.actorDid,\n namespace: op.namespace,\n key: op.key,\n method: op.method,\n payload: op.payload,\n })),\n cursor: lastOp.id.toString(),\n })\n },\n})\n"]}
@@ -2,4 +2,5 @@ export declare const validCursor: (cursor: string) => number | null;
2
2
  export declare const combineSignals: (a: AbortSignal, b: AbortSignal) => AbortSignal;
3
3
  export declare const isValidDid: (did: string) => boolean;
4
4
  export declare const isValidAtUri: (uri: string) => boolean;
5
+ export declare const validateNamespace: (namespace: string) => void;
5
6
  //# sourceMappingURL=util.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/routes/util.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,KAAG,MAAM,GAAG,IAOrD,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,GAAG,WAAW,EAAE,GAAG,WAAW,gBAa5D,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,YAUrC,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,YAOvC,CAAA"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/routes/util.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,KAAG,MAAM,GAAG,IAOrD,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,GAAG,WAAW,EAAE,GAAG,WAAW,gBAa5D,CAAA;AAED,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,YAUrC,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,YAOvC,CAAA;AAED,eAAO,MAAM,iBAAiB,GAAI,WAAW,MAAM,KAAG,IAarD,CAAA"}