@facteurjs/adonisjs 1.0.0-beta.3 → 2.0.0-beta.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/README.md +25 -0
- package/dist/_virtual/rolldown_runtime.mjs +36 -0
- package/dist/adonisjs/configure.d.mts +6 -0
- package/dist/adonisjs/configure.mjs +44 -0
- package/dist/adonisjs/stubs/index.mjs +5 -0
- package/dist/adonisjs/stubs/stubs/config/notifications.stub +17 -0
- package/dist/adonisjs/stubs/stubs/index.ts +1 -0
- package/dist/adonisjs/stubs/stubs/make/notification.stub +9 -0
- package/dist/adonisjs/stubs/stubs/migrations/notifications.stub +36 -0
- package/dist/adonisjs/stubs/stubs/migrations/preferences.stub +32 -0
- package/dist/channels/aws-sns.d.mts +9 -0
- package/dist/channels/{aws-sns.js → aws-sns.mjs} +2 -0
- package/dist/channels/database.d.mts +9 -0
- package/dist/channels/{database.js → database.mjs} +2 -0
- package/dist/channels/discord.d.mts +9 -0
- package/dist/channels/{discord.js → discord.mjs} +2 -0
- package/dist/channels/{expo.js → expo.mjs} +2 -0
- package/dist/channels/fcm.d.mts +9 -0
- package/dist/channels/{fcm.js → fcm.mjs} +2 -0
- package/dist/channels/{mail.d.ts → mail.d.mts} +1 -1
- package/dist/channels/{mail.js → mail.mjs} +2 -1
- package/dist/channels/{slack.js → slack.mjs} +2 -0
- package/dist/channels/socketio.d.mts +9 -0
- package/dist/channels/{socketio.js → socketio.mjs} +2 -0
- package/dist/channels/transmit.d.mts +9 -0
- package/dist/channels/{transmit.js → transmit.mjs} +2 -0
- package/dist/channels/twilio.d.mts +9 -0
- package/dist/channels/{twilio.js → twilio.mjs} +2 -0
- package/dist/channels/{webhook.js → webhook.mjs} +2 -0
- package/dist/channels/webpush.d.mts +9 -0
- package/dist/channels/{webpush.js → webpush.mjs} +2 -0
- package/dist/{channels.d.ts → channels.d.mts} +11 -17
- package/dist/{channels.js → channels.mjs} +5 -8
- package/dist/core/src/database/{types.d.ts → types.d.mts} +2 -6
- package/dist/core/src/types/channel.d.mts +56 -0
- package/dist/core/src/types/events.d.mts +13 -0
- package/dist/core/src/types/{extend.d.ts → extend.d.mts} +1 -5
- package/dist/core/src/types/notifications.d.mts +40 -0
- package/dist/core/src/types/options.d.mts +141 -0
- package/dist/core/src/types/preferences.d.mts +28 -0
- package/dist/core/src/types/queue.d.mts +11 -0
- package/dist/{database/index.d.ts → database.d.mts} +1 -1
- package/dist/{database/index.js → database.mjs} +3 -4
- package/dist/{define_config.d.ts → define_config.d.mts} +4 -2
- package/dist/{providers/facteur_provider.d.ts → facteur_provider.d.mts} +1 -1
- package/dist/{providers/facteur_provider.js → facteur_provider.mjs} +1 -1
- package/dist/index.d.mts +6 -0
- package/dist/index.mjs +8 -0
- package/dist/{manager.d.ts → manager.d.mts} +8 -3
- package/dist/manager.mjs +32 -0
- package/dist/server/{adapter.js → adapter.mjs} +7 -6
- package/dist/services/{main.d.ts → main.d.mts} +2 -2
- package/dist/types.d.mts +30 -0
- package/dist/types.mjs +11 -0
- package/package.json +58 -47
- package/dist/_virtual/rolldown_runtime.js +0 -25
- package/dist/channels/aws-sns.d.ts +0 -12
- package/dist/channels/database.d.ts +0 -12
- package/dist/channels/discord.d.ts +0 -12
- package/dist/channels/fcm.d.ts +0 -12
- package/dist/channels/socketio.d.ts +0 -12
- package/dist/channels/transmit.d.ts +0 -12
- package/dist/channels/twilio.d.ts +0 -12
- package/dist/channels/webpush.d.ts +0 -12
- package/dist/index.d.ts +0 -5
- package/dist/index.js +0 -7
- package/dist/manager.js +0 -21
- package/dist/types.d.ts +0 -15
- package/dist/types.js +0 -11
- /package/dist/channels/{expo.d.ts → expo.d.mts} +0 -0
- /package/dist/channels/{slack.d.ts → slack.d.mts} +0 -0
- /package/dist/channels/{webhook.d.ts → webhook.d.mts} +0 -0
- /package/dist/{define_config.js → define_config.mjs} +0 -0
- /package/dist/services/{main.js → main.mjs} +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# @facteurjs/adonisjs
|
|
2
|
+
|
|
3
|
+
AdonisJS integration for Facteur - Send notifications via multiple channels in your AdonisJS application.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @facteurjs/adonisjs
|
|
9
|
+
node ace configure @facteurjs/adonisjs
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- Full integration with AdonisJS ecosystem
|
|
15
|
+
- Support for `@adonisjs/mail`, `@adonisjs/redis`, `@adonisjs/lucid`, `@adonisjs/transmit`
|
|
16
|
+
- Queueable notifications
|
|
17
|
+
- Database storage for notification history
|
|
18
|
+
|
|
19
|
+
## Documentation
|
|
20
|
+
|
|
21
|
+
Full documentation available at [facteur.julr.dev](https://facteur.julr.dev)
|
|
22
|
+
|
|
23
|
+
## License
|
|
24
|
+
|
|
25
|
+
MIT
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __exportAll = (all, symbols) => {
|
|
7
|
+
let target = {};
|
|
8
|
+
for (var name in all) {
|
|
9
|
+
__defProp(target, name, {
|
|
10
|
+
get: all[name],
|
|
11
|
+
enumerable: true
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
if (symbols) {
|
|
15
|
+
__defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
16
|
+
}
|
|
17
|
+
return target;
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
22
|
+
key = keys[i];
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
24
|
+
__defProp(to, key, {
|
|
25
|
+
get: ((k) => from[k]).bind(null, key),
|
|
26
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return to;
|
|
32
|
+
};
|
|
33
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { __exportAll, __reExport };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { stubsRoot } from "./stubs/index.mjs";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
5
|
+
|
|
6
|
+
//#region configure.ts
|
|
7
|
+
async function addSubpathImport(command) {
|
|
8
|
+
try {
|
|
9
|
+
const pkgJson = await readFile(join(fileURLToPath(command.app.appRoot), "package.json"), "utf-8");
|
|
10
|
+
const pkg = JSON.parse(pkgJson);
|
|
11
|
+
pkg.imports ??= {};
|
|
12
|
+
pkg.imports["#notifications/*"] = "./app/notifications/*.js";
|
|
13
|
+
await writeFile(join(fileURLToPath(command.app.appRoot), "package.json"), JSON.stringify(pkg, null, 2) + "\n");
|
|
14
|
+
} catch (error) {
|
|
15
|
+
command.logger.error("Failed to add subpath import in your package.json :" + error.message);
|
|
16
|
+
command.logger.error("Please add the following to your package.json:\n");
|
|
17
|
+
command.logger.error(`\n"imports": {\n "#notifications/*": "./app/notifications/*.js"\n},\n`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function configure(command) {
|
|
21
|
+
const codemods = await command.createCodemods();
|
|
22
|
+
await codemods.makeUsingStub(stubsRoot, "config/notifications.stub", {});
|
|
23
|
+
await codemods.updateRcFile((rcFile) => {
|
|
24
|
+
rcFile.addProvider("@facteurjs/adonisjs/facteur_provider");
|
|
25
|
+
});
|
|
26
|
+
await addSubpathImport(command);
|
|
27
|
+
await codemods.makeUsingStub(stubsRoot, "migration.stub", {
|
|
28
|
+
entity: command.app.generators.createEntity("notifications"),
|
|
29
|
+
migration: {
|
|
30
|
+
folder: "database/migrations",
|
|
31
|
+
fileName: `${(/* @__PURE__ */ new Date()).getTime()}_create_notifications_table.ts`
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
await codemods.makeUsingStub(stubsRoot, "migrations/preferences.stub", {
|
|
35
|
+
entity: command.app.generators.createEntity("notifications_preferences"),
|
|
36
|
+
migration: {
|
|
37
|
+
folder: "database/migrations",
|
|
38
|
+
fileName: `${(/* @__PURE__ */ new Date()).getTime()}_create_notifications_preferences_table.ts`
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { configure };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { databases } from '@facteurjs/adonisjs/database'
|
|
2
|
+
import { defineConfig, channels } from '@facteurjs/adonisjs'
|
|
3
|
+
import type { InferChannels } from '@facteurjs/adonisjs/types'
|
|
4
|
+
|
|
5
|
+
const config = defineConfig({
|
|
6
|
+
databaseAdapter: databases.lucid({ connectionName: '' }),
|
|
7
|
+
channels: {
|
|
8
|
+
mail: channels.mail(),
|
|
9
|
+
database: channels.database({ connectionName: '' }),
|
|
10
|
+
},
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
export default config
|
|
14
|
+
|
|
15
|
+
declare module '@facteurjs/adonisjs/types' {
|
|
16
|
+
interface NotificationChannels extends InferChannels<typeof config> {}
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const stubsRoot = import.meta.dirname
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({
|
|
3
|
+
to: app.makePath(app.rcFile.directories['notifications'], notificationFileName)
|
|
4
|
+
})
|
|
5
|
+
}}}
|
|
6
|
+
import User from '#models/user'
|
|
7
|
+
|
|
8
|
+
interface NotificationParams {}
|
|
9
|
+
export default class {{ notificationName }} extends Notification<User, NotificationParams> {}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({
|
|
3
|
+
to: app.makePath(migration.folder, entity.path, migration.fileName)
|
|
4
|
+
})
|
|
5
|
+
}}}
|
|
6
|
+
import { BaseSchema } from '@adonisjs/lucid/schema'
|
|
7
|
+
|
|
8
|
+
export default class extends BaseSchema {
|
|
9
|
+
protected tableName = 'notifications'
|
|
10
|
+
|
|
11
|
+
async up() {
|
|
12
|
+
this.schema.createTable(this.tableName, (table) => {
|
|
13
|
+
table.increments('id').primary()
|
|
14
|
+
table.text('notifiable_id').notNullable()
|
|
15
|
+
table.text('tenant_id').nullable()
|
|
16
|
+
table.text('type').notNullable()
|
|
17
|
+
table.jsonb('content').notNullable()
|
|
18
|
+
table.text('status').notNullable().defaultTo('unseen')
|
|
19
|
+
table.jsonb('tags').nullable()
|
|
20
|
+
table.timestamp('read_at').nullable()
|
|
21
|
+
table.timestamp('seen_at').nullable()
|
|
22
|
+
|
|
23
|
+
table.timestamp('created_at').notNullable()
|
|
24
|
+
table.timestamp('updated_at').nullable()
|
|
25
|
+
|
|
26
|
+
table.index(['notifiable_id'])
|
|
27
|
+
table.index(['tenant_id'])
|
|
28
|
+
table.index(['status'])
|
|
29
|
+
table.index(['notifiable_id', 'tenant_id'])
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async down() {
|
|
34
|
+
this.schema.dropTable(this.tableName)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({
|
|
3
|
+
to: app.makePath(migration.folder, entity.path, migration.fileName)
|
|
4
|
+
})
|
|
5
|
+
}}}
|
|
6
|
+
import { BaseSchema } from '@adonisjs/lucid/schema'
|
|
7
|
+
|
|
8
|
+
export default class extends BaseSchema {
|
|
9
|
+
protected tableName = 'notification_preferences'
|
|
10
|
+
|
|
11
|
+
async up() {
|
|
12
|
+
this.schema.createTable(this.tableName, (table) => {
|
|
13
|
+
table.increments('id').primary()
|
|
14
|
+
|
|
15
|
+
table.text('user_id').notNullable()
|
|
16
|
+
table.text('tenant_id').nullable()
|
|
17
|
+
table.text('notification_name').nullable()
|
|
18
|
+
table.json('channels').notNullable()
|
|
19
|
+
|
|
20
|
+
table.timestamp('created_at').notNullable()
|
|
21
|
+
table.timestamp('updated_at').nullable()
|
|
22
|
+
|
|
23
|
+
table.index(['user_id'])
|
|
24
|
+
table.index(['tenant_id'])
|
|
25
|
+
table.unique(['user_id', 'tenant_id', 'notification_name'])
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async down() {
|
|
30
|
+
this.schema.dropTable(this.tableName)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "@facteurjs/core/channels/aws-sns";
|
|
2
|
+
export * from "@facteurjs/core/channels/aws-sns/types";
|
|
3
|
+
|
|
4
|
+
//#region src/channels/aws-sns.d.ts
|
|
5
|
+
|
|
6
|
+
import * as import__facteurjs_core_channels_aws_sns from "@facteurjs/core/channels/aws-sns";
|
|
7
|
+
import * as import__facteurjs_core_channels_aws_sns_types from "@facteurjs/core/channels/aws-sns/types";
|
|
8
|
+
//#endregion
|
|
9
|
+
export { import__facteurjs_core_channels_aws_sns_types as aws_sns_d_exports };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "@facteurjs/core/database";
|
|
2
|
+
export * from "@facteurjs/core/database/types";
|
|
3
|
+
|
|
4
|
+
//#region src/channels/database.d.ts
|
|
5
|
+
|
|
6
|
+
import * as import__facteurjs_core_database from "@facteurjs/core/database";
|
|
7
|
+
import * as import__facteurjs_core_database_types from "@facteurjs/core/database/types";
|
|
8
|
+
//#endregion
|
|
9
|
+
export { import__facteurjs_core_database_types as database_d_exports };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "@facteurjs/core/channels/discord";
|
|
2
|
+
export * from "@facteurjs/core/channels/discord/types";
|
|
3
|
+
|
|
4
|
+
//#region src/channels/discord.d.ts
|
|
5
|
+
|
|
6
|
+
import * as import__facteurjs_core_channels_discord from "@facteurjs/core/channels/discord";
|
|
7
|
+
import * as import__facteurjs_core_channels_discord_types from "@facteurjs/core/channels/discord/types";
|
|
8
|
+
//#endregion
|
|
9
|
+
export { import__facteurjs_core_channels_discord_types as discord_d_exports };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "@facteurjs/core/channels/fcm";
|
|
2
|
+
export * from "@facteurjs/core/channels/fcm/types";
|
|
3
|
+
|
|
4
|
+
//#region src/channels/fcm.d.ts
|
|
5
|
+
|
|
6
|
+
import * as import__facteurjs_core_channels_fcm from "@facteurjs/core/channels/fcm";
|
|
7
|
+
import * as import__facteurjs_core_channels_fcm_types from "@facteurjs/core/channels/fcm/types";
|
|
8
|
+
//#endregion
|
|
9
|
+
export { import__facteurjs_core_channels_fcm_types as fcm_d_exports };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { types_exports } from "../types.
|
|
1
|
+
import { types_exports } from "../types.mjs";
|
|
2
2
|
import { errors } from "@facteurjs/core";
|
|
3
3
|
import { BaseMail, Message } from "@adonisjs/mail";
|
|
4
4
|
|
|
@@ -15,6 +15,7 @@ var MailChannel = class {
|
|
|
15
15
|
async send(options) {
|
|
16
16
|
const targets = options.targets;
|
|
17
17
|
if (!targets || !targets.email) throw new errors.E_UNAVAILABLE_TARGETS(["Mail"]);
|
|
18
|
+
console.log(options.message);
|
|
18
19
|
if (options.message instanceof BaseMail) {
|
|
19
20
|
options.message.message.to(targets.email);
|
|
20
21
|
this.config.mailer.send(options.message);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "@facteurjs/core/channels/socketio";
|
|
2
|
+
export * from "@facteurjs/core/channels/socketio/types";
|
|
3
|
+
|
|
4
|
+
//#region src/channels/socketio.d.ts
|
|
5
|
+
|
|
6
|
+
import * as import__facteurjs_core_channels_socketio from "@facteurjs/core/channels/socketio";
|
|
7
|
+
import * as import__facteurjs_core_channels_socketio_types from "@facteurjs/core/channels/socketio/types";
|
|
8
|
+
//#endregion
|
|
9
|
+
export { import__facteurjs_core_channels_socketio_types as socketio_d_exports };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "@facteurjs/core/channels/transmit";
|
|
2
|
+
export * from "@facteurjs/core/channels/transmit/types";
|
|
3
|
+
|
|
4
|
+
//#region src/channels/transmit.d.ts
|
|
5
|
+
|
|
6
|
+
import * as import__facteurjs_core_channels_transmit from "@facteurjs/core/channels/transmit";
|
|
7
|
+
import * as import__facteurjs_core_channels_transmit_types from "@facteurjs/core/channels/transmit/types";
|
|
8
|
+
//#endregion
|
|
9
|
+
export { import__facteurjs_core_channels_transmit_types as transmit_d_exports };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "@facteurjs/core/channels/twilio";
|
|
2
|
+
export * from "@facteurjs/core/channels/twilio/types";
|
|
3
|
+
|
|
4
|
+
//#region src/channels/twilio.d.ts
|
|
5
|
+
|
|
6
|
+
import * as import__facteurjs_core_channels_twilio from "@facteurjs/core/channels/twilio";
|
|
7
|
+
import * as import__facteurjs_core_channels_twilio_types from "@facteurjs/core/channels/twilio/types";
|
|
8
|
+
//#endregion
|
|
9
|
+
export { import__facteurjs_core_channels_twilio_types as twilio_d_exports };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "@facteurjs/core/channels/webpush";
|
|
2
|
+
export * from "@facteurjs/core/channels/webpush/types";
|
|
3
|
+
|
|
4
|
+
//#region src/channels/webpush.d.ts
|
|
5
|
+
|
|
6
|
+
import * as import__facteurjs_core_channels_webpush from "@facteurjs/core/channels/webpush";
|
|
7
|
+
import * as import__facteurjs_core_channels_webpush_types from "@facteurjs/core/channels/webpush/types";
|
|
8
|
+
//#endregion
|
|
9
|
+
export { import__facteurjs_core_channels_webpush_types as webpush_d_exports };
|
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
import { aws_sns_d_exports } from "./channels/aws-sns.
|
|
2
|
-
import { database_d_exports } from "./channels/database.
|
|
3
|
-
import { discord_d_exports } from "./channels/discord.
|
|
4
|
-
import { fcm_d_exports } from "./channels/fcm.
|
|
5
|
-
import { socketio_d_exports } from "./channels/socketio.
|
|
6
|
-
import { transmit_d_exports } from "./channels/transmit.
|
|
7
|
-
import { twilio_d_exports } from "./channels/twilio.
|
|
8
|
-
import { webpush_d_exports } from "./channels/webpush.
|
|
9
|
-
import { MailChannel } from "./channels/mail.
|
|
10
|
-
import { DiscordOptions } from "@facteurjs/core/channels/discord/types";
|
|
11
|
-
import { SlackOptions } from "@facteurjs/core/channels/slack/types";
|
|
12
|
-
import { TwilioConfig } from "@facteurjs/core/channels/twilio/types";
|
|
13
|
-
import { FcmConfig } from "@facteurjs/core/channels/fcm/types";
|
|
14
|
-
import { WebpushConfig } from "@facteurjs/core/channels/webpush/types";
|
|
15
|
-
import { ExpoChannel } from "@facteurjs/core/channels/expo";
|
|
16
|
-
import { ExpoConfig } from "@facteurjs/core/channels/expo/types";
|
|
1
|
+
import { aws_sns_d_exports } from "./channels/aws-sns.mjs";
|
|
2
|
+
import { database_d_exports } from "./channels/database.mjs";
|
|
3
|
+
import { discord_d_exports } from "./channels/discord.mjs";
|
|
4
|
+
import { fcm_d_exports } from "./channels/fcm.mjs";
|
|
5
|
+
import { socketio_d_exports } from "./channels/socketio.mjs";
|
|
6
|
+
import { transmit_d_exports } from "./channels/transmit.mjs";
|
|
7
|
+
import { twilio_d_exports } from "./channels/twilio.mjs";
|
|
8
|
+
import { webpush_d_exports } from "./channels/webpush.mjs";
|
|
9
|
+
import { MailChannel } from "./channels/mail.mjs";
|
|
17
10
|
import { ConfigProvider } from "@adonisjs/core/types";
|
|
18
11
|
|
|
19
12
|
//#region src/channels.d.ts
|
|
13
|
+
|
|
20
14
|
interface DatabaseConfig {
|
|
21
15
|
connectionName?: string;
|
|
22
16
|
tableNames?: {
|
|
@@ -26,7 +20,7 @@ interface DatabaseConfig {
|
|
|
26
20
|
}
|
|
27
21
|
declare const channels: {
|
|
28
22
|
discordWebhook<Options extends DiscordOptions<any>>(config: Options): ConfigProvider<discord_d_exports.DiscordProvider<Options>>;
|
|
29
|
-
slackWebhook<Options extends SlackOptions<any>>(config: Options): ConfigProvider<
|
|
23
|
+
slackWebhook<Options extends SlackOptions<any>>(config: Options): ConfigProvider<SlackWebhookChannel<Options>>;
|
|
30
24
|
database(config: DatabaseConfig): ConfigProvider<database_d_exports.DatabaseChannel>;
|
|
31
25
|
kysely(config: database_d_exports.KyselyConfig): ConfigProvider<database_d_exports.DatabaseChannel>;
|
|
32
26
|
twilio(config: TwilioConfig): ConfigProvider<twilio_d_exports.TwilioChannel>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { configProvider } from "@adonisjs/core";
|
|
2
1
|
import { RuntimeException } from "@adonisjs/core/exceptions";
|
|
2
|
+
import { configProvider } from "@adonisjs/core";
|
|
3
3
|
|
|
4
4
|
//#region src/channels.ts
|
|
5
5
|
const channels = {
|
|
@@ -19,12 +19,11 @@ const channels = {
|
|
|
19
19
|
return configProvider.create(async (app) => {
|
|
20
20
|
const db = await app.container.make("lucid.db");
|
|
21
21
|
const connectionName = config?.connectionName || db.primaryConnectionName;
|
|
22
|
-
const connection = db.manager.get(connectionName);
|
|
23
22
|
/**
|
|
24
23
|
* Throw error when mentioned connection is not specified
|
|
25
24
|
* in the database file
|
|
26
25
|
*/
|
|
27
|
-
if (!
|
|
26
|
+
if (!db.manager.get(connectionName)) throw new RuntimeException(`Invalid connection name "${connectionName}" referenced by "config/notifications.ts" file. First register the connection inside "config/database.ts" file`);
|
|
28
27
|
const { databaseChannel } = await import("@facteurjs/core/database");
|
|
29
28
|
const { knexAdapter } = await import("@facteurjs/core/database/adapters/knex");
|
|
30
29
|
return databaseChannel({ adapter: knexAdapter({
|
|
@@ -52,15 +51,13 @@ const channels = {
|
|
|
52
51
|
transmit() {
|
|
53
52
|
return configProvider.create(async (app) => {
|
|
54
53
|
const { transmitChannel } = await import("@facteurjs/core/channels/transmit");
|
|
55
|
-
|
|
56
|
-
return transmitChannel({ transmit });
|
|
54
|
+
return transmitChannel({ transmit: await app.container.make("transmit") });
|
|
57
55
|
});
|
|
58
56
|
},
|
|
59
57
|
mail() {
|
|
60
58
|
return configProvider.create(async (app) => {
|
|
61
|
-
const { mailChannel } = await import("./channels/mail.
|
|
62
|
-
|
|
63
|
-
return mailChannel({ mailer });
|
|
59
|
+
const { mailChannel } = await import("./channels/mail.mjs");
|
|
60
|
+
return mailChannel({ mailer: await app.container.make("mail.manager") });
|
|
64
61
|
});
|
|
65
62
|
},
|
|
66
63
|
fcm(config) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChannelName } from "../types/extend.
|
|
1
|
+
import { ChannelName } from "../types/extend.mjs";
|
|
2
2
|
|
|
3
3
|
//#region ../core/src/database/types.d.ts
|
|
4
4
|
type NotificationStatus = 'read' | 'seen' | 'unread' | 'unseen';
|
|
@@ -39,10 +39,6 @@ interface PruneNotificationsParams {
|
|
|
39
39
|
tenantId?: Identifier;
|
|
40
40
|
olderThan?: Date;
|
|
41
41
|
}
|
|
42
|
-
/**
|
|
43
|
-
* Options accepted by the database provider
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
42
|
interface GetPreferencesParams {
|
|
47
43
|
notifiableId: Identifier;
|
|
48
44
|
tenantId?: Identifier;
|
|
@@ -75,4 +71,4 @@ interface DatabaseAdapter {
|
|
|
75
71
|
updatePreferences: (options: UpdatePreferencesParams) => Promise<void>;
|
|
76
72
|
}
|
|
77
73
|
//#endregion
|
|
78
|
-
export { DatabaseAdapter };
|
|
74
|
+
export { DatabaseAdapter, Identifier };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Identifier } from "../database/types.mjs";
|
|
2
|
+
import { Awaitable } from "@julr/utils/types";
|
|
3
|
+
|
|
4
|
+
//#region ../core/src/types/channel.d.ts
|
|
5
|
+
type ChannelSendParams<Message, Targets> = {
|
|
6
|
+
to?: any;
|
|
7
|
+
message: Message;
|
|
8
|
+
targets?: Targets;
|
|
9
|
+
tenantId?: Identifier | undefined;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Result of a batch send operation
|
|
13
|
+
*/
|
|
14
|
+
interface BatchSendResult {
|
|
15
|
+
success: number;
|
|
16
|
+
failed: number;
|
|
17
|
+
results: Array<{
|
|
18
|
+
index: number;
|
|
19
|
+
status: 'success' | 'failed';
|
|
20
|
+
error?: Error;
|
|
21
|
+
response?: any;
|
|
22
|
+
}>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Configuration for batch sending capabilities
|
|
26
|
+
*/
|
|
27
|
+
interface BatchConfig {
|
|
28
|
+
/**
|
|
29
|
+
* Maximum number of messages per batch API call.
|
|
30
|
+
* E.g. 500 for FCM, 100 for Expo
|
|
31
|
+
*/
|
|
32
|
+
maxSize: number;
|
|
33
|
+
/**
|
|
34
|
+
* Whether batching is enabled for this channel.
|
|
35
|
+
* @default true
|
|
36
|
+
*/
|
|
37
|
+
enabled?: boolean;
|
|
38
|
+
}
|
|
39
|
+
declare const kTargetSymbol: unique symbol;
|
|
40
|
+
interface Channel<_Options = any, Message = any, Response = any, Targets = any> {
|
|
41
|
+
[kTargetSymbol]: Targets;
|
|
42
|
+
name: string;
|
|
43
|
+
send: (options: ChannelSendParams<Message, Targets>) => Awaitable<Response>;
|
|
44
|
+
/**
|
|
45
|
+
* Optional batch send method for providers that support sending multiple messages in one API call.
|
|
46
|
+
* When implemented, the orchestration layer will group messages and use this method.
|
|
47
|
+
*/
|
|
48
|
+
sendBatch?: (messages: ChannelSendParams<Message, Targets>[]) => Awaitable<BatchSendResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Configuration for batch sending.
|
|
51
|
+
* Required when sendBatch is implemented.
|
|
52
|
+
*/
|
|
53
|
+
batchConfig?: BatchConfig;
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
export { Channel };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region ../core/src/types/events.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shape of the emitter accepted by facteur
|
|
4
|
+
* Should be compatible with node's EventEmitter and Emittery
|
|
5
|
+
*/
|
|
6
|
+
interface Emitter {
|
|
7
|
+
on: (event: string, callback: (...values: any[]) => void) => void;
|
|
8
|
+
once: (event: string, callback: (...values: any[]) => void) => void;
|
|
9
|
+
off: (event: string, callback: (...values: any[]) => void) => void;
|
|
10
|
+
emit: (event: string, ...values: any[]) => void;
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { Emitter };
|
|
@@ -9,9 +9,5 @@ type ChannelName = keyof NotificationChannels;
|
|
|
9
9
|
* be extended user-land with module augmentation
|
|
10
10
|
*/
|
|
11
11
|
interface NotificationChannels {}
|
|
12
|
-
/**
|
|
13
|
-
* The type of the notification.content in database notifications.
|
|
14
|
-
* This must be extended user-land with module augmentation
|
|
15
|
-
*/
|
|
16
12
|
//#endregion
|
|
17
|
-
export { ChannelName };
|
|
13
|
+
export { ChannelName, NotificationChannels };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Identifier } from "../database/types.mjs";
|
|
2
|
+
import { NotificationChannels } from "./extend.mjs";
|
|
3
|
+
import { ExtractChannelTargets, MessageCtx, NotificationOptions } from "./options.mjs";
|
|
4
|
+
import { Awaitable } from "@julr/utils/types";
|
|
5
|
+
|
|
6
|
+
//#region ../core/src/types/notifications.d.ts
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Base abstract class for all notifications
|
|
10
|
+
*/
|
|
11
|
+
declare abstract class Notification<N extends Notifiable | undefined = Notifiable | undefined, Params extends Record<string, any> = any> {
|
|
12
|
+
protected notifiable: N;
|
|
13
|
+
protected params: Params;
|
|
14
|
+
protected tenantId: Identifier | undefined;
|
|
15
|
+
constructor(ctx: MessageCtx<N, Params>);
|
|
16
|
+
static options: NotificationOptions<any>;
|
|
17
|
+
/**
|
|
18
|
+
* Determine if the notification should be sent or not
|
|
19
|
+
*/
|
|
20
|
+
shouldSend(): Awaitable<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Method invoked before sending the notification.
|
|
23
|
+
* Can be used to perform any pre-send logic.
|
|
24
|
+
*/
|
|
25
|
+
beforeSend(): Awaitable<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Method invoked after the notification has been sent.
|
|
28
|
+
* Can be used to perform any post-send logic.
|
|
29
|
+
*/
|
|
30
|
+
afterSend(): Awaitable<void>;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Interface for entities that can receive notifications
|
|
34
|
+
*/
|
|
35
|
+
interface Notifiable {
|
|
36
|
+
notificationTargets?(): NotifiableTargets;
|
|
37
|
+
}
|
|
38
|
+
type NotifiableTargets = { [K in keyof NotificationChannels]?: ExtractChannelTargets<NotificationChannels[K]> };
|
|
39
|
+
//#endregion
|
|
40
|
+
export { Notifiable, Notification };
|