@warlock.js/notifications 5.31.0 → 5.32.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.
- package/CHANGELOG.md +14 -0
- package/cjs/index.cjs +2 -2
- package/cjs/index.cjs.map +1 -1
- package/esm/channels/database-channel.d.mts +2 -3
- package/esm/channels/database-channel.d.mts.map +1 -1
- package/esm/channels/index.d.mts +2 -1
- package/esm/channels/index.mjs +1 -1
- package/esm/channels/mail-channel.d.mts +6 -4
- package/esm/channels/mail-channel.d.mts.map +1 -1
- package/esm/config.d.mts +13 -9
- package/esm/config.d.mts.map +1 -1
- package/esm/contracts/channel.contract.d.mts +1 -3
- package/esm/contracts/channel.contract.d.mts.map +1 -1
- package/esm/contracts/index.d.mts +2 -1
- package/esm/contracts/notification.contract.d.mts +1 -3
- package/esm/contracts/notification.contract.d.mts.map +1 -1
- package/esm/contracts/preference-provider.contract.d.mts +1 -3
- package/esm/contracts/preference-provider.contract.d.mts.map +1 -1
- package/esm/contracts/queue-dispatcher.contract.d.mts +1 -3
- package/esm/contracts/queue-dispatcher.contract.d.mts.map +1 -1
- package/esm/contracts/rate-limiter.contract.d.mts +1 -3
- package/esm/contracts/rate-limiter.contract.d.mts.map +1 -1
- package/esm/dispatch/define-channel.d.mts +2 -2
- package/esm/dispatch/define-channel.d.mts.map +1 -1
- package/esm/dispatch/define-notification.d.mts +5 -6
- package/esm/dispatch/define-notification.d.mts.map +1 -1
- package/esm/dispatch/index.d.mts +2 -1
- package/esm/dispatch/index.mjs +1 -1
- package/esm/dispatch/notifications-event-bus.d.mts +2 -3
- package/esm/dispatch/notifications-event-bus.d.mts.map +1 -1
- package/esm/dispatch/notify.d.mts +3 -5
- package/esm/dispatch/notify.d.mts.map +1 -1
- package/esm/errors.d.mts +5 -6
- package/esm/errors.d.mts.map +1 -1
- package/esm/in-app/base-notifications-repository.d.mts +6 -6
- package/esm/in-app/base-notifications-repository.d.mts.map +1 -1
- package/esm/in-app/base-notifications-repository.mjs +1 -1
- package/esm/in-app/base-notifications-repository.mjs.map +1 -1
- package/esm/in-app/column-map.d.mts +11 -8
- package/esm/in-app/column-map.d.mts.map +1 -1
- package/esm/in-app/database-notification.d.mts +2 -3
- package/esm/in-app/database-notification.d.mts.map +1 -1
- package/esm/in-app/in-app.d.mts +6 -5
- package/esm/in-app/in-app.d.mts.map +1 -1
- package/esm/in-app/index.d.mts +2 -1
- package/esm/in-app/index.mjs +1 -1
- package/esm/index.d.mts +6 -0
- package/esm/migration/index.d.mts +2 -1
- package/esm/migration/index.mjs +1 -1
- package/esm/migration/notification-columns.d.mts +6 -7
- package/esm/migration/notification-columns.d.mts.map +1 -1
- package/esm/queue/bullmq-queue.d.mts +9 -7
- package/esm/queue/bullmq-queue.d.mts.map +1 -1
- package/esm/queue/herald-queue.d.mts +6 -4
- package/esm/queue/herald-queue.d.mts.map +1 -1
- package/esm/queue/index.d.mts +2 -1
- package/esm/queue/index.mjs +1 -1
- package/esm/queue/load-herald.d.mts +1 -2
- package/esm/queue/load-herald.d.mts.map +1 -1
- package/esm/queue/load-herald.mjs +1 -1
- package/esm/queue/load-queue.d.mts +2 -3
- package/esm/queue/load-queue.d.mts.map +1 -1
- package/esm/queue/notifications-worker.d.mts +5 -4
- package/esm/queue/notifications-worker.d.mts.map +1 -1
- package/esm/queue/queue-package-not-installed.error.d.mts +1 -2
- package/esm/queue/queue-package-not-installed.error.d.mts.map +1 -1
- package/esm/types.d.mts +22 -18
- package/esm/types.d.mts.map +1 -1
- package/package.json +10 -9
- package/cjs/channel_api-C5ZZDkgQ.cjs +0 -7463
- package/cjs/channel_api-C5ZZDkgQ.cjs.map +0 -1
- package/cjs/chunk-fl3r8ClO.cjs +0 -41
- package/cjs/rabbitmq-driver-CkPaCswV.cjs +0 -3
- package/cjs/src-CcbF8Hr1.cjs +0 -11276
- package/cjs/src-CcbF8Hr1.cjs.map +0 -1
- package/esm/_virtual/_rolldown/runtime.mjs +0 -32
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/_internal.mjs +0 -6
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/_internal.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/bool.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/color.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/date.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/float.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/id.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/int.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/nanoid.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/pick.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/random.mjs +0 -16
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/sample.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/string.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/token.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/uuid.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/Random/weighted.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/async/retry.mjs +0 -3
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/index.mjs +0 -24
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/mixed/clone/clone.mjs +0 -82
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/mixed/clone/clone.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/number/round.mjs +0 -17
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/number/round.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/object/except.mjs +0 -13
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/object/except.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/object/get.mjs +0 -18
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/object/get.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/object/omit.mjs +0 -17
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/object/omit.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/object/unset.mjs +0 -30
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/object/unset.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/capitalize.mjs +0 -19
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/capitalize.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/ltrim.mjs +0 -18
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/ltrim.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/readMoreChars.mjs +0 -14
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/readMoreChars.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/rtrim.mjs +0 -18
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/rtrim.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/toCamelCase.mjs +0 -22
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/toCamelCase.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/toKebabCase.mjs +0 -17
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/toKebabCase.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/toSnakeCase.mjs +0 -21
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/toSnakeCase.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/toStudlyCase.mjs +0 -21
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/toStudlyCase.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/trim.mjs +0 -20
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/trim.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/ucfirst.mjs +0 -15
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/ucfirst.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/words.mjs +0 -25
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/string/words.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/utils/escapeRegex.mjs +0 -11
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/utils/escapeRegex.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/utils/lazy.mjs +0 -100
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/utils/lazy.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/utils/tap.mjs +0 -27
- package/esm/node_modules/.pnpm/@mongez_reinforcements@4.0.2/node_modules/@mongez/reinforcements/esm/utils/tap.mjs.map +0 -1
- package/esm/node_modules/.pnpm/@mongez_supportive-is@3.0.0/node_modules/@mongez/supportive-is/esm/index.mjs +0 -358
- package/esm/node_modules/.pnpm/@mongez_supportive-is@3.0.0/node_modules/@mongez/supportive-is/esm/index.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/channel_api.mjs +0 -28
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/channel_api.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/api_args.mjs +0 -241
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/api_args.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/bitset.mjs +0 -130
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/bitset.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/channel.mjs +0 -302
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/channel.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/channel_model.mjs +0 -206
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/channel_model.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/codec.mjs +0 -273
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/codec.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/connect.mjs +0 -143
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/connect.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/connection.mjs +0 -416
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/connection.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/credentials.mjs +0 -50
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/credentials.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/defs.mjs +0 -4600
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/defs.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/error.mjs +0 -29
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/error.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/format.mjs +0 -28
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/format.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/frame.mjs +0 -130
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/frame.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/heartbeat.mjs +0 -40
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/heartbeat.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/mux.mjs +0 -86
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/lib/mux.mjs.map +0 -1
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/package.mjs +0 -41
- package/esm/node_modules/.pnpm/amqplib@0.10.9/node_modules/amqplib/package.mjs.map +0 -1
- package/esm/node_modules/.pnpm/buffer-more-ints@1.0.0/node_modules/buffer-more-ints/buffer-more-ints.mjs +0 -360
- package/esm/node_modules/.pnpm/buffer-more-ints@1.0.0/node_modules/buffer-more-ints/buffer-more-ints.mjs.map +0 -1
- package/esm/node_modules/.pnpm/dayjs@1.11.23/node_modules/dayjs/dayjs.min.mjs +0 -305
- package/esm/node_modules/.pnpm/dayjs@1.11.23/node_modules/dayjs/dayjs.min.mjs.map +0 -1
- package/esm/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.mjs +0 -80
- package/esm/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.mjs.map +0 -1
- package/esm/node_modules/.pnpm/requires-port@1.0.0/node_modules/requires-port/index.mjs +0 -35
- package/esm/node_modules/.pnpm/requires-port@1.0.0/node_modules/requires-port/index.mjs.map +0 -1
- package/esm/node_modules/.pnpm/url-parse@1.5.10/node_modules/url-parse/index.mjs +0 -388
- package/esm/node_modules/.pnpm/url-parse@1.5.10/node_modules/url-parse/index.mjs.map +0 -1
- package/esm/packages/herald/src/communicators/broker-registry.mjs +0 -204
- package/esm/packages/herald/src/communicators/broker-registry.mjs.map +0 -1
- package/esm/packages/herald/src/communicators/broker.mjs +0 -110
- package/esm/packages/herald/src/communicators/broker.mjs.map +0 -1
- package/esm/packages/herald/src/communicators/index.mjs +0 -4
- package/esm/packages/herald/src/decorators/consumable.mjs +0 -36
- package/esm/packages/herald/src/decorators/consumable.mjs.map +0 -1
- package/esm/packages/herald/src/decorators/index.mjs +0 -3
- package/esm/packages/herald/src/drivers/index.mjs +0 -5
- package/esm/packages/herald/src/drivers/rabbitmq/index.mjs +0 -4
- package/esm/packages/herald/src/drivers/rabbitmq/rabbitmq-channel.mjs +0 -403
- package/esm/packages/herald/src/drivers/rabbitmq/rabbitmq-channel.mjs.map +0 -1
- package/esm/packages/herald/src/drivers/rabbitmq/rabbitmq-driver.mjs +0 -303
- package/esm/packages/herald/src/drivers/rabbitmq/rabbitmq-driver.mjs.map +0 -1
- package/esm/packages/herald/src/index.mjs +0 -16
- package/esm/packages/herald/src/message-managers/event-consumer.mjs +0 -76
- package/esm/packages/herald/src/message-managers/event-consumer.mjs.map +0 -1
- package/esm/packages/herald/src/message-managers/event-message.mjs +0 -85
- package/esm/packages/herald/src/message-managers/event-message.mjs.map +0 -1
- package/esm/packages/herald/src/message-managers/index.mjs +0 -4
- package/esm/packages/herald/src/message-managers/prepare-consumer-subscription.mjs +0 -42
- package/esm/packages/herald/src/message-managers/prepare-consumer-subscription.mjs.map +0 -1
- package/esm/packages/herald/src/use-case-broadcast.mjs +0 -30
- package/esm/packages/herald/src/use-case-broadcast.mjs.map +0 -1
- package/esm/packages/herald/src/utils/connect-to-broker.mjs +0 -168
- package/esm/packages/herald/src/utils/connect-to-broker.mjs.map +0 -1
- package/esm/packages/herald/src/utils/index.mjs +0 -3
- package/esm/packages/seal/src/config.mjs +0 -15
- package/esm/packages/seal/src/config.mjs.map +0 -1
- package/esm/packages/seal/src/factory/index.mjs +0 -4
- package/esm/packages/seal/src/factory/validate.mjs +0 -42
- package/esm/packages/seal/src/factory/validate.mjs.map +0 -1
- package/esm/packages/seal/src/factory/validators.mjs +0 -139
- package/esm/packages/seal/src/factory/validators.mjs.map +0 -1
- package/esm/packages/seal/src/helpers/date-helpers.mjs +0 -24
- package/esm/packages/seal/src/helpers/date-helpers.mjs.map +0 -1
- package/esm/packages/seal/src/helpers/get-field-value.mjs +0 -46
- package/esm/packages/seal/src/helpers/get-field-value.mjs.map +0 -1
- package/esm/packages/seal/src/helpers/index.mjs +0 -6
- package/esm/packages/seal/src/helpers/is-empty-value.mjs +0 -10
- package/esm/packages/seal/src/helpers/is-empty-value.mjs.map +0 -1
- package/esm/packages/seal/src/helpers/path-helpers.mjs +0 -12
- package/esm/packages/seal/src/helpers/path-helpers.mjs.map +0 -1
- package/esm/packages/seal/src/helpers/validation-helpers.mjs +0 -78
- package/esm/packages/seal/src/helpers/validation-helpers.mjs.map +0 -1
- package/esm/packages/seal/src/index.mjs +0 -88
- package/esm/packages/seal/src/mutators/array-mutators.mjs +0 -32
- package/esm/packages/seal/src/mutators/array-mutators.mjs.map +0 -1
- package/esm/packages/seal/src/mutators/boolean-mutators.mjs +0 -40
- package/esm/packages/seal/src/mutators/boolean-mutators.mjs.map +0 -1
- package/esm/packages/seal/src/mutators/date-mutators.mjs +0 -94
- package/esm/packages/seal/src/mutators/date-mutators.mjs.map +0 -1
- package/esm/packages/seal/src/mutators/index.mjs +0 -9
- package/esm/packages/seal/src/mutators/number-mutators.mjs +0 -52
- package/esm/packages/seal/src/mutators/number-mutators.mjs.map +0 -1
- package/esm/packages/seal/src/mutators/object-mutators.mjs +0 -30
- package/esm/packages/seal/src/mutators/object-mutators.mjs.map +0 -1
- package/esm/packages/seal/src/mutators/scalar-mutators.mjs +0 -9
- package/esm/packages/seal/src/mutators/scalar-mutators.mjs.map +0 -1
- package/esm/packages/seal/src/mutators/string-mutators.mjs +0 -186
- package/esm/packages/seal/src/mutators/string-mutators.mjs.map +0 -1
- package/esm/packages/seal/src/object.mjs +0 -13
- package/esm/packages/seal/src/object.mjs.map +0 -1
- package/esm/packages/seal/src/rules/array/array-rules.mjs +0 -41
- package/esm/packages/seal/src/rules/array/array-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/array/index.mjs +0 -3
- package/esm/packages/seal/src/rules/color/color-rules.mjs +0 -104
- package/esm/packages/seal/src/rules/color/color-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/color/index.mjs +0 -3
- package/esm/packages/seal/src/rules/common/enum.mjs +0 -77
- package/esm/packages/seal/src/rules/common/enum.mjs.map +0 -1
- package/esm/packages/seal/src/rules/common/equals-field-rules.mjs +0 -42
- package/esm/packages/seal/src/rules/common/equals-field-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/common/index.mjs +0 -8
- package/esm/packages/seal/src/rules/common/instanceof.mjs +0 -23
- package/esm/packages/seal/src/rules/common/instanceof.mjs.map +0 -1
- package/esm/packages/seal/src/rules/common/literal.mjs +0 -31
- package/esm/packages/seal/src/rules/common/literal.mjs.map +0 -1
- package/esm/packages/seal/src/rules/common/type-rules.mjs +0 -97
- package/esm/packages/seal/src/rules/common/type-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/common/unknown-key.mjs +0 -25
- package/esm/packages/seal/src/rules/common/unknown-key.mjs.map +0 -1
- package/esm/packages/seal/src/rules/conditional/forbidden-if-rules.mjs +0 -116
- package/esm/packages/seal/src/rules/conditional/forbidden-if-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/conditional/index.mjs +0 -12
- package/esm/packages/seal/src/rules/conditional/present-if-rules.mjs +0 -97
- package/esm/packages/seal/src/rules/conditional/present-if-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/conditional/present-unless-rules.mjs +0 -30
- package/esm/packages/seal/src/rules/conditional/present-unless-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/conditional/present-with-rules.mjs +0 -76
- package/esm/packages/seal/src/rules/conditional/present-with-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/conditional/present-without-rules.mjs +0 -76
- package/esm/packages/seal/src/rules/conditional/present-without-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/conditional/required-if-rules.mjs +0 -204
- package/esm/packages/seal/src/rules/conditional/required-if-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/conditional/required-unless-rules.mjs +0 -31
- package/esm/packages/seal/src/rules/conditional/required-unless-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/conditional/required-when-rule.mjs +0 -32
- package/esm/packages/seal/src/rules/conditional/required-when-rule.mjs.map +0 -1
- package/esm/packages/seal/src/rules/conditional/required-with-rules.mjs +0 -67
- package/esm/packages/seal/src/rules/conditional/required-with-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/conditional/required-without-rules.mjs +0 -67
- package/esm/packages/seal/src/rules/conditional/required-without-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/core/equal.mjs +0 -22
- package/esm/packages/seal/src/rules/core/equal.mjs.map +0 -1
- package/esm/packages/seal/src/rules/core/forbidden.mjs +0 -20
- package/esm/packages/seal/src/rules/core/forbidden.mjs.map +0 -1
- package/esm/packages/seal/src/rules/core/index.mjs +0 -7
- package/esm/packages/seal/src/rules/core/required.mjs +0 -36
- package/esm/packages/seal/src/rules/core/required.mjs.map +0 -1
- package/esm/packages/seal/src/rules/core/union.mjs +0 -78
- package/esm/packages/seal/src/rules/core/union.mjs.map +0 -1
- package/esm/packages/seal/src/rules/core/when.mjs +0 -37
- package/esm/packages/seal/src/rules/core/when.mjs.map +0 -1
- package/esm/packages/seal/src/rules/date/date-comparison-rules.mjs +0 -78
- package/esm/packages/seal/src/rules/date/date-comparison-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/date/date-day-rules.mjs +0 -49
- package/esm/packages/seal/src/rules/date/date-day-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/date/date-field-comparison-rules.mjs +0 -82
- package/esm/packages/seal/src/rules/date/date-field-comparison-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/date/date-period-rules.mjs +0 -401
- package/esm/packages/seal/src/rules/date/date-period-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/date/date-relative-rules.mjs +0 -55
- package/esm/packages/seal/src/rules/date/date-relative-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/date/date-special-rules.mjs +0 -58
- package/esm/packages/seal/src/rules/date/date-special-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/date/date.mjs +0 -235
- package/esm/packages/seal/src/rules/date/date.mjs.map +0 -1
- package/esm/packages/seal/src/rules/date/index.mjs +0 -9
- package/esm/packages/seal/src/rules/file/dimensions.mjs +0 -3
- package/esm/packages/seal/src/rules/file/file-size.mjs +0 -3
- package/esm/packages/seal/src/rules/file/index.mjs +0 -4
- package/esm/packages/seal/src/rules/index.mjs +0 -54
- package/esm/packages/seal/src/rules/length/index.mjs +0 -3
- package/esm/packages/seal/src/rules/length/length-rules.mjs +0 -98
- package/esm/packages/seal/src/rules/length/length-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/number/index.mjs +0 -3
- package/esm/packages/seal/src/rules/number/number-rules.mjs +0 -197
- package/esm/packages/seal/src/rules/number/number-rules.mjs.map +0 -1
- package/esm/packages/seal/src/rules/scalar/accepted-rule.mjs +0 -123
- package/esm/packages/seal/src/rules/scalar/accepted-rule.mjs.map +0 -1
- package/esm/packages/seal/src/rules/scalar/declined-rule.mjs +0 -123
- package/esm/packages/seal/src/rules/scalar/declined-rule.mjs.map +0 -1
- package/esm/packages/seal/src/rules/scalar/index.mjs +0 -4
- package/esm/packages/seal/src/rules/string/alpha.mjs +0 -41
- package/esm/packages/seal/src/rules/string/alpha.mjs.map +0 -1
- package/esm/packages/seal/src/rules/string/credit-card.mjs +0 -32
- package/esm/packages/seal/src/rules/string/credit-card.mjs.map +0 -1
- package/esm/packages/seal/src/rules/string/email.mjs +0 -20
- package/esm/packages/seal/src/rules/string/email.mjs.map +0 -1
- package/esm/packages/seal/src/rules/string/id-formats.mjs +0 -104
- package/esm/packages/seal/src/rules/string/id-formats.mjs.map +0 -1
- package/esm/packages/seal/src/rules/string/index.mjs +0 -13
- package/esm/packages/seal/src/rules/string/ip.mjs +0 -66
- package/esm/packages/seal/src/rules/string/ip.mjs.map +0 -1
- package/esm/packages/seal/src/rules/string/matches.mjs +0 -4
- package/esm/packages/seal/src/rules/string/pattern.mjs +0 -20
- package/esm/packages/seal/src/rules/string/pattern.mjs.map +0 -1
- package/esm/packages/seal/src/rules/string/string-comparison.mjs +0 -56
- package/esm/packages/seal/src/rules/string/string-comparison.mjs.map +0 -1
- package/esm/packages/seal/src/rules/string/strong-password-rule.mjs +0 -31
- package/esm/packages/seal/src/rules/string/strong-password-rule.mjs.map +0 -1
- package/esm/packages/seal/src/rules/string/url.mjs +0 -23
- package/esm/packages/seal/src/rules/string/url.mjs.map +0 -1
- package/esm/packages/seal/src/rules/string/without-whitespace.mjs +0 -19
- package/esm/packages/seal/src/rules/string/without-whitespace.mjs.map +0 -1
- package/esm/packages/seal/src/standard-schema/json-schema.mjs +0 -81
- package/esm/packages/seal/src/standard-schema/json-schema.mjs.map +0 -1
- package/esm/packages/seal/src/standard-schema/map-result.mjs +0 -26
- package/esm/packages/seal/src/standard-schema/map-result.mjs.map +0 -1
- package/esm/packages/seal/src/string.mjs +0 -13
- package/esm/packages/seal/src/string.mjs.map +0 -1
- package/esm/packages/seal/src/types/date-types.mjs +0 -17
- package/esm/packages/seal/src/types/date-types.mjs.map +0 -1
- package/esm/packages/seal/src/validators/any-validator.mjs +0 -38
- package/esm/packages/seal/src/validators/any-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/array-validator.mjs +0 -186
- package/esm/packages/seal/src/validators/array-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/base-validator.mjs +0 -750
- package/esm/packages/seal/src/validators/base-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/boolean-validator.mjs +0 -175
- package/esm/packages/seal/src/validators/boolean-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/computed-validator.mjs +0 -118
- package/esm/packages/seal/src/validators/computed-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/date-validator.mjs +0 -640
- package/esm/packages/seal/src/validators/date-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/discriminated-union-validator.mjs +0 -138
- package/esm/packages/seal/src/validators/discriminated-union-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/float-validator.mjs +0 -18
- package/esm/packages/seal/src/validators/float-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/index.mjs +0 -28
- package/esm/packages/seal/src/validators/instanceof-validator.mjs +0 -64
- package/esm/packages/seal/src/validators/instanceof-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/int-validator.mjs +0 -30
- package/esm/packages/seal/src/validators/int-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/lazy-validator.mjs +0 -87
- package/esm/packages/seal/src/validators/lazy-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/literal-validator.mjs +0 -72
- package/esm/packages/seal/src/validators/literal-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/managed-validator.mjs +0 -39
- package/esm/packages/seal/src/validators/managed-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/methods/equality-conditional-methods.mjs +0 -129
- package/esm/packages/seal/src/validators/methods/equality-conditional-methods.mjs.map +0 -1
- package/esm/packages/seal/src/validators/methods/forbidden-methods.mjs +0 -131
- package/esm/packages/seal/src/validators/methods/forbidden-methods.mjs.map +0 -1
- package/esm/packages/seal/src/validators/methods/present-methods.mjs +0 -235
- package/esm/packages/seal/src/validators/methods/present-methods.mjs.map +0 -1
- package/esm/packages/seal/src/validators/methods/required-methods.mjs +0 -347
- package/esm/packages/seal/src/validators/methods/required-methods.mjs.map +0 -1
- package/esm/packages/seal/src/validators/number-validator.mjs +0 -331
- package/esm/packages/seal/src/validators/number-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/numeric-validator.mjs +0 -27
- package/esm/packages/seal/src/validators/numeric-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/object-validator.mjs +0 -447
- package/esm/packages/seal/src/validators/object-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/primitive-validator.mjs +0 -88
- package/esm/packages/seal/src/validators/primitive-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/record-validator.mjs +0 -112
- package/esm/packages/seal/src/validators/record-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/scalar-validator.mjs +0 -173
- package/esm/packages/seal/src/validators/scalar-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/string-validator.mjs +0 -459
- package/esm/packages/seal/src/validators/string-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/tuple-validator.mjs +0 -134
- package/esm/packages/seal/src/validators/tuple-validator.mjs.map +0 -1
- package/esm/packages/seal/src/validators/union-validator.mjs +0 -68
- package/esm/packages/seal/src/validators/union-validator.mjs.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Id, Notifiable, SendOptions } from "../types.mjs";
|
|
2
|
-
|
|
3
2
|
//#region ../../packages/notifications/src/contracts/channel.contract.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* A channel = one `send` + how it resolves a route from a notifiable.
|
|
@@ -9,7 +8,7 @@ import { Id, Notifiable, SendOptions } from "../types.mjs";
|
|
|
9
8
|
* When `route` returns `undefined`, the dispatcher tries `notifiable.id` as
|
|
10
9
|
* a fallback.
|
|
11
10
|
*/
|
|
12
|
-
interface Channel<P> {
|
|
11
|
+
export interface Channel<P> {
|
|
13
12
|
/** Unique channel name — matches the key in `NotificationChannels`. */
|
|
14
13
|
readonly name: string;
|
|
15
14
|
/**
|
|
@@ -34,5 +33,4 @@ interface Channel<P> {
|
|
|
34
33
|
}): Promise<void>;
|
|
35
34
|
}
|
|
36
35
|
//#endregion
|
|
37
|
-
export { Channel };
|
|
38
36
|
//# sourceMappingURL=channel.contract.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.contract.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/contracts/channel.contract.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"channel.contract.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/contracts/channel.contract.ts"],"mappings":";;;;;;;;;;iBAUiB,QAAQ;;WAEd;;;;;;EAOT,OAAO,YAAY;IAAwB,IAAI;;;;;;EAM/C,KAAK;IACH,SAAS;IACT;MAAkB,IAAI;;IACtB,aAAa;IACb,SAAS;MACP"}
|
|
@@ -2,4 +2,5 @@ import { Channel } from "./channel.contract.mjs";
|
|
|
2
2
|
import { NotificationContract } from "./notification.contract.mjs";
|
|
3
3
|
import { PreferenceProvider } from "./preference-provider.contract.mjs";
|
|
4
4
|
import { QueueDispatcher } from "./queue-dispatcher.contract.mjs";
|
|
5
|
-
import { RateLimiter } from "./rate-limiter.contract.mjs";
|
|
5
|
+
import { RateLimiter } from "./rate-limiter.contract.mjs";
|
|
6
|
+
export { Channel, NotificationContract, PreferenceProvider, QueueDispatcher, RateLimiter };
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { Id } from "../types.mjs";
|
|
2
|
-
|
|
3
2
|
//#region ../../packages/notifications/src/contracts/notification.contract.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* The stored in-app record contract the database channel + `inApp` depend on.
|
|
6
5
|
* Accessors are the STABLE surface; physical columns vary per app and are
|
|
7
6
|
* resolved from the model's `columnMap` (see `DatabaseNotification`).
|
|
8
7
|
*/
|
|
9
|
-
interface NotificationContract {
|
|
8
|
+
export interface NotificationContract {
|
|
10
9
|
readonly recipientId: Id;
|
|
11
10
|
readonly type: string;
|
|
12
11
|
readonly isRead: boolean;
|
|
@@ -14,5 +13,4 @@ interface NotificationContract {
|
|
|
14
13
|
markRead(): Promise<void>;
|
|
15
14
|
}
|
|
16
15
|
//#endregion
|
|
17
|
-
export { NotificationContract };
|
|
18
16
|
//# sourceMappingURL=notification.contract.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification.contract.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/contracts/notification.contract.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"notification.contract.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/contracts/notification.contract.ts"],"mappings":";;;;;;;iBAOiB;WACN,aAAa;WACb;WACA;WACA,QAAQ;EACjB,YAAY"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ChannelName, Notifiable } from "../types.mjs";
|
|
2
|
-
|
|
3
2
|
//#region ../../packages/notifications/src/contracts/preference-provider.contract.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Pre-send gate consulted BEFORE each channel dispatch. Returns the subset of
|
|
@@ -12,9 +11,8 @@ import { ChannelName, Notifiable } from "../types.mjs";
|
|
|
12
11
|
* App-owned (set in the `preferences` slot of `config/notifications.ts`). The
|
|
13
12
|
* package reserves the slot but ships no default implementation.
|
|
14
13
|
*/
|
|
15
|
-
interface PreferenceProvider {
|
|
14
|
+
export interface PreferenceProvider {
|
|
16
15
|
resolveChannels(notifiable: Notifiable, type: string, requestedChannels: ChannelName[]): Promise<ChannelName[]> | ChannelName[];
|
|
17
16
|
}
|
|
18
17
|
//#endregion
|
|
19
|
-
export { PreferenceProvider };
|
|
20
18
|
//# sourceMappingURL=preference-provider.contract.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preference-provider.contract.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/contracts/preference-provider.contract.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"preference-provider.contract.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/contracts/preference-provider.contract.ts"],"mappings":";;;;;;;;;;;;;iBAaiB;EACf,gBACE,YAAY,YACZ,cACA,mBAAmB,gBAClB,QAAQ,iBAAiB"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { SendOptions } from "../types.mjs";
|
|
2
|
-
|
|
3
2
|
//#region ../../packages/notifications/src/contracts/queue-dispatcher.contract.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Async dispatcher contract — what `.queue(...)` hands rendered jobs to.
|
|
@@ -10,7 +9,7 @@ import { SendOptions } from "../types.mjs";
|
|
|
10
9
|
* worker only needs to look up the channel by name and call `channel.send`.
|
|
11
10
|
* No model re-hydration, no closure serialization.
|
|
12
11
|
*/
|
|
13
|
-
interface QueueDispatcher {
|
|
12
|
+
export interface QueueDispatcher {
|
|
14
13
|
dispatch(job: {
|
|
15
14
|
channel: string;
|
|
16
15
|
route: unknown;
|
|
@@ -19,5 +18,4 @@ interface QueueDispatcher {
|
|
|
19
18
|
}): Promise<void>;
|
|
20
19
|
}
|
|
21
20
|
//#endregion
|
|
22
|
-
export { QueueDispatcher };
|
|
23
21
|
//# sourceMappingURL=queue-dispatcher.contract.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue-dispatcher.contract.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/contracts/queue-dispatcher.contract.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"queue-dispatcher.contract.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/contracts/queue-dispatcher.contract.ts"],"mappings":";;;;;;;;;;;iBAWiB;EACf,SAAS;IACP;IACA;IACA;IACA,SAAS;MACP"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ChannelName, Notifiable } from "../types.mjs";
|
|
2
|
-
|
|
3
2
|
//#region ../../packages/notifications/src/contracts/rate-limiter.contract.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Per-(recipient, channel, type) rate limit. Return `false` to drop the
|
|
@@ -15,9 +14,8 @@ import { ChannelName, Notifiable } from "../types.mjs";
|
|
|
15
14
|
* App-owned (set in the `rateLimit` slot of `config/notifications.ts`). The
|
|
16
15
|
* package reserves the slot but ships no default implementation.
|
|
17
16
|
*/
|
|
18
|
-
interface RateLimiter {
|
|
17
|
+
export interface RateLimiter {
|
|
19
18
|
allow(notifiable: Notifiable, channel: ChannelName, type: string): Promise<boolean> | boolean;
|
|
20
19
|
}
|
|
21
20
|
//#endregion
|
|
22
|
-
export { RateLimiter };
|
|
23
21
|
//# sourceMappingURL=rate-limiter.contract.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limiter.contract.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/contracts/rate-limiter.contract.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"rate-limiter.contract.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/contracts/rate-limiter.contract.ts"],"mappings":";;;;;;;;;;;;;;;;iBAgBiB;EACf,MAAM,YAAY,YAAY,SAAS,aAAa,eAAe"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Channel } from "../contracts/channel.contract.mjs";
|
|
2
|
+
import "../contracts/index.mjs";
|
|
2
3
|
//#region ../../packages/notifications/src/dispatch/define-channel.d.ts
|
|
3
4
|
/**
|
|
4
5
|
* Identity helper that narrows the channel type to its payload. Use it when
|
|
@@ -31,7 +32,6 @@ import { Channel } from "../contracts/channel.contract.mjs";
|
|
|
31
32
|
* interface NotificationChannels { discord: DiscordPayload }
|
|
32
33
|
* }
|
|
33
34
|
*/
|
|
34
|
-
declare function defineChannel<P>(channel: Channel<P>): Channel<P>;
|
|
35
|
+
export declare function defineChannel<P>(channel: Channel<P>): Channel<P>;
|
|
35
36
|
//#endregion
|
|
36
|
-
export { defineChannel };
|
|
37
37
|
//# sourceMappingURL=define-channel.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-channel.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/dispatch/define-channel.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"define-channel.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/dispatch/define-channel.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAiCgB,cAAc,GAAG,SAAS,QAAQ,KAAK,QAAQ"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ChannelName, Notifiable, NotificationChannels, RenderContext, SendOptions } from "../types.mjs";
|
|
2
|
-
|
|
3
2
|
//#region ../../packages/notifications/src/dispatch/define-notification.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Per-channel renderer return type. The `database` renderer may OMIT `type`
|
|
@@ -7,16 +6,16 @@ import { ChannelName, Notifiable, NotificationChannels, RenderContext, SendOptio
|
|
|
7
6
|
*/
|
|
8
7
|
type RendererReturn<C extends ChannelName> = C extends "database" ? Omit<NotificationChannels["database"], "type"> : NotificationChannels[C];
|
|
9
8
|
type Renderer<Data, C extends ChannelName> = (data: Data, to: Notifiable, ctx: RenderContext) => RendererReturn<C>;
|
|
10
|
-
type NotificationDef<Data> = {
|
|
9
|
+
export type NotificationDef<Data> = {
|
|
11
10
|
type: string;
|
|
12
11
|
via: ChannelName[] | ((data: Data, to: Notifiable) => ChannelName[]);
|
|
13
|
-
} & { [C in ChannelName]?: Renderer<Data, C
|
|
14
|
-
interface DefinedNotification<Data> {
|
|
12
|
+
} & { [C in ChannelName]?: Renderer<Data, C>; };
|
|
13
|
+
export interface DefinedNotification<Data> {
|
|
15
14
|
send(to: Notifiable | Notifiable[], data: Data, options?: SendOptions): Promise<void>;
|
|
16
15
|
queue(to: Notifiable | Notifiable[], data: Data, options?: SendOptions): Promise<void>;
|
|
17
16
|
only(...channels: ChannelName[]): DefinedNotification<Data>;
|
|
18
17
|
}
|
|
19
|
-
declare function defineNotification<Data>(def: NotificationDef<Data>): DefinedNotification<Data>;
|
|
18
|
+
export declare function defineNotification<Data>(def: NotificationDef<Data>): DefinedNotification<Data>;
|
|
20
19
|
//#endregion
|
|
21
|
-
export {
|
|
20
|
+
export {};
|
|
22
21
|
//# sourceMappingURL=define-notification.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define-notification.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/dispatch/define-notification.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"define-notification.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/dispatch/define-notification.ts"],"mappings":";;;;;;KAiDK,eAAe,UAAU,eAAe,uBACzC,KAAK,4CACL,qBAAqB;KAEpB,SAAS,MAAM,UAAU,gBAC5B,MAAM,MACN,IAAI,YACJ,KAAK,kBACF,eAAe;YAER,gBAAgB;EAC1B;EACA,KAAK,kBAAkB,MAAM,MAAM,IAAI,eAAe;OAErD,KAAK,eAAe,SAAS,MAAM;iBAGrB,oBAAoB;EACnC,KAAK,IAAI,aAAa,cAAc,MAAM,MAAM,UAAU,cAAc;EACxE,MAAM,IAAI,aAAa,cAAc,MAAM,MAAM,UAAU,cAAc;EACzE,QAAQ,UAAU,gBAAgB,oBAAoB;;wBAYxC,mBAAmB,MAAM,KAAK,gBAAgB,QAAQ,oBAAoB"}
|
package/esm/dispatch/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defineChannel } from "./define-channel.mjs";
|
|
2
2
|
import { DefinedNotification, NotificationDef, defineNotification } from "./define-notification.mjs";
|
|
3
3
|
import { Notify, notify } from "./notify.mjs";
|
|
4
|
-
import { notifications } from "./notifications-event-bus.mjs";
|
|
4
|
+
import { notifications } from "./notifications-event-bus.mjs";
|
|
5
|
+
export { DefinedNotification, NotificationDef, Notify, defineChannel, defineNotification, notifications, notify };
|
package/esm/dispatch/index.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { NotificationEvents } from "../types.mjs";
|
|
2
|
-
|
|
3
2
|
//#region ../../packages/notifications/src/dispatch/notifications-event-bus.d.ts
|
|
4
3
|
type EventName = keyof NotificationEvents;
|
|
5
4
|
type Handler<E extends EventName> = (data: NotificationEvents[E]) => void | Promise<void>;
|
|
@@ -9,10 +8,10 @@ type Handler<E extends EventName> = (data: NotificationEvents[E]) => void | Prom
|
|
|
9
8
|
* `on(event, handler)` returns an unsubscribe function. `off` exists for
|
|
10
9
|
* symmetry with libraries that hold handler references for later removal.
|
|
11
10
|
*/
|
|
12
|
-
declare const notifications: {
|
|
11
|
+
export declare const notifications: {
|
|
13
12
|
on<E extends EventName>(event: E, handler: Handler<E>): () => void;
|
|
14
13
|
off<E extends EventName>(event: E, handler: Handler<E>): void;
|
|
15
14
|
};
|
|
16
15
|
//#endregion
|
|
17
|
-
export {
|
|
16
|
+
export {};
|
|
18
17
|
//# sourceMappingURL=notifications-event-bus.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications-event-bus.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/dispatch/notifications-event-bus.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"notifications-event-bus.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/dispatch/notifications-event-bus.ts"],"mappings":";;KAkBK,kBAAkB;KAClB,QAAQ,UAAU,cAAc,MAAM,mBAAmB,cAAc;;;;;;;qBAe/D;EACX,GAAG,UAAU,WAAS,OAAS,GAAC,SAAW,QAAQ;EAMnD,IAAI,UAAU,WAAS,OAAS,GAAC,SAAW,QAAQ"}
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { ChannelName, Notifiable, NotificationChannels, SendOptions } from "../types.mjs";
|
|
2
|
-
|
|
3
2
|
//#region ../../packages/notifications/src/dispatch/notify.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Public shape of `notify`. The mapped portion gives `notify.<channel>` per
|
|
6
5
|
* registered channel; `channel(name)` is the runtime escape.
|
|
7
6
|
*/
|
|
8
|
-
type Notify = {
|
|
7
|
+
export type Notify = {
|
|
9
8
|
channel(name: string): {
|
|
10
9
|
send(to: Notifiable | string, payload: unknown, options?: SendOptions): Promise<void>;
|
|
11
10
|
};
|
|
12
|
-
} & { [C in ChannelName]: (to: Notifiable | string, payload: NotificationChannels[C], options?: SendOptions) => Promise<void
|
|
11
|
+
} & { [C in ChannelName]: (to: Notifiable | string, payload: NotificationChannels[C], options?: SendOptions) => Promise<void>; };
|
|
13
12
|
/**
|
|
14
13
|
* Build the `notify` proxy. `channel(name)` returns a `{ send }` object;
|
|
15
14
|
* any other property access returns a one-shot dispatcher for that channel.
|
|
16
15
|
*/
|
|
17
|
-
declare const notify: Notify;
|
|
16
|
+
export declare const notify: Notify;
|
|
18
17
|
//#endregion
|
|
19
|
-
export { Notify, notify };
|
|
20
18
|
//# sourceMappingURL=notify.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/dispatch/notify.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"notify.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/dispatch/notify.ts"],"mappings":";;;;;;YA8BY;EACV,QAAQ;IACN,KAAK,IAAI,qBAAqB,kBAAkB,UAAU,cAAc;;OAGzE,KAAK,eACJ,IAAI,qBACJ,SAAS,qBAAqB,IAC9B,UAAU,gBACP;;;;;qBAwEM,QAAQ"}
|
package/esm/errors.d.mts
CHANGED
|
@@ -7,16 +7,16 @@
|
|
|
7
7
|
* Each captures a clean V8 stack (drops the Error-constructor frame) to match
|
|
8
8
|
* the cascade convention.
|
|
9
9
|
*/
|
|
10
|
-
declare class NotificationsNotConfiguredError extends Error {
|
|
10
|
+
export declare class NotificationsNotConfiguredError extends Error {
|
|
11
11
|
constructor();
|
|
12
12
|
}
|
|
13
|
-
declare class ChannelNotFoundError extends Error {
|
|
13
|
+
export declare class ChannelNotFoundError extends Error {
|
|
14
14
|
constructor(channelName: string);
|
|
15
15
|
}
|
|
16
|
-
declare class NoQueueDispatcherError extends Error {
|
|
16
|
+
export declare class NoQueueDispatcherError extends Error {
|
|
17
17
|
constructor(channelName: string);
|
|
18
18
|
}
|
|
19
|
-
declare class MissingRendererError extends Error {
|
|
19
|
+
export declare class MissingRendererError extends Error {
|
|
20
20
|
constructor(notificationType: string, channelName: string);
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
@@ -24,9 +24,8 @@ declare class MissingRendererError extends Error {
|
|
|
24
24
|
* a recipient (e.g. a mail recipient with no email). Distinct from "the
|
|
25
25
|
* channel declares no resolver" — that case falls back to `{ id }`.
|
|
26
26
|
*/
|
|
27
|
-
declare class UnresolvableRouteError extends Error {
|
|
27
|
+
export declare class UnresolvableRouteError extends Error {
|
|
28
28
|
constructor(channelName: string, recipientId?: unknown);
|
|
29
29
|
}
|
|
30
30
|
//#endregion
|
|
31
|
-
export { ChannelNotFoundError, MissingRendererError, NoQueueDispatcherError, NotificationsNotConfiguredError, UnresolvableRouteError };
|
|
32
31
|
//# sourceMappingURL=errors.d.mts.map
|
package/esm/errors.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.mts","names":[],"sources":["../../../../../../../packages/notifications/src/errors.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"errors.d.mts","names":[],"sources":["../../../../../../../packages/notifications/src/errors.ts"],"mappings":";;;;;;;;;qBAiBa,wCAAwC;EACnD;;qBAUW,6BAA6B;EACxC,YAAmB;;qBAUR,+BAA+B;EAC1C,YAAmB;;qBAUR,6BAA6B;EACxC,YAAmB,0BAA0B;;;;;;;qBAelC,+BAA+B;EAC1C,YAAmB,qBAAqB"}
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
import { DatabasePayload, Id } from "../types.mjs";
|
|
2
2
|
import { NotificationContract } from "../contracts/notification.contract.mjs";
|
|
3
|
+
import "../contracts/index.mjs";
|
|
3
4
|
import { NotificationColumnMapHost } from "./column-map.mjs";
|
|
4
5
|
import { DatabaseNotification } from "./database-notification.mjs";
|
|
5
6
|
import { FilterRules, RepositoryManager } from "@warlock.js/core";
|
|
6
|
-
|
|
7
7
|
//#region ../../packages/notifications/src/in-app/base-notifications-repository.d.ts
|
|
8
8
|
/**
|
|
9
9
|
* Filter shape — logical keys the repo understands. `filterBy` maps each to a
|
|
10
10
|
* physical column (or a predicate) derived from the model's `columnMap`.
|
|
11
11
|
*/
|
|
12
|
-
type NotificationsFilter = {
|
|
12
|
+
export type NotificationsFilter = {
|
|
13
13
|
id?: Id;
|
|
14
|
-
type?: string;
|
|
14
|
+
type?: string;
|
|
15
|
+
/** Mode-agnostic unread filter — resolves to the model's read-state column. */
|
|
15
16
|
unread?: boolean;
|
|
16
17
|
recipientId?: Id;
|
|
17
18
|
idempotencyKey?: string;
|
|
18
19
|
};
|
|
19
20
|
/** Class form of a `DatabaseNotification` subclass — what `configure()` accepts. */
|
|
20
|
-
type NotificationModelClass = (new (...args: any[]) => DatabaseNotification) & NotificationColumnMapHost;
|
|
21
|
-
declare class BaseNotificationsRepository<TModel extends NotificationContract = NotificationContract> extends RepositoryManager<TModel, NotificationsFilter> {
|
|
21
|
+
export type NotificationModelClass = (new (...args: any[]) => DatabaseNotification) & NotificationColumnMapHost;
|
|
22
|
+
export declare class BaseNotificationsRepository<TModel extends NotificationContract = NotificationContract> extends RepositoryManager<TModel, NotificationsFilter> {
|
|
22
23
|
/** Resolved physical columns for the bound model — the single source. */
|
|
23
24
|
private readonly columns;
|
|
24
25
|
filterBy: FilterRules;
|
|
@@ -92,5 +93,4 @@ declare class BaseNotificationsRepository<TModel extends NotificationContract =
|
|
|
92
93
|
private firstByIdempotencyKey;
|
|
93
94
|
}
|
|
94
95
|
//#endregion
|
|
95
|
-
export { BaseNotificationsRepository, NotificationModelClass, NotificationsFilter };
|
|
96
96
|
//# sourceMappingURL=base-notifications-repository.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-notifications-repository.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/in-app/base-notifications-repository.ts"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"base-notifications-repository.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/in-app/base-notifications-repository.ts"],"mappings":";;;;;;;;;;;YA2CY;EACV,KAAK;EACL;;EAEA;EACA,cAAc;EACd;;;YAIU,kCAAkC,gBAAgB,wBAC5D;qBAEW,4BACX,eAAe,uBAAuB,8BAC9B,kBAAkB,QAAQ;;mBAEjB;EAEV,UAAU;EAEjB,YAAmB,QAAQ;;MAYhB;;;;;;UASH;;;;;;;;YA2CE,MAAM,KAAK,0BAA0B;;;;;;;;;;;;UAwBvC;;;;;;;;;;;;EAoCK,UAAU,aAAa,IAAI,OAAO,iBAAiB,WAAW,KAAK,QAAQ;;;;;;EAwCjF,cACL,cAAc,MACd,OAAO,iBACP,WAAW,KACV,QAAQ;;;;;;;EAYJ,SAAS,aAAa,IAAI,KAAK,KAAK;;;;;EAwBpC,WAAW,aAAa,IAAI,KAAK,KAAK;;EAmBtC,QAAQ,aAAa,IAAI,IAAI,KAAK,QAAQ;;;;;EAQ1C,UAAU,aAAa,IAAI,KAAK,KAAK;;UAKpC"}
|
|
@@ -98,7 +98,7 @@ var BaseNotificationsRepository = class extends RepositoryManager {
|
|
|
98
98
|
*/
|
|
99
99
|
stripServerOwnedKeys(input) {
|
|
100
100
|
const { recipient, tenant, readAt, isRead } = this.columns;
|
|
101
|
-
const serverOwned = new Set([
|
|
101
|
+
const serverOwned = /* @__PURE__ */ new Set([
|
|
102
102
|
"id",
|
|
103
103
|
"recipientId",
|
|
104
104
|
"tenant",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base-notifications-repository.mjs","names":[],"sources":["../../../../../../../../packages/notifications/src/in-app/base-notifications-repository.ts"],"sourcesContent":["/**\n * Shipped behavior repository for the in-app store.\n *\n * Concrete (NOT abstract) so `inApp.configure({ model })` can\n * `new BaseNotificationsRepository(model)` without subclassing. The dev only\n * extends this when they need extra query methods.\n *\n * ## The single source of truth: the model's `columnMap`\n *\n * The model declares its physical columns ONCE via `static columnMap`. The\n * constructor resolves that map and derives BOTH sides from it:\n *\n * - the READ path — `filterBy` maps logical keys (`recipientId`, `unread`,\n * `type`, …) onto the model's columns; `RepositoryManager` applies it.\n * - the WRITE / UPDATE / DELETE path — `createFor` / `markRead` / … translate\n * logical keys through the same `filterBy` via `toRow`.\n *\n * Because both come from one `columnMap`, reads and writes can never target\n * different columns. `unread` is mode-agnostic: it filters `is_read = false`\n * when the model has that flag, otherwise `read_at IS NULL`.\n *\n * @example default (SQL snake_case — no subclass needed)\n * inApp.configure({ model: Notification })\n *\n * @example custom columns — declare them on the model, not here\n * class Notification extends DatabaseNotification {\n * public static columnMap = { recipient: \"audience_id\", isRead: \"seen\" };\n * }\n */\nimport { type FilterRules, RepositoryManager } from \"@warlock.js/core\";\nimport type { NotificationContract } from \"../contracts\";\nimport type { DatabasePayload, Id } from \"../types\";\nimport {\n type NotificationColumnMapHost,\n type ResolvedNotificationColumnMap,\n resolveColumnMap,\n} from \"./column-map\";\nimport type { DatabaseNotification } from \"./database-notification\";\n\n/**\n * Filter shape — logical keys the repo understands. `filterBy` maps each to a\n * physical column (or a predicate) derived from the model's `columnMap`.\n */\nexport type NotificationsFilter = {\n id?: Id;\n type?: string;\n /** Mode-agnostic unread filter — resolves to the model's read-state column. */\n unread?: boolean;\n recipientId?: Id;\n idempotencyKey?: string;\n};\n\n/** Class form of a `DatabaseNotification` subclass — what `configure()` accepts. */\nexport type NotificationModelClass = (new (...args: any[]) => DatabaseNotification) &\n NotificationColumnMapHost;\n\nexport class BaseNotificationsRepository<\n TModel extends NotificationContract = NotificationContract,\n> extends RepositoryManager<TModel, NotificationsFilter> {\n /** Resolved physical columns for the bound model — the single source. */\n private readonly columns: ResolvedNotificationColumnMap;\n\n public filterBy: FilterRules;\n\n public constructor(model?: NotificationModelClass) {\n super();\n\n if (model) {\n this.source = model;\n }\n\n this.columns = resolveColumnMap(model?.columnMap);\n this.filterBy = this.buildFilterBy();\n }\n\n /** The tenant column for this model, or `undefined` for single-tenant. */\n public get tenantColumn(): string | undefined {\n return this.columns.tenant;\n }\n\n /**\n * Build `filterBy` from the resolved column map. `unread` is the\n * mode-agnostic read filter; `isRead` / `readAt` / `tenant` are exposed for\n * direct filtering only when the model declares those columns.\n */\n private buildFilterBy(): FilterRules {\n const { recipient, tenant, readAt, isRead } = this.columns;\n\n const rules: FilterRules = {\n id: \"=\",\n type: \"=\",\n recipientId: [\"=\", recipient],\n idempotencyKey: [\"=\", \"idempotency_key\"],\n unread: (value, query) => {\n if (value !== true && value !== \"true\") {\n return;\n }\n\n if (isRead) {\n query.where(isRead, false);\n } else if (readAt) {\n query.whereNull(readAt);\n }\n },\n };\n\n if (isRead) {\n rules.isRead = [\"=\", isRead];\n }\n\n if (readAt) {\n rules.readAt = [\"=\", readAt];\n }\n\n if (tenant) {\n rules.tenant = [\"=\", tenant];\n }\n\n return rules;\n }\n\n /**\n * Translate an object keyed by LOGICAL names into one keyed by PHYSICAL\n * columns, using `filterBy` as the lookup. Keys with no `[op, column]` tuple\n * (e.g. `title`, `body`, `payload`, `type`, `id`) pass through unchanged —\n * they're already physical. Used for every write / update / delete payload +\n * filter (the paths `RepositoryManager` does NOT map).\n */\n protected toRow(obj: Record<string, unknown>): Record<string, unknown> {\n const rules = this.filterBy as Record<string, unknown>;\n const row: Record<string, unknown> = {};\n\n for (const [logical, value] of Object.entries(obj)) {\n const rule = rules[logical];\n const column = Array.isArray(rule) ? (rule[1] as string) : logical;\n row[column] = value;\n }\n\n return row;\n }\n\n /**\n * Runtime backstop for the compile-time `DatabasePayload` `Omit`: untyped\n * callers (`notify.channel(name).send`, payloads assembled from request\n * JSON) can smuggle server-owned keys past the type system, and spreading\n * them into the row would let a payload redirect the notification into\n * another recipient's inbox (recipient spoofing), cross tenants, pre-set\n * read-state, or clobber the primary key. Drops BOTH the logical names and\n * the model's resolved physical columns — `toRow` passes unmapped keys\n * through verbatim, so a payload carrying `user_id` would otherwise reach\n * the recipient column directly.\n */\n private stripServerOwnedKeys(input: DatabasePayload): Record<string, unknown> {\n const { recipient, tenant, readAt, isRead } = this.columns;\n const serverOwned = new Set<string | undefined>([\n \"id\",\n \"recipientId\",\n \"tenant\",\n \"readAt\",\n \"isRead\",\n recipient,\n tenant,\n readAt,\n isRead,\n ]);\n\n const safe: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(input)) {\n if (!serverOwned.has(key)) {\n safe[key] = value;\n }\n }\n\n return safe;\n }\n\n /**\n * Create one row for the recipient. New rows start unread; the tenant column\n * (when the model declares one) is written from `tenantId`, which the\n * database channel reads off the recipient. `recipientId` and the other\n * server-owned keys always come from the trusted arguments — matching keys\n * in `input` are stripped, never merged.\n *\n * Idempotency: when `input.idempotencyKey` is set, find-or-create — return\n * the existing row instead of inserting a duplicate. A unique index on the\n * key is the backstop for the rare insert race (we re-fetch on conflict).\n */\n public async createFor(recipientId: Id, input: DatabasePayload, tenantId?: Id): Promise<TModel> {\n const { idempotencyKey } = input;\n\n if (idempotencyKey) {\n const existing = await this.firstByIdempotencyKey(recipientId, idempotencyKey);\n if (existing) {\n return existing;\n }\n }\n\n const row: Record<string, unknown> = { ...this.stripServerOwnedKeys(input), recipientId };\n\n if (this.columns.isRead) {\n row.isRead = false;\n }\n\n if (this.columns.tenant && tenantId !== undefined) {\n row.tenant = tenantId;\n }\n\n try {\n return await this.create(this.toRow(row));\n } catch (error) {\n // Lost the insert race to a concurrent send with the same key → re-fetch.\n if (idempotencyKey) {\n const existing = await this.firstByIdempotencyKey(recipientId, idempotencyKey);\n if (existing) {\n return existing;\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Bulk-create one row per recipient sharing the same input + tenant. Reserved\n * for the Phase-2 `Channel.sendMany` fan-out hook; not on the per-recipient\n * send path yet.\n */\n public createManyFor(\n recipientIds: Id[],\n input: DatabasePayload,\n tenantId?: Id,\n ): Promise<TModel[]> {\n return Promise.all(\n recipientIds.map((recipientId) => this.createFor(recipientId, input, tenantId)),\n );\n }\n\n /**\n * Mark rows read — recipient-scoped. `id` omitted → all unread rows for the\n * recipient; `id` given → that one row, still scoped to the recipient. Scoped\n * to unread so a re-mark never overwrites an earlier `read_at` timestamp.\n * Sets whichever read-state column(s) the model declares.\n */\n public markRead(recipientId: Id, id?: Id): Promise<number> {\n const { isRead, readAt } = this.columns;\n const unreadScope = isRead ? { isRead: false } : { readAt: null };\n\n const data: Record<string, unknown> = {};\n\n if (isRead) {\n data.isRead = true;\n }\n\n if (readAt) {\n data.readAt = new Date();\n }\n\n return this.updateMany(\n this.toRow({ recipientId, ...unreadScope, ...(id !== undefined ? { id } : {}) }),\n this.toRow(data),\n );\n }\n\n /**\n * Inverse of `markRead`, same recipient-scoping. No unread scope needed —\n * clearing the read-state of an already-unread row is a no-op.\n */\n public markUnread(recipientId: Id, id?: Id): Promise<number> {\n const { isRead, readAt } = this.columns;\n const data: Record<string, unknown> = {};\n\n if (isRead) {\n data.isRead = false;\n }\n\n if (readAt) {\n data.readAt = null;\n }\n\n return this.updateMany(\n this.toRow({ recipientId, ...(id !== undefined ? { id } : {}) }),\n this.toRow(data),\n );\n }\n\n /** Find one row for a recipient (read path — `filterBy` maps the keys). */\n public findFor(recipientId: Id, id: Id): Promise<TModel | null> {\n return this.first({ recipientId, id } as NotificationsFilter);\n }\n\n /**\n * Delete rows — recipient-scoped. `id` omitted → clear all for the\n * recipient; `id` given → that one row.\n */\n public deleteFor(recipientId: Id, id?: Id): Promise<number> {\n return this.deleteMany(this.toRow({ recipientId, ...(id !== undefined ? { id } : {}) }));\n }\n\n /** Read path — `filterBy` maps `recipientId`/`idempotencyKey` to columns. */\n private firstByIdempotencyKey(recipientId: Id, idempotencyKey: string): Promise<TModel | null> {\n return this.first({ recipientId, idempotencyKey } as NotificationsFilter);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base-notifications-repository.mjs","names":[],"sources":["../../../../../../../../packages/notifications/src/in-app/base-notifications-repository.ts"],"sourcesContent":["/**\n * Shipped behavior repository for the in-app store.\n *\n * Concrete (NOT abstract) so `inApp.configure({ model })` can\n * `new BaseNotificationsRepository(model)` without subclassing. The dev only\n * extends this when they need extra query methods.\n *\n * ## The single source of truth: the model's `columnMap`\n *\n * The model declares its physical columns ONCE via `static columnMap`. The\n * constructor resolves that map and derives BOTH sides from it:\n *\n * - the READ path — `filterBy` maps logical keys (`recipientId`, `unread`,\n * `type`, …) onto the model's columns; `RepositoryManager` applies it.\n * - the WRITE / UPDATE / DELETE path — `createFor` / `markRead` / … translate\n * logical keys through the same `filterBy` via `toRow`.\n *\n * Because both come from one `columnMap`, reads and writes can never target\n * different columns. `unread` is mode-agnostic: it filters `is_read = false`\n * when the model has that flag, otherwise `read_at IS NULL`.\n *\n * @example default (SQL snake_case — no subclass needed)\n * inApp.configure({ model: Notification })\n *\n * @example custom columns — declare them on the model, not here\n * class Notification extends DatabaseNotification {\n * public static columnMap = { recipient: \"audience_id\", isRead: \"seen\" };\n * }\n */\nimport { type FilterRules, RepositoryManager } from \"@warlock.js/core\";\nimport type { NotificationContract } from \"../contracts\";\nimport type { DatabasePayload, Id } from \"../types\";\nimport {\n type NotificationColumnMapHost,\n type ResolvedNotificationColumnMap,\n resolveColumnMap,\n} from \"./column-map\";\nimport type { DatabaseNotification } from \"./database-notification\";\n\n/**\n * Filter shape — logical keys the repo understands. `filterBy` maps each to a\n * physical column (or a predicate) derived from the model's `columnMap`.\n */\nexport type NotificationsFilter = {\n id?: Id;\n type?: string;\n /** Mode-agnostic unread filter — resolves to the model's read-state column. */\n unread?: boolean;\n recipientId?: Id;\n idempotencyKey?: string;\n};\n\n/** Class form of a `DatabaseNotification` subclass — what `configure()` accepts. */\nexport type NotificationModelClass = (new (...args: any[]) => DatabaseNotification) &\n NotificationColumnMapHost;\n\nexport class BaseNotificationsRepository<\n TModel extends NotificationContract = NotificationContract,\n> extends RepositoryManager<TModel, NotificationsFilter> {\n /** Resolved physical columns for the bound model — the single source. */\n private readonly columns: ResolvedNotificationColumnMap;\n\n public filterBy: FilterRules;\n\n public constructor(model?: NotificationModelClass) {\n super();\n\n if (model) {\n this.source = model;\n }\n\n this.columns = resolveColumnMap(model?.columnMap);\n this.filterBy = this.buildFilterBy();\n }\n\n /** The tenant column for this model, or `undefined` for single-tenant. */\n public get tenantColumn(): string | undefined {\n return this.columns.tenant;\n }\n\n /**\n * Build `filterBy` from the resolved column map. `unread` is the\n * mode-agnostic read filter; `isRead` / `readAt` / `tenant` are exposed for\n * direct filtering only when the model declares those columns.\n */\n private buildFilterBy(): FilterRules {\n const { recipient, tenant, readAt, isRead } = this.columns;\n\n const rules: FilterRules = {\n id: \"=\",\n type: \"=\",\n recipientId: [\"=\", recipient],\n idempotencyKey: [\"=\", \"idempotency_key\"],\n unread: (value, query) => {\n if (value !== true && value !== \"true\") {\n return;\n }\n\n if (isRead) {\n query.where(isRead, false);\n } else if (readAt) {\n query.whereNull(readAt);\n }\n },\n };\n\n if (isRead) {\n rules.isRead = [\"=\", isRead];\n }\n\n if (readAt) {\n rules.readAt = [\"=\", readAt];\n }\n\n if (tenant) {\n rules.tenant = [\"=\", tenant];\n }\n\n return rules;\n }\n\n /**\n * Translate an object keyed by LOGICAL names into one keyed by PHYSICAL\n * columns, using `filterBy` as the lookup. Keys with no `[op, column]` tuple\n * (e.g. `title`, `body`, `payload`, `type`, `id`) pass through unchanged —\n * they're already physical. Used for every write / update / delete payload +\n * filter (the paths `RepositoryManager` does NOT map).\n */\n protected toRow(obj: Record<string, unknown>): Record<string, unknown> {\n const rules = this.filterBy as Record<string, unknown>;\n const row: Record<string, unknown> = {};\n\n for (const [logical, value] of Object.entries(obj)) {\n const rule = rules[logical];\n const column = Array.isArray(rule) ? (rule[1] as string) : logical;\n row[column] = value;\n }\n\n return row;\n }\n\n /**\n * Runtime backstop for the compile-time `DatabasePayload` `Omit`: untyped\n * callers (`notify.channel(name).send`, payloads assembled from request\n * JSON) can smuggle server-owned keys past the type system, and spreading\n * them into the row would let a payload redirect the notification into\n * another recipient's inbox (recipient spoofing), cross tenants, pre-set\n * read-state, or clobber the primary key. Drops BOTH the logical names and\n * the model's resolved physical columns — `toRow` passes unmapped keys\n * through verbatim, so a payload carrying `user_id` would otherwise reach\n * the recipient column directly.\n */\n private stripServerOwnedKeys(input: DatabasePayload): Record<string, unknown> {\n const { recipient, tenant, readAt, isRead } = this.columns;\n const serverOwned = new Set<string | undefined>([\n \"id\",\n \"recipientId\",\n \"tenant\",\n \"readAt\",\n \"isRead\",\n recipient,\n tenant,\n readAt,\n isRead,\n ]);\n\n const safe: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(input)) {\n if (!serverOwned.has(key)) {\n safe[key] = value;\n }\n }\n\n return safe;\n }\n\n /**\n * Create one row for the recipient. New rows start unread; the tenant column\n * (when the model declares one) is written from `tenantId`, which the\n * database channel reads off the recipient. `recipientId` and the other\n * server-owned keys always come from the trusted arguments — matching keys\n * in `input` are stripped, never merged.\n *\n * Idempotency: when `input.idempotencyKey` is set, find-or-create — return\n * the existing row instead of inserting a duplicate. A unique index on the\n * key is the backstop for the rare insert race (we re-fetch on conflict).\n */\n public async createFor(recipientId: Id, input: DatabasePayload, tenantId?: Id): Promise<TModel> {\n const { idempotencyKey } = input;\n\n if (idempotencyKey) {\n const existing = await this.firstByIdempotencyKey(recipientId, idempotencyKey);\n if (existing) {\n return existing;\n }\n }\n\n const row: Record<string, unknown> = { ...this.stripServerOwnedKeys(input), recipientId };\n\n if (this.columns.isRead) {\n row.isRead = false;\n }\n\n if (this.columns.tenant && tenantId !== undefined) {\n row.tenant = tenantId;\n }\n\n try {\n return await this.create(this.toRow(row));\n } catch (error) {\n // Lost the insert race to a concurrent send with the same key → re-fetch.\n if (idempotencyKey) {\n const existing = await this.firstByIdempotencyKey(recipientId, idempotencyKey);\n if (existing) {\n return existing;\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Bulk-create one row per recipient sharing the same input + tenant. Reserved\n * for the Phase-2 `Channel.sendMany` fan-out hook; not on the per-recipient\n * send path yet.\n */\n public createManyFor(\n recipientIds: Id[],\n input: DatabasePayload,\n tenantId?: Id,\n ): Promise<TModel[]> {\n return Promise.all(\n recipientIds.map((recipientId) => this.createFor(recipientId, input, tenantId)),\n );\n }\n\n /**\n * Mark rows read — recipient-scoped. `id` omitted → all unread rows for the\n * recipient; `id` given → that one row, still scoped to the recipient. Scoped\n * to unread so a re-mark never overwrites an earlier `read_at` timestamp.\n * Sets whichever read-state column(s) the model declares.\n */\n public markRead(recipientId: Id, id?: Id): Promise<number> {\n const { isRead, readAt } = this.columns;\n const unreadScope = isRead ? { isRead: false } : { readAt: null };\n\n const data: Record<string, unknown> = {};\n\n if (isRead) {\n data.isRead = true;\n }\n\n if (readAt) {\n data.readAt = new Date();\n }\n\n return this.updateMany(\n this.toRow({ recipientId, ...unreadScope, ...(id !== undefined ? { id } : {}) }),\n this.toRow(data),\n );\n }\n\n /**\n * Inverse of `markRead`, same recipient-scoping. No unread scope needed —\n * clearing the read-state of an already-unread row is a no-op.\n */\n public markUnread(recipientId: Id, id?: Id): Promise<number> {\n const { isRead, readAt } = this.columns;\n const data: Record<string, unknown> = {};\n\n if (isRead) {\n data.isRead = false;\n }\n\n if (readAt) {\n data.readAt = null;\n }\n\n return this.updateMany(\n this.toRow({ recipientId, ...(id !== undefined ? { id } : {}) }),\n this.toRow(data),\n );\n }\n\n /** Find one row for a recipient (read path — `filterBy` maps the keys). */\n public findFor(recipientId: Id, id: Id): Promise<TModel | null> {\n return this.first({ recipientId, id } as NotificationsFilter);\n }\n\n /**\n * Delete rows — recipient-scoped. `id` omitted → clear all for the\n * recipient; `id` given → that one row.\n */\n public deleteFor(recipientId: Id, id?: Id): Promise<number> {\n return this.deleteMany(this.toRow({ recipientId, ...(id !== undefined ? { id } : {}) }));\n }\n\n /** Read path — `filterBy` maps `recipientId`/`idempotencyKey` to columns. */\n private firstByIdempotencyKey(recipientId: Id, idempotencyKey: string): Promise<TModel | null> {\n return this.first({ recipientId, idempotencyKey } as NotificationsFilter);\n }\n}\n"],"mappings":"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"}
|
|
@@ -32,10 +32,14 @@
|
|
|
32
32
|
* Every key is optional; `resolveColumnMap` fills the defaults. Values are the
|
|
33
33
|
* app's real column names (rename-friendly: `readAt: "seen_at"`).
|
|
34
34
|
*/
|
|
35
|
-
type NotificationColumnMap = {
|
|
36
|
-
/** Recipient FK column. Default: `"user_id"`. */
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
export type NotificationColumnMap = {
|
|
36
|
+
/** Recipient FK column. Default: `"user_id"`. */
|
|
37
|
+
recipient?: string;
|
|
38
|
+
/** Multi-tenant scope column, written from the recipient. Omit → single-tenant. */
|
|
39
|
+
tenant?: string;
|
|
40
|
+
/** Read-timestamp column. Present → read-state records "when". */
|
|
41
|
+
readAt?: string;
|
|
42
|
+
/** Read-flag column (indexed → fast unread filter). Present → read-state is a boolean. */
|
|
39
43
|
isRead?: string;
|
|
40
44
|
};
|
|
41
45
|
/**
|
|
@@ -43,14 +47,14 @@ type NotificationColumnMap = {
|
|
|
43
47
|
* set, and at least one of `readAt` / `isRead` is always present (the resolver
|
|
44
48
|
* falls back to `readAt`), so consumers never face a "no read-state" map.
|
|
45
49
|
*/
|
|
46
|
-
type ResolvedNotificationColumnMap = {
|
|
50
|
+
export type ResolvedNotificationColumnMap = {
|
|
47
51
|
recipient: string;
|
|
48
52
|
tenant?: string;
|
|
49
53
|
readAt?: string;
|
|
50
54
|
isRead?: string;
|
|
51
55
|
};
|
|
52
56
|
/** A model class that may carry the `columnMap` static. */
|
|
53
|
-
type NotificationColumnMapHost = {
|
|
57
|
+
export type NotificationColumnMapHost = {
|
|
54
58
|
columnMap?: NotificationColumnMap;
|
|
55
59
|
};
|
|
56
60
|
/**
|
|
@@ -59,7 +63,6 @@ type NotificationColumnMapHost = {
|
|
|
59
63
|
* declares no read-state column. The fallback guarantees the result always
|
|
60
64
|
* has a usable read-state representation, so no boot-time validation is needed.
|
|
61
65
|
*/
|
|
62
|
-
declare function resolveColumnMap(map: NotificationColumnMap | undefined): ResolvedNotificationColumnMap;
|
|
66
|
+
export declare function resolveColumnMap(map: NotificationColumnMap | undefined): ResolvedNotificationColumnMap;
|
|
63
67
|
//#endregion
|
|
64
|
-
export { NotificationColumnMap, NotificationColumnMapHost, ResolvedNotificationColumnMap, resolveColumnMap };
|
|
65
68
|
//# sourceMappingURL=column-map.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column-map.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/in-app/column-map.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"column-map.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/in-app/column-map.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAkCY;;EAEV;;EAEA;;EAEA;;EAEA;;;;;;;YAQU;EACV;EACA;EACA;EACA;;;YAIU;EACV,YAAY;;;;;;;;wBAYE,iBACd,KAAK,oCACJ"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Id } from "../types.mjs";
|
|
2
2
|
import { NotificationContract } from "../contracts/notification.contract.mjs";
|
|
3
|
+
import "../contracts/index.mjs";
|
|
3
4
|
import { NotificationColumnMap, ResolvedNotificationColumnMap } from "./column-map.mjs";
|
|
4
5
|
import { Model } from "@warlock.js/cascade";
|
|
5
|
-
|
|
6
6
|
//#region ../../packages/notifications/src/in-app/database-notification.d.ts
|
|
7
|
-
declare abstract class DatabaseNotification extends Model implements NotificationContract {
|
|
7
|
+
export declare abstract class DatabaseNotification extends Model implements NotificationContract {
|
|
8
8
|
/**
|
|
9
9
|
* Physical column bindings for THIS model's table. Override in the subclass;
|
|
10
10
|
* the empty default resolves to `{ recipient: "user_id", readAt: "read_at" }`.
|
|
@@ -26,5 +26,4 @@ declare abstract class DatabaseNotification extends Model implements Notificatio
|
|
|
26
26
|
markRead(): Promise<void>;
|
|
27
27
|
}
|
|
28
28
|
//#endregion
|
|
29
|
-
export { DatabaseNotification };
|
|
30
29
|
//# sourceMappingURL=database-notification.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database-notification.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/in-app/database-notification.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"database-notification.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/in-app/database-notification.ts"],"mappings":";;;;;;8BA6BsB,6BAA6B,iBAAiB;;;;;SAKpD,WAAW;;gBAGX,WAAW;MAId,eAAe;;MAKf,YAAY;MAKZ;MAIA;MAUA,UAAU;;;;;;EAUR,YAAY"}
|
package/esm/in-app/in-app.d.mts
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { DatabasePayload, Id, Notifiable } from "../types.mjs";
|
|
2
2
|
import { Channel } from "../contracts/channel.contract.mjs";
|
|
3
3
|
import { NotificationContract } from "../contracts/notification.contract.mjs";
|
|
4
|
+
import "../contracts/index.mjs";
|
|
4
5
|
import { BaseNotificationsRepository, NotificationModelClass, NotificationsFilter } from "./base-notifications-repository.mjs";
|
|
6
|
+
import "../index.mjs";
|
|
5
7
|
import { TypedRepositoryOptionsWithPages } from "@warlock.js/core";
|
|
6
|
-
|
|
7
8
|
//#region ../../packages/notifications/src/in-app/in-app.d.ts
|
|
8
9
|
/**
|
|
9
10
|
* List options for the read methods — the repository's paginated options
|
|
10
11
|
* (`page` / `limit` / `orderBy` / filter keys). `recipientId` is always forced
|
|
11
12
|
* from the recipient argument, so passing it here has no effect.
|
|
12
13
|
*/
|
|
13
|
-
type NotificationsListOptions = TypedRepositoryOptionsWithPages<NotificationsFilter>;
|
|
14
|
+
export type NotificationsListOptions = TypedRepositoryOptionsWithPages<NotificationsFilter>;
|
|
14
15
|
/**
|
|
15
16
|
* Configure options — discriminated so `model` and `repository` are mutually
|
|
16
17
|
* exclusive at the type level. Future knobs (cache / realtime / naming) slot
|
|
17
18
|
* in here without breaking the signature.
|
|
18
19
|
*/
|
|
19
|
-
type ConfigureOptions = {
|
|
20
|
+
export type ConfigureOptions = {
|
|
20
21
|
model: NotificationModelClass;
|
|
21
22
|
repository?: never;
|
|
22
23
|
} | {
|
|
@@ -50,7 +51,7 @@ declare class InApp {
|
|
|
50
51
|
dismiss(recipient: Notifiable | Id, id?: Id): Promise<number>;
|
|
51
52
|
}
|
|
52
53
|
/** Single in-app facade — bound at boot via `inApp.configure(...)`. */
|
|
53
|
-
declare const inApp: InApp;
|
|
54
|
+
export declare const inApp: InApp;
|
|
54
55
|
//#endregion
|
|
55
|
-
export {
|
|
56
|
+
export {};
|
|
56
57
|
//# sourceMappingURL=in-app.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"in-app.d.mts","names":[],"sources":["../../../../../../../../packages/notifications/src/in-app/in-app.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"in-app.d.mts","names":["_$__0.NotificationContract"],"sources":["../../../../../../../../packages/notifications/src/in-app/in-app.ts"],"mappings":";;;;;;;;;;;;;YA4CY,2BAA2B,gCAAgC;;;;;;YAO3D;EACN,OAAO;EAAwB;;EAC/B,YAAY;EAA6B;;cAKzC;UACI;;;;;EAMD,UAAU,SAAS,mBAAmB,QAAQ;cAQzC;;EAWL,KAAK,WAAW,aAAa,IAAI,UAAU,2BAAwB,mCAAA,iBAAxBA;;EAK3C,WAAW,WAAW,aAAa,IAAI,UAAU,2BAAwB,mCAAA,iBAAxBA;;;;;EAQjD,YAAY,WAAW,aAAa,KAAE;;EAKtC,KAAK,WAAW,aAAa,IAAI,IAAI,KAAE,QAAFA;;EAKrC,WAAW,WAAW,aAAa,IAAI,KAAK,KAAE;;EAK9C,aAAa,WAAW,aAAa,IAAI,KAAK,KAAE;;EAKhD,QAAQ,WAAW,aAAa,IAAI,KAAK,KAAE;;;qBAMvC,OAAK"}
|
package/esm/in-app/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { NotificationColumnMap, NotificationColumnMapHost, ResolvedNotificationColumnMap, resolveColumnMap } from "./column-map.mjs";
|
|
2
2
|
import { DatabaseNotification } from "./database-notification.mjs";
|
|
3
3
|
import { BaseNotificationsRepository, NotificationModelClass, NotificationsFilter } from "./base-notifications-repository.mjs";
|
|
4
|
-
import { ConfigureOptions, NotificationsListOptions, inApp } from "./in-app.mjs";
|
|
4
|
+
import { ConfigureOptions, NotificationsListOptions, inApp } from "./in-app.mjs";
|
|
5
|
+
export { BaseNotificationsRepository, ConfigureOptions, DatabaseNotification, NotificationColumnMap, NotificationColumnMapHost, NotificationModelClass, NotificationsFilter, NotificationsListOptions, ResolvedNotificationColumnMap, inApp, resolveColumnMap };
|
package/esm/in-app/index.mjs
CHANGED
|
@@ -3,4 +3,4 @@ import { BaseNotificationsRepository } from "./base-notifications-repository.mjs
|
|
|
3
3
|
import { DatabaseNotification } from "./database-notification.mjs";
|
|
4
4
|
import { inApp } from "./in-app.mjs";
|
|
5
5
|
|
|
6
|
-
export {
|
|
6
|
+
export { BaseNotificationsRepository, DatabaseNotification, inApp, resolveColumnMap };
|
package/esm/index.d.mts
CHANGED
|
@@ -4,25 +4,31 @@ import { NotificationContract } from "./contracts/notification.contract.mjs";
|
|
|
4
4
|
import { PreferenceProvider } from "./contracts/preference-provider.contract.mjs";
|
|
5
5
|
import { QueueDispatcher } from "./contracts/queue-dispatcher.contract.mjs";
|
|
6
6
|
import { RateLimiter } from "./contracts/rate-limiter.contract.mjs";
|
|
7
|
+
import "./contracts/index.mjs";
|
|
7
8
|
import { ChannelNotFoundError, MissingRendererError, NoQueueDispatcherError, NotificationsNotConfiguredError, UnresolvableRouteError } from "./errors.mjs";
|
|
8
9
|
import { ChannelMap, NotificationConfig, getNotificationConfig, resetNotificationConfig, setNotificationConfig } from "./config.mjs";
|
|
9
10
|
import { defineChannel } from "./dispatch/define-channel.mjs";
|
|
10
11
|
import { DefinedNotification, NotificationDef, defineNotification } from "./dispatch/define-notification.mjs";
|
|
11
12
|
import { Notify, notify } from "./dispatch/notify.mjs";
|
|
12
13
|
import { notifications } from "./dispatch/notifications-event-bus.mjs";
|
|
14
|
+
import "./dispatch/index.mjs";
|
|
13
15
|
import { NotificationColumnMap, NotificationColumnMapHost, ResolvedNotificationColumnMap, resolveColumnMap } from "./in-app/column-map.mjs";
|
|
14
16
|
import { DatabaseNotification } from "./in-app/database-notification.mjs";
|
|
15
17
|
import { BaseNotificationsRepository, NotificationModelClass, NotificationsFilter } from "./in-app/base-notifications-repository.mjs";
|
|
16
18
|
import { databaseChannel } from "./channels/database-channel.mjs";
|
|
17
19
|
import { MailChannelConfig, mailChannel } from "./channels/mail-channel.mjs";
|
|
20
|
+
import "./channels/index.mjs";
|
|
18
21
|
import { ConfigureOptions, NotificationsListOptions, inApp } from "./in-app/in-app.mjs";
|
|
22
|
+
import "./in-app/index.mjs";
|
|
19
23
|
import { NotificationColumnsOptions, NotificationIdType, notificationColumns } from "./migration/notification-columns.mjs";
|
|
24
|
+
import "./migration/index.mjs";
|
|
20
25
|
import { HeraldQueueOptions, heraldQueue } from "./queue/herald-queue.mjs";
|
|
21
26
|
import { WorkerOptions, startNotificationsWorker } from "./queue/notifications-worker.mjs";
|
|
22
27
|
import { DEFAULT_QUEUE_CHANNEL } from "./queue/load-herald.mjs";
|
|
23
28
|
import { BullmqQueueOptions, NOTIFICATION_JOB_NAME, bullmqQueue } from "./queue/bullmq-queue.mjs";
|
|
24
29
|
import { QueuePackageLoader, loadQueuePackage } from "./queue/load-queue.mjs";
|
|
25
30
|
import { QueuePackageNotInstalledError } from "./queue/queue-package-not-installed.error.mjs";
|
|
31
|
+
import "./queue/index.mjs";
|
|
26
32
|
export { BaseNotificationsRepository, BullmqQueueOptions, Channel, ChannelMap, ChannelName, ChannelNotFoundError, ConfigureOptions, DEFAULT_QUEUE_CHANNEL, DatabaseNotification, DatabasePayload, DefinedNotification, HeraldQueueOptions, Id, MailChannelConfig, MailPayload, MissingRendererError, NOTIFICATION_JOB_NAME, NoQueueDispatcherError, Notifiable, NotificationChannels, NotificationColumnMap, NotificationColumnMapHost, NotificationColumnsOptions, NotificationConfig, NotificationContract, NotificationDef, NotificationEvents, NotificationIdType, NotificationInput, NotificationModelClass, NotificationsFilter, NotificationsListOptions, NotificationsNotConfiguredError, Notify, PreferenceProvider, QueueDispatcher, type QueuePackageLoader, QueuePackageNotInstalledError, RateLimiter, RenderContext, ResolvedNotificationColumnMap, SendOptions, UnresolvableRouteError, WorkerOptions, bullmqQueue, databaseChannel, defineChannel, defineNotification, getNotificationConfig, heraldQueue, inApp, loadQueuePackage, mailChannel, notificationColumns, notifications, notify, resetNotificationConfig, resolveColumnMap, setNotificationConfig, startNotificationsWorker };
|
|
27
33
|
import "./dispatch/define-channel.mjs";
|
|
28
34
|
import "./types.mjs";
|