@atproto/ozone 0.0.12 → 0.0.13

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 (47) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/api/label/queryLabels.d.ts +3 -0
  3. package/dist/api/label/subscribeLabels.d.ts +3 -0
  4. package/dist/config/config.d.ts +3 -0
  5. package/dist/config/env.d.ts +3 -0
  6. package/dist/context.d.ts +3 -0
  7. package/dist/db/index.js +3 -1
  8. package/dist/db/index.js.map +2 -2
  9. package/dist/db/schema/label.d.ts +4 -0
  10. package/dist/index.js +593 -244
  11. package/dist/index.js.map +3 -3
  12. package/dist/logger.d.ts +1 -0
  13. package/dist/mod-service/util.d.ts +3 -0
  14. package/dist/sequencer/index.d.ts +2 -0
  15. package/dist/sequencer/outbox.d.ts +16 -0
  16. package/dist/sequencer/sequencer.d.ts +33 -0
  17. package/package.json +10 -10
  18. package/src/api/admin/emitModerationEvent.ts +16 -10
  19. package/src/api/index.ts +4 -0
  20. package/src/api/label/queryLabels.ts +58 -0
  21. package/src/api/label/subscribeLabels.ts +25 -0
  22. package/src/api/temp/fetchLabels.ts +2 -4
  23. package/src/config/config.ts +6 -0
  24. package/src/config/env.ts +6 -0
  25. package/src/context.ts +12 -0
  26. package/src/db/migrations/20231219T205730722Z-init.ts +7 -1
  27. package/src/db/schema/label.ts +7 -0
  28. package/src/index.ts +2 -0
  29. package/src/lexicon/lexicons.ts +1 -1
  30. package/src/logger.ts +2 -0
  31. package/src/mod-service/index.ts +73 -72
  32. package/src/mod-service/status.ts +3 -0
  33. package/src/mod-service/util.ts +17 -0
  34. package/src/mod-service/views.ts +2 -5
  35. package/src/sequencer/index.ts +2 -0
  36. package/src/sequencer/outbox.ts +122 -0
  37. package/src/sequencer/sequencer.ts +143 -0
  38. package/tests/__snapshots__/moderation-events.test.ts.snap +53 -75
  39. package/tests/__snapshots__/moderation.test.ts.snap +4 -4
  40. package/tests/moderation-appeals.test.ts +19 -7
  41. package/tests/moderation-events.test.ts +7 -7
  42. package/tests/moderation-statuses.test.ts +2 -2
  43. package/tests/moderation.test.ts +14 -13
  44. package/tests/query-labels.test.ts +163 -0
  45. package/tests/repo-search.test.ts +0 -1
  46. package/tests/sequencer.test.ts +222 -0
  47. package/tests/server.test.ts +2 -0
package/dist/index.js CHANGED
@@ -1331,7 +1331,7 @@ var require_src = __commonJS({
1331
1331
  var require_destroy = __commonJS({
1332
1332
  "../../node_modules/.pnpm/destroy@1.2.0/node_modules/destroy/index.js"(exports, module2) {
1333
1333
  "use strict";
1334
- var EventEmitter2 = require("events").EventEmitter;
1334
+ var EventEmitter3 = require("events").EventEmitter;
1335
1335
  var ReadStream = require("fs").ReadStream;
1336
1336
  var Stream2 = require("stream");
1337
1337
  var Zlib = require("zlib");
@@ -1393,7 +1393,7 @@ var require_destroy = __commonJS({
1393
1393
  return stream instanceof Stream2 && typeof stream.destroy === "function";
1394
1394
  }
1395
1395
  function isEventEmitter(val) {
1396
- return val instanceof EventEmitter2;
1396
+ return val instanceof EventEmitter3;
1397
1397
  }
1398
1398
  function isFsReadStream(stream) {
1399
1399
  return stream instanceof ReadStream;
@@ -21674,7 +21674,7 @@ var require_express = __commonJS({
21674
21674
  "../../node_modules/.pnpm/express@4.18.2/node_modules/express/lib/express.js"(exports, module2) {
21675
21675
  "use strict";
21676
21676
  var bodyParser = require_body_parser();
21677
- var EventEmitter2 = require("events").EventEmitter;
21677
+ var EventEmitter3 = require("events").EventEmitter;
21678
21678
  var mixin = require_merge_descriptors();
21679
21679
  var proto = require_application();
21680
21680
  var Route = require_route();
@@ -21686,7 +21686,7 @@ var require_express = __commonJS({
21686
21686
  var app = function(req2, res2, next) {
21687
21687
  app.handle(req2, res2, next);
21688
21688
  };
21689
- mixin(app, EventEmitter2.prototype, false);
21689
+ mixin(app, EventEmitter3.prototype, false);
21690
21690
  mixin(app, proto, false);
21691
21691
  app.request = Object.create(req, {
21692
21692
  app: { configurable: true, enumerable: true, writable: true, value: app }
@@ -45098,7 +45098,7 @@ var require_sonic_boom = __commonJS({
45098
45098
  "../../node_modules/.pnpm/sonic-boom@3.3.0/node_modules/sonic-boom/index.js"(exports, module2) {
45099
45099
  "use strict";
45100
45100
  var fs = require("fs");
45101
- var EventEmitter2 = require("events");
45101
+ var EventEmitter3 = require("events");
45102
45102
  var inherits = require("util").inherits;
45103
45103
  var path = require("path");
45104
45104
  var sleep = require_atomic_sleep();
@@ -45285,7 +45285,7 @@ var require_sonic_boom = __commonJS({
45285
45285
  sonic._asyncDrainScheduled = false;
45286
45286
  sonic.emit("drain");
45287
45287
  }
45288
- inherits(SonicBoom, EventEmitter2);
45288
+ inherits(SonicBoom, EventEmitter3);
45289
45289
  SonicBoom.prototype.write = function(data) {
45290
45290
  if (this.destroyed) {
45291
45291
  throw new Error("SonicBoom destroyed");
@@ -45675,7 +45675,7 @@ var require_thread_stream = __commonJS({
45675
45675
  "../../node_modules/.pnpm/thread-stream@2.4.0/node_modules/thread-stream/index.js"(exports, module2) {
45676
45676
  "use strict";
45677
45677
  var { version: version2 } = require_package();
45678
- var { EventEmitter: EventEmitter2 } = require("events");
45678
+ var { EventEmitter: EventEmitter3 } = require("events");
45679
45679
  var { Worker } = require("worker_threads");
45680
45680
  var { join } = require("path");
45681
45681
  var { pathToFileURL } = require("url");
@@ -45830,7 +45830,7 @@ var require_thread_stream = __commonJS({
45830
45830
  stream.worker.off("exit", onWorkerExit);
45831
45831
  destroy(stream, code3 !== 0 ? new Error("the worker thread exited") : null);
45832
45832
  }
45833
- var ThreadStream = class extends EventEmitter2 {
45833
+ var ThreadStream = class extends EventEmitter3 {
45834
45834
  constructor(opts = {}) {
45835
45835
  super();
45836
45836
  if (opts.bufferSize < 4) {
@@ -46694,7 +46694,7 @@ var require_meta = __commonJS({
46694
46694
  var require_proto = __commonJS({
46695
46695
  "../../node_modules/.pnpm/pino@8.15.0/node_modules/pino/lib/proto.js"(exports, module2) {
46696
46696
  "use strict";
46697
- var { EventEmitter: EventEmitter2 } = require("events");
46697
+ var { EventEmitter: EventEmitter3 } = require("events");
46698
46698
  var {
46699
46699
  lsCacheSym,
46700
46700
  levelValSym,
@@ -46768,7 +46768,7 @@ var require_proto = __commonJS({
46768
46768
  [getLevelSym]: getLevel,
46769
46769
  [setLevelSym]: setLevel
46770
46770
  };
46771
- Object.setPrototypeOf(prototype, EventEmitter2.prototype);
46771
+ Object.setPrototypeOf(prototype, EventEmitter3.prototype);
46772
46772
  module2.exports = function() {
46773
46773
  return Object.create(prototype);
46774
46774
  };
@@ -48861,7 +48861,7 @@ var require_extension = __commonJS({
48861
48861
  var require_websocket = __commonJS({
48862
48862
  "../../node_modules/.pnpm/ws@8.12.0/node_modules/ws/lib/websocket.js"(exports, module2) {
48863
48863
  "use strict";
48864
- var EventEmitter2 = require("events");
48864
+ var EventEmitter3 = require("events");
48865
48865
  var https = require("https");
48866
48866
  var http = require("http");
48867
48867
  var net = require("net");
@@ -48892,7 +48892,7 @@ var require_websocket = __commonJS({
48892
48892
  var protocolVersions = [8, 13];
48893
48893
  var readyStates = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"];
48894
48894
  var subprotocolRegex = /^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;
48895
- var WebSocket4 = class extends EventEmitter2 {
48895
+ var WebSocket4 = class extends EventEmitter3 {
48896
48896
  constructor(address, protocols, options) {
48897
48897
  super();
48898
48898
  this._binaryType = BINARY_TYPES[0];
@@ -49627,7 +49627,7 @@ var require_subprotocol = __commonJS({
49627
49627
  var require_websocket_server = __commonJS({
49628
49628
  "../../node_modules/.pnpm/ws@8.12.0/node_modules/ws/lib/websocket-server.js"(exports, module2) {
49629
49629
  "use strict";
49630
- var EventEmitter2 = require("events");
49630
+ var EventEmitter3 = require("events");
49631
49631
  var http = require("http");
49632
49632
  var https = require("https");
49633
49633
  var net = require("net");
@@ -49642,7 +49642,7 @@ var require_websocket_server = __commonJS({
49642
49642
  var RUNNING = 0;
49643
49643
  var CLOSING = 1;
49644
49644
  var CLOSED = 2;
49645
- var WebSocketServer2 = class extends EventEmitter2 {
49645
+ var WebSocketServer2 = class extends EventEmitter3 {
49646
49646
  constructor(options, callback) {
49647
49647
  super();
49648
49648
  options = {
@@ -53572,7 +53572,7 @@ var require_dist3 = __commonJS({
53572
53572
  "../../node_modules/sonic-boom/index.js"(exports2, module22) {
53573
53573
  "use strict";
53574
53574
  var fs = require("fs");
53575
- var EventEmitter2 = require("events");
53575
+ var EventEmitter22 = require("events");
53576
53576
  var inherits2 = require("util").inherits;
53577
53577
  var path = require("path");
53578
53578
  var sleep = require_atomic_sleep2();
@@ -53759,7 +53759,7 @@ var require_dist3 = __commonJS({
53759
53759
  sonic._asyncDrainScheduled = false;
53760
53760
  sonic.emit("drain");
53761
53761
  }
53762
- inherits2(SonicBoom, EventEmitter2);
53762
+ inherits2(SonicBoom, EventEmitter22);
53763
53763
  SonicBoom.prototype.write = function(data) {
53764
53764
  if (this.destroyed) {
53765
53765
  throw new Error("SonicBoom destroyed");
@@ -54126,7 +54126,7 @@ var require_dist3 = __commonJS({
54126
54126
  "../../node_modules/thread-stream/index.js"(exports2, module22) {
54127
54127
  "use strict";
54128
54128
  var { version: version22 } = require_package2();
54129
- var { EventEmitter: EventEmitter2 } = require("events");
54129
+ var { EventEmitter: EventEmitter22 } = require("events");
54130
54130
  var { Worker } = require("worker_threads");
54131
54131
  var { join } = require("path");
54132
54132
  var { pathToFileURL } = require("url");
@@ -54277,7 +54277,7 @@ var require_dist3 = __commonJS({
54277
54277
  stream4.worker.off("exit", onWorkerExit);
54278
54278
  destroy(stream4, code4 !== 0 ? new Error("the worker thread exited") : null);
54279
54279
  }
54280
- var ThreadStream = class extends EventEmitter2 {
54280
+ var ThreadStream = class extends EventEmitter22 {
54281
54281
  constructor(opts = {}) {
54282
54282
  super();
54283
54283
  if (opts.bufferSize < 4) {
@@ -55113,7 +55113,7 @@ var require_dist3 = __commonJS({
55113
55113
  var require_proto2 = __commonJS2({
55114
55114
  "../../node_modules/@atproto/common/node_modules/pino/lib/proto.js"(exports2, module22) {
55115
55115
  "use strict";
55116
- var { EventEmitter: EventEmitter2 } = require("events");
55116
+ var { EventEmitter: EventEmitter22 } = require("events");
55117
55117
  var {
55118
55118
  lsCacheSym,
55119
55119
  levelValSym,
@@ -55185,7 +55185,7 @@ var require_dist3 = __commonJS({
55185
55185
  [getLevelSym]: getLevel,
55186
55186
  [setLevelSym]: setLevel
55187
55187
  };
55188
- Object.setPrototypeOf(prototype3, EventEmitter2.prototype);
55188
+ Object.setPrototypeOf(prototype3, EventEmitter22.prototype);
55189
55189
  module22.exports = function() {
55190
55190
  return Object.create(prototype3);
55191
55191
  };
@@ -77552,7 +77552,7 @@ if (cid) {
77552
77552
  }
77553
77553
  };
77554
77554
  var AxiosTransformStream_default = AxiosTransformStream;
77555
- var import_events2 = __toESM2(require("events"), 1);
77555
+ var import_events3 = __toESM2(require("events"), 1);
77556
77556
  var import_util310 = require("util");
77557
77557
  var import_stream22 = require("stream");
77558
77558
  var { asyncIterator } = Symbol;
@@ -77750,7 +77750,7 @@ if (cid) {
77750
77750
  let isDone;
77751
77751
  let rejected = false;
77752
77752
  let req;
77753
- const emitter = new import_events2.default();
77753
+ const emitter = new import_events3.default();
77754
77754
  const onFinished = () => {
77755
77755
  if (config22.cancelToken) {
77756
77756
  config22.cancelToken.unsubscribe(abort);
@@ -85284,10 +85284,10 @@ var require_result = __commonJS({
85284
85284
  var require_query2 = __commonJS({
85285
85285
  "../../node_modules/.pnpm/pg@8.10.0/node_modules/pg/lib/query.js"(exports, module2) {
85286
85286
  "use strict";
85287
- var { EventEmitter: EventEmitter2 } = require("events");
85287
+ var { EventEmitter: EventEmitter3 } = require("events");
85288
85288
  var Result = require_result();
85289
85289
  var utils = require_utils5();
85290
- var Query = class extends EventEmitter2 {
85290
+ var Query = class extends EventEmitter3 {
85291
85291
  constructor(config2, values, callback) {
85292
85292
  super();
85293
85293
  config2 = utils.normalizeQueryConfig(config2, values, callback);
@@ -86253,12 +86253,12 @@ var require_connection = __commonJS({
86253
86253
  "../../node_modules/.pnpm/pg@8.10.0/node_modules/pg/lib/connection.js"(exports, module2) {
86254
86254
  "use strict";
86255
86255
  var net = require("net");
86256
- var EventEmitter2 = require("events").EventEmitter;
86256
+ var EventEmitter3 = require("events").EventEmitter;
86257
86257
  var { parse: parse2, serialize } = require_dist4();
86258
86258
  var flushBuffer = serialize.flush();
86259
86259
  var syncBuffer = serialize.sync();
86260
86260
  var endBuffer = serialize.end();
86261
- var Connection = class extends EventEmitter2 {
86261
+ var Connection = class extends EventEmitter3 {
86262
86262
  constructor(config2) {
86263
86263
  super();
86264
86264
  config2 = config2 || {};
@@ -86433,7 +86433,7 @@ var require_connection = __commonJS({
86433
86433
  var require_client = __commonJS({
86434
86434
  "../../node_modules/.pnpm/pg@8.10.0/node_modules/pg/lib/client.js"(exports, module2) {
86435
86435
  "use strict";
86436
- var EventEmitter2 = require("events").EventEmitter;
86436
+ var EventEmitter3 = require("events").EventEmitter;
86437
86437
  var utils = require_utils5();
86438
86438
  var sasl = require_sasl();
86439
86439
  var pgPass = require_lib6();
@@ -86442,7 +86442,7 @@ var require_client = __commonJS({
86442
86442
  var Query = require_query2();
86443
86443
  var defaults = require_defaults3();
86444
86444
  var Connection = require_connection();
86445
- var Client3 = class extends EventEmitter2 {
86445
+ var Client3 = class extends EventEmitter3 {
86446
86446
  constructor(config2) {
86447
86447
  super();
86448
86448
  this.connectionParameters = new ConnectionParameters(config2);
@@ -86936,7 +86936,7 @@ var require_client = __commonJS({
86936
86936
  var require_pg_pool = __commonJS({
86937
86937
  "../../node_modules/.pnpm/pg-pool@3.6.1_pg@8.10.0/node_modules/pg-pool/index.js"(exports, module2) {
86938
86938
  "use strict";
86939
- var EventEmitter2 = require("events").EventEmitter;
86939
+ var EventEmitter3 = require("events").EventEmitter;
86940
86940
  var NOOP = function() {
86941
86941
  };
86942
86942
  var removeWhere = (list, predicate) => {
@@ -86987,7 +86987,7 @@ var require_pg_pool = __commonJS({
86987
86987
  pool.emit("error", err, client);
86988
86988
  };
86989
86989
  }
86990
- var Pool = class extends EventEmitter2 {
86990
+ var Pool = class extends EventEmitter3 {
86991
86991
  constructor(options, Client3) {
86992
86992
  super();
86993
86993
  this.options = Object.assign({}, options);
@@ -87310,11 +87310,11 @@ var require_pg_pool = __commonJS({
87310
87310
  var require_query3 = __commonJS({
87311
87311
  "../../node_modules/.pnpm/pg@8.10.0/node_modules/pg/lib/native/query.js"(exports, module2) {
87312
87312
  "use strict";
87313
- var EventEmitter2 = require("events").EventEmitter;
87313
+ var EventEmitter3 = require("events").EventEmitter;
87314
87314
  var util2 = require("util");
87315
87315
  var utils = require_utils5();
87316
87316
  var NativeQuery = module2.exports = function(config2, values, callback) {
87317
- EventEmitter2.call(this);
87317
+ EventEmitter3.call(this);
87318
87318
  config2 = utils.normalizeQueryConfig(config2, values, callback);
87319
87319
  this.text = config2.text;
87320
87320
  this.values = config2.values;
@@ -87328,7 +87328,7 @@ var require_query3 = __commonJS({
87328
87328
  this._emitRowEvents = true;
87329
87329
  }.bind(this));
87330
87330
  };
87331
- util2.inherits(NativeQuery, EventEmitter2);
87331
+ util2.inherits(NativeQuery, EventEmitter3);
87332
87332
  var errorFieldMap = {
87333
87333
  sqlState: "code",
87334
87334
  statementPosition: "position",
@@ -87448,12 +87448,12 @@ var require_client2 = __commonJS({
87448
87448
  "use strict";
87449
87449
  var Native = require("pg-native");
87450
87450
  var TypeOverrides = require_type_overrides();
87451
- var EventEmitter2 = require("events").EventEmitter;
87451
+ var EventEmitter3 = require("events").EventEmitter;
87452
87452
  var util2 = require("util");
87453
87453
  var ConnectionParameters = require_connection_parameters();
87454
87454
  var NativeQuery = require_query3();
87455
87455
  var Client3 = module2.exports = function(config2) {
87456
- EventEmitter2.call(this);
87456
+ EventEmitter3.call(this);
87457
87457
  config2 = config2 || {};
87458
87458
  this._Promise = config2.Promise || global.Promise;
87459
87459
  this._types = new TypeOverrides(config2.types);
@@ -87479,7 +87479,7 @@ var require_client2 = __commonJS({
87479
87479
  this.namedQueries = {};
87480
87480
  };
87481
87481
  Client3.Query = NativeQuery;
87482
- util2.inherits(Client3, EventEmitter2);
87482
+ util2.inherits(Client3, EventEmitter3);
87483
87483
  Client3.prototype._errorAllQueries = function(err) {
87484
87484
  const enqueueError = (query) => {
87485
87485
  process.nextTick(() => {
@@ -87771,11 +87771,11 @@ var require_eventemitter3 = __commonJS({
87771
87771
  else
87772
87772
  delete emitter._events[evt];
87773
87773
  }
87774
- function EventEmitter2() {
87774
+ function EventEmitter3() {
87775
87775
  this._events = new Events();
87776
87776
  this._eventsCount = 0;
87777
87777
  }
87778
- EventEmitter2.prototype.eventNames = function eventNames() {
87778
+ EventEmitter3.prototype.eventNames = function eventNames() {
87779
87779
  var names = [], events2, name2;
87780
87780
  if (this._eventsCount === 0)
87781
87781
  return names;
@@ -87788,7 +87788,7 @@ var require_eventemitter3 = __commonJS({
87788
87788
  }
87789
87789
  return names;
87790
87790
  };
87791
- EventEmitter2.prototype.listeners = function listeners(event) {
87791
+ EventEmitter3.prototype.listeners = function listeners(event) {
87792
87792
  var evt = prefix ? prefix + event : event, handlers = this._events[evt];
87793
87793
  if (!handlers)
87794
87794
  return [];
@@ -87799,7 +87799,7 @@ var require_eventemitter3 = __commonJS({
87799
87799
  }
87800
87800
  return ee;
87801
87801
  };
87802
- EventEmitter2.prototype.listenerCount = function listenerCount(event) {
87802
+ EventEmitter3.prototype.listenerCount = function listenerCount(event) {
87803
87803
  var evt = prefix ? prefix + event : event, listeners = this._events[evt];
87804
87804
  if (!listeners)
87805
87805
  return 0;
@@ -87807,7 +87807,7 @@ var require_eventemitter3 = __commonJS({
87807
87807
  return 1;
87808
87808
  return listeners.length;
87809
87809
  };
87810
- EventEmitter2.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
87810
+ EventEmitter3.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
87811
87811
  var evt = prefix ? prefix + event : event;
87812
87812
  if (!this._events[evt])
87813
87813
  return false;
@@ -87862,13 +87862,13 @@ var require_eventemitter3 = __commonJS({
87862
87862
  }
87863
87863
  return true;
87864
87864
  };
87865
- EventEmitter2.prototype.on = function on(event, fn, context) {
87865
+ EventEmitter3.prototype.on = function on(event, fn, context) {
87866
87866
  return addListener(this, event, fn, context, false);
87867
87867
  };
87868
- EventEmitter2.prototype.once = function once(event, fn, context) {
87868
+ EventEmitter3.prototype.once = function once(event, fn, context) {
87869
87869
  return addListener(this, event, fn, context, true);
87870
87870
  };
87871
- EventEmitter2.prototype.removeListener = function removeListener(event, fn, context, once) {
87871
+ EventEmitter3.prototype.removeListener = function removeListener(event, fn, context, once) {
87872
87872
  var evt = prefix ? prefix + event : event;
87873
87873
  if (!this._events[evt])
87874
87874
  return this;
@@ -87894,7 +87894,7 @@ var require_eventemitter3 = __commonJS({
87894
87894
  }
87895
87895
  return this;
87896
87896
  };
87897
- EventEmitter2.prototype.removeAllListeners = function removeAllListeners(event) {
87897
+ EventEmitter3.prototype.removeAllListeners = function removeAllListeners(event) {
87898
87898
  var evt;
87899
87899
  if (event) {
87900
87900
  evt = prefix ? prefix + event : event;
@@ -87906,12 +87906,12 @@ var require_eventemitter3 = __commonJS({
87906
87906
  }
87907
87907
  return this;
87908
87908
  };
87909
- EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener;
87910
- EventEmitter2.prototype.addListener = EventEmitter2.prototype.on;
87911
- EventEmitter2.prefixed = prefix;
87912
- EventEmitter2.EventEmitter = EventEmitter2;
87909
+ EventEmitter3.prototype.off = EventEmitter3.prototype.removeListener;
87910
+ EventEmitter3.prototype.addListener = EventEmitter3.prototype.on;
87911
+ EventEmitter3.prefixed = prefix;
87912
+ EventEmitter3.EventEmitter = EventEmitter3;
87913
87913
  if (typeof module2 !== "undefined") {
87914
- module2.exports = EventEmitter2;
87914
+ module2.exports = EventEmitter3;
87915
87915
  }
87916
87916
  }
87917
87917
  });
@@ -87983,13 +87983,13 @@ var require_dist5 = __commonJS({
87983
87983
  "../../node_modules/.pnpm/p-queue@6.6.2/node_modules/p-queue/dist/index.js"(exports) {
87984
87984
  "use strict";
87985
87985
  Object.defineProperty(exports, "__esModule", { value: true });
87986
- var EventEmitter2 = require_eventemitter3();
87986
+ var EventEmitter3 = require_eventemitter3();
87987
87987
  var p_timeout_1 = require_p_timeout();
87988
87988
  var priority_queue_1 = require_priority_queue();
87989
87989
  var empty2 = () => {
87990
87990
  };
87991
87991
  var timeoutError = new p_timeout_1.TimeoutError();
87992
- var PQueue2 = class extends EventEmitter2 {
87992
+ var PQueue2 = class extends EventEmitter3 {
87993
87993
  constructor(options) {
87994
87994
  var _a, _b, _c, _d;
87995
87995
  super();
@@ -88219,7 +88219,7 @@ __export(src_exports5, {
88219
88219
  });
88220
88220
  module.exports = __toCommonJS(src_exports5);
88221
88221
  var import_express4 = __toESM(require_express2());
88222
- var import_events = __toESM(require("events"));
88222
+ var import_events2 = __toESM(require("events"));
88223
88223
  var import_http_terminator = __toESM(require_src3());
88224
88224
  var import_cors = __toESM(require_lib4());
88225
88225
  var import_compression = __toESM(require_compression());
@@ -92303,6 +92303,77 @@ var mapDefined = (arr, fn) => {
92303
92303
  return output2;
92304
92304
  };
92305
92305
 
92306
+ // ../common-web/src/async.ts
92307
+ var AsyncBuffer = class {
92308
+ constructor(maxSize) {
92309
+ this.maxSize = maxSize;
92310
+ this.buffer = [];
92311
+ this.closed = false;
92312
+ this.promise = Promise.resolve();
92313
+ this.resolve = () => null;
92314
+ this.resetPromise();
92315
+ }
92316
+ get curr() {
92317
+ return this.buffer;
92318
+ }
92319
+ get size() {
92320
+ return this.buffer.length;
92321
+ }
92322
+ get isClosed() {
92323
+ return this.closed;
92324
+ }
92325
+ resetPromise() {
92326
+ this.promise = new Promise((r) => this.resolve = r);
92327
+ }
92328
+ push(item) {
92329
+ this.buffer.push(item);
92330
+ this.resolve();
92331
+ }
92332
+ pushMany(items) {
92333
+ items.forEach((i) => this.buffer.push(i));
92334
+ this.resolve();
92335
+ }
92336
+ async *events() {
92337
+ while (true) {
92338
+ if (this.closed && this.buffer.length === 0) {
92339
+ if (this.toThrow) {
92340
+ throw this.toThrow;
92341
+ } else {
92342
+ return;
92343
+ }
92344
+ }
92345
+ await this.promise;
92346
+ if (this.toThrow) {
92347
+ throw this.toThrow;
92348
+ }
92349
+ if (this.maxSize && this.size > this.maxSize) {
92350
+ throw new AsyncBufferFullError(this.maxSize);
92351
+ }
92352
+ const [first, ...rest] = this.buffer;
92353
+ if (first) {
92354
+ this.buffer = rest;
92355
+ yield first;
92356
+ } else {
92357
+ this.resetPromise();
92358
+ }
92359
+ }
92360
+ }
92361
+ throw(err) {
92362
+ this.toThrow = err;
92363
+ this.closed = true;
92364
+ this.resolve();
92365
+ }
92366
+ close() {
92367
+ this.closed = true;
92368
+ this.resolve();
92369
+ }
92370
+ };
92371
+ var AsyncBufferFullError = class extends Error {
92372
+ constructor(maxSize) {
92373
+ super(`ReachedMaxBufferSize: ${maxSize}`);
92374
+ }
92375
+ };
92376
+
92306
92377
  // ../../node_modules/.pnpm/multiformats@9.9.0/node_modules/multiformats/esm/vendor/varint.js
92307
92378
  var encode_1 = encode;
92308
92379
  var MSB = 128;
@@ -106618,7 +106689,7 @@ var schemaDict = {
106618
106689
  defs: {
106619
106690
  main: {
106620
106691
  type: "query",
106621
- description: "Fetch all labels from a labeler created after a certain date. DEPRECATED: use queryLabels or subscribeLabels instead",
106692
+ description: "DEPRECATED: use queryLabels or subscribeLabels instead -- Fetch all labels from a labeler created after a certain date.",
106622
106693
  parameters: {
106623
106694
  type: "params",
106624
106695
  properties: {
@@ -110684,6 +110755,7 @@ var RecordSubject = class {
110684
110755
  // src/logger.ts
110685
110756
  var import_pino_http = __toESM(require_logger());
110686
110757
  var dbLogger = subsystemLogger("ozone:db");
110758
+ var seqLogger = subsystemLogger("ozone:sequencer");
110687
110759
  var httpLogger = subsystemLogger("ozone");
110688
110760
  var langLogger = subsystemLogger("ozone:lang");
110689
110761
  var loggerMiddleware = (0, import_pino_http.default)({
@@ -110805,11 +110877,13 @@ function emitModerationEvent_default(server, ctx) {
110805
110877
  const isReverseTakedownEvent = isModEventReverseTakedown(event);
110806
110878
  const isLabelEvent = isModEventLabel(event);
110807
110879
  const subject = subjectFromInput(input.body.subject, input.body.subjectBlobCids);
110808
- if (!access.moderator && isTakedownEvent && subject.isRepo()) {
110809
- throw new AuthRequiredError("Must be a full moderator to perform an account takedown");
110810
- }
110811
- if (!access.moderator && (isTakedownEvent || isReverseTakedownEvent)) {
110812
- throw new AuthRequiredError("Must be a full moderator to take this type of action");
110880
+ if (isTakedownEvent || isReverseTakedownEvent) {
110881
+ if (!access.moderator) {
110882
+ throw new AuthRequiredError("Must be a full moderator to take this type of action");
110883
+ }
110884
+ if (!access.admin && subject.recordPath?.includes("app.bsky.feed.generator/")) {
110885
+ throw new AuthRequiredError("Must be a full admin to take this type of action on feed generators");
110886
+ }
110813
110887
  }
110814
110888
  if (!access.moderator && isLabelEvent) {
110815
110889
  throw new AuthRequiredError("Must be a full moderator to label content");
@@ -111131,140 +111205,6 @@ function getModerationEvent_default(server, ctx) {
111131
111205
  });
111132
111206
  }
111133
111207
 
111134
- // src/mod-service/types.ts
111135
- var UNSPECCED_TAKEDOWN_LABEL = "!unspecced-takedown";
111136
- var UNSPECCED_TAKEDOWN_BLOBS_LABEL = "!unspecced-takedown-blobs";
111137
-
111138
- // src/api/temp/fetchLabels.ts
111139
- function fetchLabels_default(server, ctx) {
111140
- server.com.atproto.temp.fetchLabels({
111141
- auth: ctx.authOptionalAccessOrRoleVerifier,
111142
- handler: async ({ auth, params: params2 }) => {
111143
- const { limit } = params2;
111144
- const since = params2.since !== void 0 ? new Date(params2.since).toISOString() : "";
111145
- const includeUnspeccedTakedowns = auth.credentials.type === "role" && auth.credentials.admin;
111146
- const labelRes = await ctx.db.db.selectFrom("label").selectAll().orderBy("label.cts", "asc").where("cts", ">", since).if(!includeUnspeccedTakedowns, (q) => q.where("label.val", "not in", [
111147
- UNSPECCED_TAKEDOWN_LABEL,
111148
- UNSPECCED_TAKEDOWN_BLOBS_LABEL
111149
- ])).limit(limit).execute();
111150
- const labels = labelRes.map((l) => ({
111151
- ...l,
111152
- cid: l.cid === "" ? void 0 : l.cid
111153
- }));
111154
- return {
111155
- encoding: "application/json",
111156
- body: {
111157
- labels
111158
- }
111159
- };
111160
- }
111161
- });
111162
- }
111163
-
111164
- // src/api/admin/createCommunicationTemplate.ts
111165
- function createCommunicationTemplate_default(server, ctx) {
111166
- server.com.atproto.admin.createCommunicationTemplate({
111167
- auth: ctx.roleVerifier,
111168
- handler: async ({ input, auth }) => {
111169
- const access = auth.credentials;
111170
- const db = ctx.db;
111171
- const { createdBy, ...template } = input.body;
111172
- if (!access.admin) {
111173
- throw new AuthRequiredError("Must be an admin to create a communication template");
111174
- }
111175
- if (!createdBy) {
111176
- throw new InvalidRequestError("createdBy field is required");
111177
- }
111178
- const communicationTemplate = ctx.communicationTemplateService(db);
111179
- const newTemplate = await communicationTemplate.create({
111180
- ...template,
111181
- disabled: false,
111182
- lastUpdatedBy: createdBy
111183
- });
111184
- return {
111185
- encoding: "application/json",
111186
- body: communicationTemplate.view(newTemplate)
111187
- };
111188
- }
111189
- });
111190
- }
111191
-
111192
- // src/api/admin/updateCommunicationTemplate.ts
111193
- function updateCommunicationTemplate_default(server, ctx) {
111194
- server.com.atproto.admin.updateCommunicationTemplate({
111195
- auth: ctx.roleVerifier,
111196
- handler: async ({ input, auth }) => {
111197
- const access = auth.credentials;
111198
- const db = ctx.db;
111199
- const { id, updatedBy, ...template } = input.body;
111200
- if (!access.admin) {
111201
- throw new AuthRequiredError("Must be an admin to update a communication template");
111202
- }
111203
- if (!updatedBy) {
111204
- throw new InvalidRequestError("updatedBy field is required");
111205
- }
111206
- if (!Object.keys(template).length) {
111207
- throw new InvalidRequestError("Missing update data in request body");
111208
- }
111209
- const communicationTemplate = ctx.communicationTemplateService(db);
111210
- const updatedTemplate = await communicationTemplate.update(Number(id), {
111211
- ...template,
111212
- lastUpdatedBy: updatedBy
111213
- });
111214
- return {
111215
- encoding: "application/json",
111216
- body: communicationTemplate.view(updatedTemplate)
111217
- };
111218
- }
111219
- });
111220
- }
111221
-
111222
- // src/api/admin/deleteCommunicationTemplate.ts
111223
- function deleteCommunicationTemplate_default(server, ctx) {
111224
- server.com.atproto.admin.deleteCommunicationTemplate({
111225
- auth: ctx.roleVerifier,
111226
- handler: async ({ input, auth }) => {
111227
- const access = auth.credentials;
111228
- const db = ctx.db;
111229
- const { id } = input.body;
111230
- if (!access.admin) {
111231
- throw new AuthRequiredError("Must be an admin to delete a communication template");
111232
- }
111233
- const communicationTemplate = ctx.communicationTemplateService(db);
111234
- await communicationTemplate.delete(Number(id));
111235
- }
111236
- });
111237
- }
111238
-
111239
- // src/api/admin/listCommunicationTemplates.ts
111240
- function listCommunicationTemplates_default(server, ctx) {
111241
- server.com.atproto.admin.listCommunicationTemplates({
111242
- auth: ctx.roleVerifier,
111243
- handler: async ({ auth }) => {
111244
- const access = auth.credentials;
111245
- const db = ctx.db;
111246
- if (!access.moderator) {
111247
- throw new AuthRequiredError("Must be a full moderator to view list of communication template");
111248
- }
111249
- const communicationTemplate = ctx.communicationTemplateService(db);
111250
- const list = await communicationTemplate.list();
111251
- return {
111252
- encoding: "application/json",
111253
- body: {
111254
- communicationTemplates: list.map((item) => communicationTemplate.view(item))
111255
- }
111256
- };
111257
- }
111258
- });
111259
- }
111260
-
111261
- // src/api/health.ts
111262
- var health_exports = {};
111263
- __export(health_exports, {
111264
- createRouter: () => createRouter
111265
- });
111266
- var import_express2 = __toESM(require_express2());
111267
-
111268
111208
  // ../../node_modules/.pnpm/kysely@0.22.0/node_modules/kysely/dist/esm/util/object-utils.js
111269
111209
  function isUndefined(obj) {
111270
111210
  return obj === void 0;
@@ -118800,7 +118740,301 @@ var PostgresDialect = class {
118800
118740
  }
118801
118741
  };
118802
118742
 
118743
+ // src/mod-service/util.ts
118744
+ var formatLabel = (row) => {
118745
+ const label = {
118746
+ src: row.src,
118747
+ uri: row.uri,
118748
+ val: row.val,
118749
+ neg: row.neg,
118750
+ cts: row.cts
118751
+ };
118752
+ if (row.cid !== "") {
118753
+ label.cid = row.cid;
118754
+ }
118755
+ return label;
118756
+ };
118757
+
118758
+ // src/api/label/queryLabels.ts
118759
+ function queryLabels_default(server, ctx) {
118760
+ server.com.atproto.label.queryLabels(async ({ params: params2 }) => {
118761
+ const { uriPatterns, sources, limit, cursor } = params2;
118762
+ let builder = ctx.db.db.selectFrom("label").selectAll().limit(limit);
118763
+ if (!uriPatterns.includes("*")) {
118764
+ builder = builder.where((qb) => {
118765
+ qb = qb.where(sql`1 = 0`);
118766
+ for (const pattern of uriPatterns) {
118767
+ if (!pattern.includes("*")) {
118768
+ qb = qb.orWhere("uri", "=", pattern);
118769
+ } else {
118770
+ if (pattern.indexOf("*") < pattern.length - 1) {
118771
+ throw new InvalidRequestError(`invalid pattern: ${pattern}`);
118772
+ }
118773
+ const searchPattern = pattern.slice(0, -1).replaceAll("%", "").replaceAll("_", "\\_");
118774
+ qb = qb.orWhere("uri", "like", `${searchPattern}%`);
118775
+ }
118776
+ }
118777
+ return qb;
118778
+ });
118779
+ }
118780
+ if (sources && sources.length > 0) {
118781
+ builder = builder.where("src", "in", sources);
118782
+ }
118783
+ if (cursor) {
118784
+ const cursorId = parseInt(cursor, 10);
118785
+ if (isNaN(cursorId)) {
118786
+ throw new InvalidRequestError("invalid cursor");
118787
+ }
118788
+ builder = builder.where("id", ">", cursorId);
118789
+ }
118790
+ const res = await builder.execute();
118791
+ const labels = res.map((l) => formatLabel(l));
118792
+ const resCursor = res.at(-1)?.id.toString(10);
118793
+ return {
118794
+ encoding: "application/json",
118795
+ body: {
118796
+ cursor: resCursor,
118797
+ labels
118798
+ }
118799
+ };
118800
+ });
118801
+ }
118802
+
118803
+ // src/sequencer/outbox.ts
118804
+ var Outbox = class {
118805
+ constructor(sequencer, opts = {}) {
118806
+ this.sequencer = sequencer;
118807
+ this.caughtUp = false;
118808
+ this.lastSeen = -1;
118809
+ const { maxBufferSize = 500 } = opts;
118810
+ this.cutoverBuffer = [];
118811
+ this.outBuffer = new AsyncBuffer(maxBufferSize);
118812
+ }
118813
+ async *events(backfillCursor, signal) {
118814
+ if (backfillCursor !== void 0) {
118815
+ for await (const evt of this.getBackfill(backfillCursor)) {
118816
+ if (signal?.aborted)
118817
+ return;
118818
+ this.lastSeen = evt.seq;
118819
+ yield evt;
118820
+ }
118821
+ } else {
118822
+ this.caughtUp = true;
118823
+ }
118824
+ const addToBuffer = (evts) => {
118825
+ if (this.caughtUp) {
118826
+ this.outBuffer.pushMany(evts);
118827
+ } else {
118828
+ this.cutoverBuffer = [...this.cutoverBuffer, ...evts];
118829
+ }
118830
+ };
118831
+ if (!signal?.aborted) {
118832
+ this.sequencer.on("events", addToBuffer);
118833
+ }
118834
+ signal?.addEventListener("abort", () => this.sequencer.off("events", addToBuffer));
118835
+ const cutover = async () => {
118836
+ if (backfillCursor !== void 0) {
118837
+ const cutoverEvts = await this.sequencer.requestLabelRange({
118838
+ earliestId: this.lastSeen > -1 ? this.lastSeen : backfillCursor
118839
+ });
118840
+ this.outBuffer.pushMany(cutoverEvts);
118841
+ this.outBuffer.pushMany(this.cutoverBuffer);
118842
+ this.caughtUp = true;
118843
+ this.cutoverBuffer = [];
118844
+ } else {
118845
+ this.caughtUp = true;
118846
+ }
118847
+ };
118848
+ cutover();
118849
+ while (true) {
118850
+ try {
118851
+ for await (const evt of this.outBuffer.events()) {
118852
+ if (signal?.aborted)
118853
+ return;
118854
+ if (evt.seq > this.lastSeen) {
118855
+ this.lastSeen = evt.seq;
118856
+ yield evt;
118857
+ }
118858
+ }
118859
+ } catch (err) {
118860
+ if (err instanceof AsyncBufferFullError) {
118861
+ throw new InvalidRequestError("Stream consumer too slow", "ConsumerTooSlow");
118862
+ } else {
118863
+ throw err;
118864
+ }
118865
+ }
118866
+ }
118867
+ }
118868
+ async *getBackfill(backfillCursor) {
118869
+ const PAGE_SIZE = 500;
118870
+ while (true) {
118871
+ const evts = await this.sequencer.requestLabelRange({
118872
+ earliestId: this.lastSeen > -1 ? this.lastSeen : backfillCursor,
118873
+ limit: PAGE_SIZE
118874
+ });
118875
+ for (const evt of evts) {
118876
+ yield evt;
118877
+ }
118878
+ const seqCursor = this.sequencer.lastSeen ?? -1;
118879
+ if (seqCursor - this.lastSeen < PAGE_SIZE / 2)
118880
+ break;
118881
+ if (evts.length < 1)
118882
+ break;
118883
+ }
118884
+ }
118885
+ };
118886
+ var outbox_default = Outbox;
118887
+
118888
+ // src/api/label/subscribeLabels.ts
118889
+ function subscribeLabels_default(server, ctx) {
118890
+ server.com.atproto.label.subscribeLabels(async function* ({
118891
+ params: params2,
118892
+ signal
118893
+ }) {
118894
+ const { cursor } = params2;
118895
+ const outbox = new outbox_default(ctx.sequencer);
118896
+ if (cursor !== void 0) {
118897
+ const curr = await ctx.sequencer.curr();
118898
+ if (cursor > (curr ?? 0)) {
118899
+ throw new InvalidRequestError("Cursor in the future.", "FutureCursor");
118900
+ }
118901
+ }
118902
+ for await (const evt of outbox.events(cursor, signal)) {
118903
+ yield { $type: "com.atproto.label.subscribeLabels#labels", ...evt };
118904
+ }
118905
+ });
118906
+ }
118907
+
118908
+ // src/mod-service/types.ts
118909
+ var UNSPECCED_TAKEDOWN_LABEL = "!unspecced-takedown";
118910
+ var UNSPECCED_TAKEDOWN_BLOBS_LABEL = "!unspecced-takedown-blobs";
118911
+
118912
+ // src/api/temp/fetchLabels.ts
118913
+ function fetchLabels_default(server, ctx) {
118914
+ server.com.atproto.temp.fetchLabels({
118915
+ auth: ctx.authOptionalAccessOrRoleVerifier,
118916
+ handler: async ({ auth, params: params2 }) => {
118917
+ const { limit } = params2;
118918
+ const since = params2.since !== void 0 ? new Date(params2.since).toISOString() : "";
118919
+ const includeUnspeccedTakedowns = auth.credentials.type === "role" && auth.credentials.admin;
118920
+ const labelRes = await ctx.db.db.selectFrom("label").selectAll().orderBy("label.cts", "asc").where("cts", ">", since).if(!includeUnspeccedTakedowns, (q) => q.where("label.val", "not in", [
118921
+ UNSPECCED_TAKEDOWN_LABEL,
118922
+ UNSPECCED_TAKEDOWN_BLOBS_LABEL
118923
+ ])).limit(limit).execute();
118924
+ const labels = labelRes.map((l) => formatLabel(l));
118925
+ return {
118926
+ encoding: "application/json",
118927
+ body: {
118928
+ labels
118929
+ }
118930
+ };
118931
+ }
118932
+ });
118933
+ }
118934
+
118935
+ // src/api/admin/createCommunicationTemplate.ts
118936
+ function createCommunicationTemplate_default(server, ctx) {
118937
+ server.com.atproto.admin.createCommunicationTemplate({
118938
+ auth: ctx.roleVerifier,
118939
+ handler: async ({ input, auth }) => {
118940
+ const access = auth.credentials;
118941
+ const db = ctx.db;
118942
+ const { createdBy, ...template } = input.body;
118943
+ if (!access.admin) {
118944
+ throw new AuthRequiredError("Must be an admin to create a communication template");
118945
+ }
118946
+ if (!createdBy) {
118947
+ throw new InvalidRequestError("createdBy field is required");
118948
+ }
118949
+ const communicationTemplate = ctx.communicationTemplateService(db);
118950
+ const newTemplate = await communicationTemplate.create({
118951
+ ...template,
118952
+ disabled: false,
118953
+ lastUpdatedBy: createdBy
118954
+ });
118955
+ return {
118956
+ encoding: "application/json",
118957
+ body: communicationTemplate.view(newTemplate)
118958
+ };
118959
+ }
118960
+ });
118961
+ }
118962
+
118963
+ // src/api/admin/updateCommunicationTemplate.ts
118964
+ function updateCommunicationTemplate_default(server, ctx) {
118965
+ server.com.atproto.admin.updateCommunicationTemplate({
118966
+ auth: ctx.roleVerifier,
118967
+ handler: async ({ input, auth }) => {
118968
+ const access = auth.credentials;
118969
+ const db = ctx.db;
118970
+ const { id, updatedBy, ...template } = input.body;
118971
+ if (!access.admin) {
118972
+ throw new AuthRequiredError("Must be an admin to update a communication template");
118973
+ }
118974
+ if (!updatedBy) {
118975
+ throw new InvalidRequestError("updatedBy field is required");
118976
+ }
118977
+ if (!Object.keys(template).length) {
118978
+ throw new InvalidRequestError("Missing update data in request body");
118979
+ }
118980
+ const communicationTemplate = ctx.communicationTemplateService(db);
118981
+ const updatedTemplate = await communicationTemplate.update(Number(id), {
118982
+ ...template,
118983
+ lastUpdatedBy: updatedBy
118984
+ });
118985
+ return {
118986
+ encoding: "application/json",
118987
+ body: communicationTemplate.view(updatedTemplate)
118988
+ };
118989
+ }
118990
+ });
118991
+ }
118992
+
118993
+ // src/api/admin/deleteCommunicationTemplate.ts
118994
+ function deleteCommunicationTemplate_default(server, ctx) {
118995
+ server.com.atproto.admin.deleteCommunicationTemplate({
118996
+ auth: ctx.roleVerifier,
118997
+ handler: async ({ input, auth }) => {
118998
+ const access = auth.credentials;
118999
+ const db = ctx.db;
119000
+ const { id } = input.body;
119001
+ if (!access.admin) {
119002
+ throw new AuthRequiredError("Must be an admin to delete a communication template");
119003
+ }
119004
+ const communicationTemplate = ctx.communicationTemplateService(db);
119005
+ await communicationTemplate.delete(Number(id));
119006
+ }
119007
+ });
119008
+ }
119009
+
119010
+ // src/api/admin/listCommunicationTemplates.ts
119011
+ function listCommunicationTemplates_default(server, ctx) {
119012
+ server.com.atproto.admin.listCommunicationTemplates({
119013
+ auth: ctx.roleVerifier,
119014
+ handler: async ({ auth }) => {
119015
+ const access = auth.credentials;
119016
+ const db = ctx.db;
119017
+ if (!access.moderator) {
119018
+ throw new AuthRequiredError("Must be a full moderator to view list of communication template");
119019
+ }
119020
+ const communicationTemplate = ctx.communicationTemplateService(db);
119021
+ const list = await communicationTemplate.list();
119022
+ return {
119023
+ encoding: "application/json",
119024
+ body: {
119025
+ communicationTemplates: list.map((item) => communicationTemplate.view(item))
119026
+ }
119027
+ };
119028
+ }
119029
+ });
119030
+ }
119031
+
118803
119032
  // src/api/health.ts
119033
+ var health_exports = {};
119034
+ __export(health_exports, {
119035
+ createRouter: () => createRouter
119036
+ });
119037
+ var import_express2 = __toESM(require_express2());
118804
119038
  var createRouter = (ctx) => {
118805
119039
  const router = import_express2.default.Router();
118806
119040
  router.get("/xrpc/_health", async function(req, res) {
@@ -118862,6 +119096,8 @@ function api_default(server, ctx) {
118862
119096
  getModerationEvent_default(server, ctx);
118863
119097
  queryModerationEvents_default(server, ctx);
118864
119098
  queryModerationStatuses_default(server, ctx);
119099
+ queryLabels_default(server, ctx);
119100
+ subscribeLabels_default(server, ctx);
118865
119101
  fetchLabels_default(server, ctx);
118866
119102
  listCommunicationTemplates_default(server, ctx);
118867
119103
  createCommunicationTemplate_default(server, ctx);
@@ -119527,6 +119763,9 @@ var getKey = (doc) => {
119527
119763
  const key = getSigningKey(doc);
119528
119764
  if (!key)
119529
119765
  return void 0;
119766
+ return getDidKeyFromMultibase(key);
119767
+ };
119768
+ var getDidKeyFromMultibase = (key) => {
119530
119769
  const keyBytes = multibaseToBytes(key.publicKeyMultibase);
119531
119770
  let didKey = void 0;
119532
119771
  if (key.type === "EcdsaSecp256r1VerificationKey2019") {
@@ -124579,7 +124818,7 @@ var schemaDict2 = {
124579
124818
  defs: {
124580
124819
  main: {
124581
124820
  type: "query",
124582
- description: "Fetch all labels from a labeler created after a certain date. DEPRECATED: use queryLabels or subscribeLabels instead",
124821
+ description: "DEPRECATED: use queryLabels or subscribeLabels instead -- Fetch all labels from a labeler created after a certain date.",
124583
124822
  parameters: {
124584
124823
  type: "params",
124585
124824
  properties: {
@@ -131887,7 +132126,8 @@ async function up(db) {
131887
132126
  await db.schema.createTable("moderation_event").addColumn("id", "serial", (col) => col.primaryKey()).addColumn("action", "varchar", (col) => col.notNull()).addColumn("subjectType", "varchar", (col) => col.notNull()).addColumn("subjectDid", "varchar", (col) => col.notNull()).addColumn("subjectUri", "varchar").addColumn("subjectCid", "varchar").addColumn("comment", "text").addColumn("meta", "jsonb").addColumn("createdAt", "varchar", (col) => col.notNull()).addColumn("createdBy", "varchar", (col) => col.notNull()).addColumn("reversedAt", "varchar").addColumn("reversedBy", "varchar").addColumn("durationInHours", "integer").addColumn("expiresAt", "varchar").addColumn("reversedReason", "text").addColumn("createLabelVals", "varchar").addColumn("negateLabelVals", "varchar").addColumn("legacyRefId", "integer").execute();
131888
132127
  await db.schema.createTable("moderation_subject_status").addColumn("id", "serial", (col) => col.primaryKey()).addColumn("did", "varchar", (col) => col.notNull()).addColumn("recordPath", "varchar", (col) => col.notNull().defaultTo("")).addColumn("blobCids", "jsonb").addColumn("recordCid", "varchar").addColumn("reviewState", "varchar", (col) => col.notNull()).addColumn("comment", "varchar").addColumn("muteUntil", "varchar").addColumn("lastReviewedAt", "varchar").addColumn("lastReviewedBy", "varchar").addColumn("lastReportedAt", "varchar").addColumn("lastAppealedAt", "varchar").addColumn("takendown", "boolean", (col) => col.defaultTo(false).notNull()).addColumn("suspendUntil", "varchar").addColumn("appealed", "boolean").addColumn("createdAt", "varchar", (col) => col.notNull()).addColumn("updatedAt", "varchar", (col) => col.notNull()).addUniqueConstraint("moderation_status_unique_idx", ["did", "recordPath"]).execute();
131889
132128
  await db.schema.createIndex("moderation_subject_status_blob_cids_idx").on("moderation_subject_status").using("gin").column("blobCids").execute();
131890
- await db.schema.createTable("label").addColumn("src", "varchar", (col) => col.notNull()).addColumn("uri", "varchar", (col) => col.notNull()).addColumn("cid", "varchar", (col) => col.notNull()).addColumn("val", "varchar", (col) => col.notNull()).addColumn("neg", "boolean", (col) => col.notNull()).addColumn("cts", "varchar", (col) => col.notNull()).addPrimaryKeyConstraint("label_pkey", ["src", "uri", "cid", "val"]).execute();
132129
+ await db.schema.createTable("label").addColumn("id", "bigserial", (col) => col.primaryKey()).addColumn("src", "varchar", (col) => col.notNull()).addColumn("uri", "varchar", (col) => col.notNull()).addColumn("cid", "varchar", (col) => col.notNull()).addColumn("val", "varchar", (col) => col.notNull()).addColumn("neg", "boolean", (col) => col.notNull()).addColumn("cts", "varchar", (col) => col.notNull()).execute();
132130
+ await db.schema.createIndex("unique_label_idx").unique().on("label").columns(["src", "uri", "cid", "val"]).execute();
131891
132131
  await db.schema.createIndex("label_uri_index").on("label").column("uri").execute();
131892
132132
  await db.schema.createTable("repo_push_event").addColumn("id", "serial", (col) => col.primaryKey()).addColumn("eventType", "varchar", (col) => col.notNull()).addColumn("subjectDid", "varchar", (col) => col.notNull()).addColumn("takedownRef", "varchar").addColumn("confirmedAt", "timestamptz").addColumn("lastAttempted", "timestamptz").addColumn("attempts", "integer", (col) => col.notNull().defaultTo(0)).addUniqueConstraint("repo_push_event_unique_evt", [
131893
132133
  "subjectDid",
@@ -132402,11 +132642,7 @@ var ModerationViews = class {
132402
132642
  }
132403
132643
  async labels(subject, includeNeg) {
132404
132644
  const res = await this.db.db.selectFrom("label").where("label.uri", "=", subject).if(!includeNeg, (qb) => qb.where("neg", "=", false)).selectAll().execute();
132405
- return res.map((l) => ({
132406
- ...l,
132407
- cid: l.cid === "" ? void 0 : l.cid,
132408
- neg: l.neg
132409
- }));
132645
+ return res.map((l) => formatLabel(l));
132410
132646
  }
132411
132647
  async getSubjectStatus(subjects) {
132412
132648
  const parsedSubjects = subjects.map((subject) => parseSubjectId(subject));
@@ -132629,6 +132865,8 @@ var adjustModerationSubjectStatus = async (db, moderationEvent, blobCids) => {
132629
132865
  subjectStatus.appealed = true;
132630
132866
  newStatus.lastAppealedAt = createdAt;
132631
132867
  subjectStatus.lastAppealedAt = createdAt;
132868
+ subjectStatus.reviewState = REVIEWESCALATED;
132869
+ newStatus.reviewState = REVIEWESCALATED;
132632
132870
  }
132633
132871
  if (action === "com.atproto.admin.defs#modEventResolveAppeal" && subjectStatus.appealed) {
132634
132872
  newStatus.appealed = false;
@@ -132821,6 +133059,9 @@ var paginate = (qb, opts) => {
132821
133059
  return qb.if(!!limit, (q) => q.limit(limit)).if(!nullsLast, (q) => q.orderBy(keyset.primary, direction).orderBy(keyset.secondary, direction)).if(!!nullsLast, (q) => q.orderBy(direction === "asc" ? sql`${keyset.primary} asc nulls last` : sql`${keyset.primary} desc nulls last`).orderBy(direction === "asc" ? sql`${keyset.secondary} asc nulls last` : sql`${keyset.secondary} desc nulls last`)).if(!!keysetSql, (qb2) => keysetSql ? qb2.where(keysetSql) : qb2);
132822
133060
  };
132823
133061
 
133062
+ // src/db/schema/label.ts
133063
+ var LabelChannel = "label_channel";
133064
+
132824
133065
  // src/mod-service/index.ts
132825
133066
  var ModerationService = class {
132826
133067
  constructor(db, backgroundQueue, eventPusher, appviewAgent, appviewAuth, serverDid) {
@@ -133053,17 +133294,15 @@ var ModerationService = class {
133053
133294
  subjectDid: subject.did,
133054
133295
  takedownRef
133055
133296
  }));
133056
- const [repoEvts] = await Promise.all([
133057
- this.db.db.insertInto("repo_push_event").values(values).onConflict((oc) => oc.columns(["subjectDid", "eventType"]).doUpdateSet({
133058
- takedownRef,
133059
- confirmedAt: null,
133060
- attempts: 0,
133061
- lastAttempted: null
133062
- })).returning("id").execute(),
133063
- this.formatAndCreateLabels(subject.did, null, {
133064
- create: [UNSPECCED_TAKEDOWN_LABEL]
133065
- })
133066
- ]);
133297
+ const repoEvts = await this.db.db.insertInto("repo_push_event").values(values).onConflict((oc) => oc.columns(["subjectDid", "eventType"]).doUpdateSet({
133298
+ takedownRef,
133299
+ confirmedAt: null,
133300
+ attempts: 0,
133301
+ lastAttempted: null
133302
+ })).returning("id").execute();
133303
+ await this.formatAndCreateLabels(subject.did, null, {
133304
+ create: [UNSPECCED_TAKEDOWN_LABEL]
133305
+ });
133067
133306
  this.db.onCommit(() => {
133068
133307
  this.backgroundQueue.add(async () => {
133069
133308
  await Promise.all(repoEvts.map((evt) => this.eventPusher.attemptRepoEvent(evt.id)));
@@ -133071,17 +133310,15 @@ var ModerationService = class {
133071
133310
  });
133072
133311
  }
133073
133312
  async reverseTakedownRepo(subject) {
133074
- const [repoEvts] = await Promise.all([
133075
- this.db.db.updateTable("repo_push_event").where("eventType", "in", TAKEDOWNS).where("subjectDid", "=", subject.did).set({
133076
- takedownRef: null,
133077
- confirmedAt: null,
133078
- attempts: 0,
133079
- lastAttempted: null
133080
- }).returning("id").execute(),
133081
- this.formatAndCreateLabels(subject.did, null, {
133082
- negate: [UNSPECCED_TAKEDOWN_LABEL]
133083
- })
133084
- ]);
133313
+ const repoEvts = await this.db.db.updateTable("repo_push_event").where("eventType", "in", TAKEDOWNS).where("subjectDid", "=", subject.did).set({
133314
+ takedownRef: null,
133315
+ confirmedAt: null,
133316
+ attempts: 0,
133317
+ lastAttempted: null
133318
+ }).returning("id").execute();
133319
+ await this.formatAndCreateLabels(subject.did, null, {
133320
+ negate: [UNSPECCED_TAKEDOWN_LABEL]
133321
+ });
133085
133322
  this.db.onCommit(() => {
133086
133323
  this.backgroundQueue.add(async () => {
133087
133324
  await Promise.all(repoEvts.map((evt) => this.eventPusher.attemptRepoEvent(evt.id)));
@@ -133103,15 +133340,15 @@ var ModerationService = class {
133103
133340
  if (blobCids && blobCids.length > 0) {
133104
133341
  labels.push(UNSPECCED_TAKEDOWN_BLOBS_LABEL);
133105
133342
  }
133106
- const [recordEvts] = await Promise.all([
133107
- this.db.db.insertInto("record_push_event").values(values).onConflict((oc) => oc.columns(["subjectUri", "eventType"]).doUpdateSet({
133108
- takedownRef,
133109
- confirmedAt: null,
133110
- attempts: 0,
133111
- lastAttempted: null
133112
- })).returning("id").execute(),
133113
- this.formatAndCreateLabels(subject.uri, subject.cid, { create: labels })
133114
- ]);
133343
+ const recordEvts = await this.db.db.insertInto("record_push_event").values(values).onConflict((oc) => oc.columns(["subjectUri", "eventType"]).doUpdateSet({
133344
+ takedownRef,
133345
+ confirmedAt: null,
133346
+ attempts: 0,
133347
+ lastAttempted: null
133348
+ })).returning("id").execute();
133349
+ await this.formatAndCreateLabels(subject.uri, subject.cid, {
133350
+ create: labels
133351
+ });
133115
133352
  this.db.onCommit(() => {
133116
133353
  this.backgroundQueue.add(async () => {
133117
133354
  await Promise.all(recordEvts.map((evt) => this.eventPusher.attemptRecordEvent(evt.id)));
@@ -133149,16 +133386,15 @@ var ModerationService = class {
133149
133386
  if (blobCids && blobCids.length > 0) {
133150
133387
  labels.push(UNSPECCED_TAKEDOWN_BLOBS_LABEL);
133151
133388
  }
133152
- const [recordEvts] = await Promise.all([
133153
- this.db.db.updateTable("record_push_event").where("eventType", "in", TAKEDOWNS).where("subjectDid", "=", subject.did).where("subjectUri", "=", subject.uri).set({
133154
- takedownRef: null,
133155
- confirmedAt: null,
133156
- attempts: 0,
133157
- lastAttempted: null
133158
- }).returning("id").execute(),
133159
- this.formatAndCreateLabels(subject.uri, subject.cid, { negate: labels })
133160
- ]);
133161
- this.db.onCommit(() => {
133389
+ const recordEvts = await this.db.db.updateTable("record_push_event").where("eventType", "in", TAKEDOWNS).where("subjectDid", "=", subject.did).where("subjectUri", "=", subject.uri).set({
133390
+ takedownRef: null,
133391
+ confirmedAt: null,
133392
+ attempts: 0,
133393
+ lastAttempted: null
133394
+ }).returning("id").execute();
133395
+ await this.formatAndCreateLabels(subject.uri, subject.cid, {
133396
+ negate: labels
133397
+ }), this.db.onCommit(() => {
133162
133398
  this.backgroundQueue.add(async () => {
133163
133399
  await Promise.all(recordEvts.map((evt) => this.eventPusher.attemptRecordEvent(evt.id)));
133164
133400
  });
@@ -133313,8 +133549,10 @@ var ModerationService = class {
133313
133549
  neg: !!l.neg
133314
133550
  }));
133315
133551
  const { ref } = this.db.db.dynamic;
133552
+ await sql`notify ${ref(LabelChannel)}`.execute(this.db.db);
133316
133553
  const excluded = (col) => ref(`excluded.${col}`);
133317
133554
  await this.db.db.insertInto("label").values(dbVals).onConflict((oc) => oc.columns(["src", "uri", "cid", "val"]).doUpdateSet({
133555
+ id: sql`${excluded("id")}`,
133318
133556
  neg: sql`${excluded("neg")}`,
133319
133557
  cts: sql`${excluded("cts")}`
133320
133558
  })).execute();
@@ -133766,6 +134004,101 @@ var OzoneDaemon = class {
133766
134004
  }
133767
134005
  };
133768
134006
 
134007
+ // src/sequencer/sequencer.ts
134008
+ var import_events = __toESM(require("events"));
134009
+ var Sequencer = class extends import_events.default {
134010
+ constructor(db, lastSeen = 0) {
134011
+ super();
134012
+ this.db = db;
134013
+ this.lastSeen = lastSeen;
134014
+ this.destroyed = false;
134015
+ this.queued = false;
134016
+ this.setMaxListeners(100);
134017
+ }
134018
+ async start() {
134019
+ const curr = await this.curr();
134020
+ this.lastSeen = curr ?? 0;
134021
+ this.poll();
134022
+ this.conn = await this.db.pool.connect();
134023
+ this.conn.query(`listen ${LabelChannel}`);
134024
+ this.conn.on("notification", (notif) => {
134025
+ if (notif.channel === LabelChannel) {
134026
+ this.poll();
134027
+ }
134028
+ });
134029
+ }
134030
+ async destroy() {
134031
+ if (this.destroyed)
134032
+ return;
134033
+ this.destroyed = true;
134034
+ if (this.conn) {
134035
+ this.conn.release();
134036
+ this.conn = void 0;
134037
+ }
134038
+ if (this.pollPromise) {
134039
+ await this.pollPromise;
134040
+ }
134041
+ this.emit("close");
134042
+ }
134043
+ async curr() {
134044
+ const got = await this.db.db.selectFrom("label").selectAll().orderBy("id", "desc").limit(1).executeTakeFirst();
134045
+ return got?.id ?? null;
134046
+ }
134047
+ async next(cursor) {
134048
+ const got = await this.db.db.selectFrom("label").selectAll().where("id", ">", cursor).limit(1).orderBy("id", "asc").executeTakeFirst();
134049
+ return got || null;
134050
+ }
134051
+ async requestLabelRange(opts) {
134052
+ const { earliestId, limit } = opts;
134053
+ let seqQb = this.db.db.selectFrom("label").selectAll().orderBy("id", "asc");
134054
+ if (earliestId !== void 0) {
134055
+ seqQb = seqQb.where("id", ">", earliestId);
134056
+ }
134057
+ if (limit !== void 0) {
134058
+ seqQb = seqQb.limit(limit);
134059
+ }
134060
+ const rows = await seqQb.execute();
134061
+ if (rows.length < 1) {
134062
+ return [];
134063
+ }
134064
+ const evts = [];
134065
+ for (const row of rows) {
134066
+ evts.push({
134067
+ seq: row.id,
134068
+ labels: [formatLabel(row)]
134069
+ });
134070
+ }
134071
+ return evts;
134072
+ }
134073
+ poll() {
134074
+ if (this.destroyed)
134075
+ return;
134076
+ if (this.pollPromise) {
134077
+ this.queued = true;
134078
+ return;
134079
+ }
134080
+ this.queued = false;
134081
+ this.pollPromise = this.requestLabelRange({
134082
+ earliestId: this.lastSeen,
134083
+ limit: 500
134084
+ }).then((evts) => {
134085
+ this.emit("events", evts);
134086
+ this.lastSeen = evts.at(-1)?.seq ?? this.lastSeen;
134087
+ if (evts.length > 0) {
134088
+ this.queued = true;
134089
+ }
134090
+ }).catch((err) => {
134091
+ seqLogger.error({ err, lastSeen: this.lastSeen }, "sequencer failed to poll db");
134092
+ }).finally(() => {
134093
+ this.pollPromise = void 0;
134094
+ if (this.queued) {
134095
+ this.poll();
134096
+ }
134097
+ });
134098
+ }
134099
+ };
134100
+ var sequencer_default = Sequencer;
134101
+
133769
134102
  // src/communication-service/template.ts
133770
134103
  var CommunicationTemplateService = class {
133771
134104
  constructor(db) {
@@ -133842,7 +134175,10 @@ var AppContext = class {
133842
134175
  static async fromConfig(cfg, secrets, overrides) {
133843
134176
  const db = new Database({
133844
134177
  url: cfg.db.postgresUrl,
133845
- schema: cfg.db.postgresSchema
134178
+ schema: cfg.db.postgresSchema,
134179
+ poolSize: cfg.db.poolSize,
134180
+ poolMaxUses: cfg.db.poolMaxUses,
134181
+ poolIdleTimeoutMs: cfg.db.poolIdleTimeoutMs
133846
134182
  });
133847
134183
  const signingKey = await Secp256k1Keypair.import(secrets.signingKeyHex);
133848
134184
  const appviewAgent = new AtpAgent({ service: cfg.appview.url });
@@ -133863,6 +134199,7 @@ var AppContext = class {
133863
134199
  const idResolver = new IdResolver({
133864
134200
  plcUrl: cfg.identity.plcUrl
133865
134201
  });
134202
+ const sequencer = new sequencer_default(db);
133866
134203
  return new AppContext({
133867
134204
  db,
133868
134205
  cfg,
@@ -133873,6 +134210,7 @@ var AppContext = class {
133873
134210
  signingKey,
133874
134211
  idResolver,
133875
134212
  backgroundQueue,
134213
+ sequencer,
133876
134214
  ...overrides ?? {}
133877
134215
  }, secrets);
133878
134216
  }
@@ -133910,6 +134248,9 @@ var AppContext = class {
133910
134248
  get backgroundQueue() {
133911
134249
  return this.opts.backgroundQueue;
133912
134250
  }
134251
+ get sequencer() {
134252
+ return this.opts.sequencer;
134253
+ }
133913
134254
  get authVerifier() {
133914
134255
  return authVerifier(this.idResolver, { aud: this.cfg.service.did });
133915
134256
  }
@@ -133965,7 +134306,10 @@ var envToCfg = (env) => {
133965
134306
  (0, import_node_assert.default)(env.dbPostgresUrl);
133966
134307
  const dbCfg = {
133967
134308
  postgresUrl: env.dbPostgresUrl,
133968
- postgresSchema: env.dbPostgresSchema
134309
+ postgresSchema: env.dbPostgresSchema,
134310
+ poolSize: env.dbPoolSize,
134311
+ poolMaxUses: env.dbPoolMaxUses,
134312
+ poolIdleTimeoutMs: env.dbPoolIdleTimeoutMs
133969
134313
  };
133970
134314
  (0, import_node_assert.default)(env.appviewUrl);
133971
134315
  (0, import_node_assert.default)(env.appviewDid);
@@ -134006,6 +134350,9 @@ var readEnv = () => {
134006
134350
  pdsDid: envStr("OZONE_PDS_DID"),
134007
134351
  dbPostgresUrl: envStr("OZONE_DB_POSTGRES_URL"),
134008
134352
  dbPostgresSchema: envStr("OZONE_DB_POSTGRES_SCHEMA"),
134353
+ dbPoolSize: envInt("OZONE_DB_POOL_SIZE"),
134354
+ dbPoolMaxUses: envInt("OZONE_DB_POOL_MAX_USES"),
134355
+ dbPoolIdleTimeoutMs: envInt("OZONE_DB_POOL_IDLE_TIMEOUT_MS"),
134009
134356
  didPlcUrl: envStr("OZONE_DID_PLC_URL"),
134010
134357
  adminPassword: envStr("OZONE_ADMIN_PASSWORD"),
134011
134358
  moderatorPassword: envStr("OZONE_MODERATOR_PASSWORD"),
@@ -134070,11 +134417,12 @@ var OzoneService = class {
134070
134417
  waitingCount: backgroundQueue.queue.size
134071
134418
  }, "background queue stats");
134072
134419
  }, 1e4);
134420
+ await this.ctx.sequencer.start();
134073
134421
  const server = this.app.listen(this.ctx.cfg.service.port);
134074
134422
  this.server = server;
134075
134423
  server.keepAliveTimeout = 9e4;
134076
134424
  this.terminator = (0, import_http_terminator.createHttpTerminator)({ server });
134077
- await import_events.default.once(server, "listening");
134425
+ await import_events2.default.once(server, "listening");
134078
134426
  const { port } = server.address();
134079
134427
  this.ctx.assignPort(port);
134080
134428
  return server;
@@ -134082,6 +134430,7 @@ var OzoneService = class {
134082
134430
  async destroy() {
134083
134431
  await this.terminator?.terminate();
134084
134432
  await this.ctx.backgroundQueue.destroy();
134433
+ await this.ctx.sequencer.destroy();
134085
134434
  await this.ctx.db.close();
134086
134435
  clearInterval(this.dbStatsInterval);
134087
134436
  }