@camstack/addon-notifiers 1.2.131 → 1.2.133

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/addon.js +159 -89
  2. package/dist/addon.mjs +159 -89
  3. package/package.json +1 -1
package/dist/addon.js CHANGED
@@ -53352,65 +53352,79 @@ var discordAdapter = {
53352
53352
  };
53353
53353
  }
53354
53354
  };
53355
- var descriptor$2 = {
53356
- kind: "email",
53357
- label: "Email",
53358
- icon: "mail",
53359
- addonId: "notifiers",
53360
- supportsDiscovery: false,
53361
- configSchema: { sections: [{
53362
- id: "email",
53363
- title: "Email",
53364
- description: "Send via a Connectivity → Email provider (Google Services or SMTP). Install and Verify a provider first.",
53365
- fields: [
53366
- {
53367
- type: "text",
53368
- key: "to",
53369
- label: "To",
53370
- description: "Recipient address, or comma-separated list.",
53371
- required: true
53372
- },
53373
- {
53374
- type: "text",
53375
- key: "smtpAddonId",
53376
- label: "Email provider addon id (optional)",
53377
- description: "Leave blank to use the first ready smtp-provider. Examples: google-services, smtp-nodemailer."
53355
+ //#endregion
53356
+ //#region src/adapters/email.ts
53357
+ var EMAIL_KIND = "email";
53358
+ var BODY_MAX = 1e5;
53359
+ /** Build the email kind descriptor, optionally stamping live provider options. */
53360
+ function buildEmailDescriptor(providers = []) {
53361
+ const options = providers.map((p) => ({
53362
+ value: p.value,
53363
+ label: p.label,
53364
+ ...p.description !== void 0 ? { description: p.description } : {}
53365
+ }));
53366
+ return {
53367
+ kind: EMAIL_KIND,
53368
+ label: "Email",
53369
+ icon: "mail",
53370
+ addonId: "notifiers",
53371
+ supportsDiscovery: false,
53372
+ configSchema: { sections: [{
53373
+ id: "email",
53374
+ title: "Email",
53375
+ description: "Send via a Connectivity → Email provider (Google Services or SMTP). Install and Verify a provider first.",
53376
+ fields: [
53377
+ {
53378
+ type: "text",
53379
+ key: "to",
53380
+ label: "To",
53381
+ description: "Recipient address, or comma-separated list.",
53382
+ required: true
53383
+ },
53384
+ {
53385
+ type: "select",
53386
+ key: "smtpAddonId",
53387
+ label: "Email provider",
53388
+ description: options.length === 0 ? "No Email provider installed. Open Connectivity → Email, install Google Services or SMTP, then Verify." : "Which Connectivity → Email entry delivers this target. Verify it under Connectivity → Email if the label says not verified.",
53389
+ required: true,
53390
+ options
53391
+ },
53392
+ {
53393
+ type: "text",
53394
+ key: "from",
53395
+ label: "From (optional)",
53396
+ description: "Override From when the relay allows it."
53397
+ }
53398
+ ]
53399
+ }] },
53400
+ caps: {
53401
+ attachments: {
53402
+ mediaTypes: ["image"],
53403
+ mode: "url",
53404
+ max: 0
53378
53405
  },
53379
- {
53380
- type: "text",
53381
- key: "from",
53382
- label: "From (optional)",
53383
- description: "Override From when the relay allows it."
53384
- }
53385
- ]
53386
- }] },
53387
- caps: {
53388
- attachments: {
53389
- mediaTypes: ["image"],
53390
- mode: "url",
53391
- max: 0
53392
- },
53393
- actions: 0,
53394
- levels: [{
53395
- id: "normal",
53396
- label: "Normal",
53397
- ordinal: 3
53398
- }, {
53399
- id: "high",
53400
- label: "High",
53401
- ordinal: 4
53402
- }],
53403
- format: [
53404
- "text",
53405
- "html",
53406
- "markdown"
53407
- ],
53408
- clickUrl: true,
53409
- sound: false,
53410
- ttl: false,
53411
- bodyMaxLen: 1e5
53412
- }
53413
- };
53406
+ actions: 0,
53407
+ levels: [{
53408
+ id: "normal",
53409
+ label: "Normal",
53410
+ ordinal: 3
53411
+ }, {
53412
+ id: "high",
53413
+ label: "High",
53414
+ ordinal: 4
53415
+ }],
53416
+ format: [
53417
+ "text",
53418
+ "html",
53419
+ "markdown"
53420
+ ],
53421
+ clickUrl: true,
53422
+ sound: false,
53423
+ ttl: false,
53424
+ bodyMaxLen: BODY_MAX
53425
+ }
53426
+ };
53427
+ }
53414
53428
  function requireTo(config) {
53415
53429
  const raw = config["to"];
53416
53430
  if (typeof raw !== "string" || raw.trim() === "") throw new Error("email: missing required config 'to'");
@@ -53435,13 +53449,17 @@ function escapeHtml$1(value) {
53435
53449
  /** Build the email adapter bound to a live smtp-provider client. */
53436
53450
  function createEmailAdapter(smtp) {
53437
53451
  return {
53438
- descriptor: descriptor$2,
53439
- destinationKeys: ["to"],
53452
+ descriptor: buildEmailDescriptor(),
53453
+ hydrateDescriptor: async () => {
53454
+ return buildEmailDescriptor(await smtp.listProviders?.() ?? []);
53455
+ },
53456
+ destinationKeys: ["to", "smtpAddonId"],
53440
53457
  async sendDirect(config, prepared) {
53441
53458
  try {
53442
53459
  const to = requireTo(config);
53443
53460
  const bodies = renderBodies(prepared);
53444
53461
  const addonId = (typeof config["smtpAddonId"] === "string" && config["smtpAddonId"].trim() !== "" ? config["smtpAddonId"].trim() : void 0) ?? await smtp.resolveDefaultAddonId?.();
53462
+ if (addonId === void 0) throw new Error("email: pick an Email provider (Connectivity → Email) — none ready or none selected");
53445
53463
  const subject = prepared.title?.trim() && prepared.title.trim().length > 0 ? prepared.title.trim() : "CamStack notification";
53446
53464
  const from = typeof config["from"] === "string" && config["from"].trim() !== "" ? config["from"].trim() : void 0;
53447
53465
  await smtp.sendEmail({
@@ -53449,7 +53467,7 @@ function createEmailAdapter(smtp) {
53449
53467
  subject,
53450
53468
  text: bodies.text,
53451
53469
  ...bodies.html !== void 0 ? { html: bodies.html } : {},
53452
- ...addonId !== void 0 ? { addonId } : {},
53470
+ addonId,
53453
53471
  ...from !== void 0 ? { from } : {}
53454
53472
  });
53455
53473
  return { success: true };
@@ -55586,6 +55604,10 @@ var NOTIFIER_ICONS = {
55586
55604
  contentType: "image/svg+xml",
55587
55605
  body: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"#7C3AED\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4.876 13.61a4 4 0 1 0 6.124 3.39h6\" /><path d=\"M15.066 20.502a4 4 0 1 0 1.934 -7.502c-.706 0 -1.424 .179 -2 .5l-3 -5.5\" /><path d=\"M16 8a4 4 0 1 0 -8 0c0 1.506 .77 2.818 2 3.5l-3 5.5\" /></svg>"
55588
55606
  },
55607
+ email: {
55608
+ contentType: "image/svg+xml",
55609
+ body: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"#EA4335\"><path d=\"M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6zm-2 0-8 5-8-5h16zm0 12H4V8l8 5 8-5v10z\"/></svg>"
55610
+ },
55589
55611
  gotify: {
55590
55612
  contentType: "image/svg+xml",
55591
55613
  body: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 500 500\" width=\"500\" height=\"500\"><style type=\"text/css\" id=\"style1\"> .st0{fill:#DDCBA2;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st1{fill:#71CAEE;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st2{fill:#FFFFFF;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st3{fill:#888E93;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st4{fill:#F0F0F0;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st5{fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st6{fill:url(#SVGID_1_);} .st7{fill:url(#SVGID_2_);} .st8{fill:#FFFFFF;} .st9{fill:url(#SVGID_3_);} .st10{fill:url(#SVGID_4_);} .st11{fill:url(#SVGID_5_);} .st12{fill:none;stroke:#FFFFFF;stroke-width:63;stroke-linecap:round;stroke-miterlimit:10;} .st13{fill:none;stroke:#FFFFFF;stroke-width:56;stroke-linecap:round;stroke-miterlimit:10;} .st14{fill:none;stroke:#A4C639;stroke-width:45.1385;stroke-linecap:round;stroke-miterlimit:10;} .st15{fill:none;stroke:#FFFFFF;stroke-width:16;} .st16{fill:#A4C639;} .st17{fill:#E6E6E6;stroke:#FFFFFF;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;} .st18{fill:none;stroke:#FFFFFF;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;} .st19{fill:url(#SVGID_6_);} .st20{fill:url(#SVGID_7_);} .st21{fill:url(#SVGID_8_);} </style><g transform=\"matrix(2.3327641,0,0,2.3327641,-431.80457,-323.21807)\"><g id=\"g48\" transform=\"translate(-24.881692,25.94805)\"><g id=\"g47\"><path class=\"st1\" d=\"m 258.9,119.7 c -3,-0.9 -6,-1.8 -9,-2.7 -4.6,-1.4 -9.2,-2.8 -14,-2.5 -2.8,0.2 -6.1,1.3 -6.9,4 -0.6,2 -1.6,7.3 -1.3,7.9 1.5,3.4 13.9,6.7 18.3,6.7\" id=\"path2\" /><path d=\"m 392.6,177.9 c -1.4,1.4 -2.2,3.5 -2.5,5.5 -0.2,1.4 -0.1,3 0.5,4.3 0.6,1.3 1.8,2.3 3.1,3 1.3,0.6 2.8,0.9 4.3,0.9 1.1,0 2.3,-0.1 3.1,-0.9 0.6,-0.7 0.8,-1.6 0.9,-2.5 0.2,-2.3 -0.1,-4.7 -0.9,-6.9 -0.4,-1.1 -0.9,-2.3 -1.8,-3.1 -1.7,-1.8 -4.5,-2.2 -6.4,-0.5 -0.1,0 -0.2,0.1 -0.3,0.2 z\" id=\"path3\" /><path class=\"st2\" d=\"m 358.5,164.2 c -1,-1 0,-2.7 1,-3.7 5.8,-5.2 15.1,-4.6 21.8,-0.6 10.9,6.6 15.6,19.9 17.2,32.5 0.6,5.2 0.9,10.6 -0.5,15.7 -1.4,5.1 -4.6,9.9 -9.3,12.1 -1.1,0.5 -2.3,0.9 -3.4,0.5 -1.1,-0.4 -1.9,-1.8 -1.2,-2.8 -9.4,-13.6 -19,-26.8 -20.9,-43.2 -0.5,-4.1 -1.8,-7.4 -4.7,-10.5 z\" id=\"path4\" /><path class=\"st1\" d=\"m 220.05771,133 c 34.58546,-18 79.30862,-19.6 112.16964,-8.7 23.69194,7.9 41.3449,26.7 49.4515,50 7.11442,20.6 7.1441,43.6 3.04307,65.7 -7.4942,40.2 -26.19597,77.9 -48.96683,112.6 -12.56244,19 -24.57093,36 -44.23305,48.5 -38.69347,24.6 -88.90104,22.1 -129.28516,11.5 -19.50745,-5.1 -38.36842,-17.3 -44.32901,-37.3 -3.81479,-12.8 -2.07563,-27.6 4.5788,-40 13.50886,-24.8 46.15565,-38.4 50.82627,-67.9 1.36964,-8.7 -0.26842,-17.3 -1.62187,-25.7 -3.7989,-23.4 -5.37477,-45.8 6.68784,-68.7 9.46237,-17.7 24.28607,-31 41.6788,-40 z\" id=\"path6\" /><path class=\"st2\" d=\"m 264.5,174.9 c -0.5,0.5 -0.9,1 -1.3,1.6 -9,11.6 -12,27.9 -9.3,42.1 1.7,9 5.9,17.9 13.2,23.4 19.3,14.6 51.5,13.5 68.4,-1.5 24.4,-21.7 13,-67.6 -14,-78.8 -17.6,-7.2 -43.7,-1.6 -57,13.2 z\" id=\"path9\" /><g id=\"g11\"><path class=\"st2\" d=\"m 382.1,237.1 c 1.4,-0.1 2.9,-0.1 4.3,0.1 0.3,0 0.7,0.1 1,0.4 0.2,0.3 0.4,0.7 0.5,1.1 1,3.9 0.5,8.2 0.1,12.4 -0.1,0.9 -0.2,1.8 -0.6,2.6 -1,2.1 -3.1,2.7 -4.7,2.7 -0.1,0 -0.2,0 -0.3,-0.1 -0.3,-0.2 -0.3,-0.7 -0.2,-1.2 0.3,-5.9 -0.1,-11.9 -0.1,-18 0,0.1 0,0.1 0,0 z\" id=\"path10\" /><path class=\"st2\" d=\"m 378.7,236.8 c -1.4,0.4 -2.5,2 -2.8,4.4 -0.5,4.4 -0.7,8.9 -0.5,13.4 0,0.9 0.1,1.9 0.5,2.4 0.2,0.3 0.5,0.4 0.8,0.4 1.6,0.3 4.1,-0.6 5.6,-1 0,0 0,-5.2 -0.1,-8 -0.1,-2.8 -0.1,-6.1 -0.2,-8.9 0,-0.6 0,-1.5 0,-2.2 0.1,-0.7 -2.6,-0.7 -3.3,-0.5 z\" id=\"path11\" /></g><path class=\"st0\" d=\"m 358.3,231.8 c -0.3,2.2 0.1,4.7 1.7,7.4 2.6,4.4 7,6.1 11.9,5.8 8.9,-0.6 25.3,-5.4 27.5,-15.7 0.6,-3 -0.3,-6.1 -2.2,-8.5 -6.2,-7.8 -17.8,-5.7 -25.6,-2 -5.9,2.7 -12.4,7 -13.3,13 z\" id=\"path12\" /><path class=\"st3\" d=\"m 386.4,208.6 c 2.2,1.4 3.7,3.8 4,7 0.3,3.6 -1.4,7.5 -5,8.8 -2.9,1.1 -6.2,0.6 -9.1,-0.4 -2.9,-1 -5.8,-2.8 -6.8,-5.7 -0.7,-2 -0.3,-4.3 0.7,-6.1 1.1,-1.8 2.8,-3.2 4.7,-4.1 3.9,-1.8 8.4,-1.6 11.5,0.5 z\" id=\"path13\" /><path class=\"st0\" d=\"m 414.7,262.6 c 2.4,0.6 4.8,2.1 5.6,4.4 0.8,2.3 0.1,4.9 -1.6,6.7 -1.7,1.8 -4.2,2.5 -6.6,2.5 -0.8,0 -1.7,-0.1 -2.4,-0.5 -2.5,-1.1 -3.5,-4 -4.2,-6.6 -1.8,-6.8 3.6,-7.8 9.2,-6.5 z\" id=\"path14\" /><g id=\"g17\"><path class=\"st4\" d=\"m 267.1,284.7 c 2.3,-4.5 141.3,-36.2 144.7,-31.6 3.4,4.5 15.8,88.2 9,90.4 -6.8,2.3 -119.8,37.3 -126.6,35 -6.8,-2.3 -29.4,-89.3 -27.1,-93.8 z\" id=\"path15\" /><path class=\"st5\" d=\"m 294.2,378.5 c 0,0 54.3,-74.6 59.9,-76.9 5.7,-2.3 67.3,41.3 67.3,41.3\" id=\"path16\" /><path class=\"st4\" d=\"m 267,287.7 c 0,0 86,38.8 91.6,36.6 5.7,-2.3 53.1,-71.2 53.1,-71.2\" id=\"path17\" /></g><g id=\"g33\"><linearGradient id=\"SVGID_2_\" gradientUnits=\"userSpaceOnUse\" x1=\"265.03339\" y1=\"280.2951\" x2=\"275.3009\" y2=\"302.31369\"><stop offset=\"5.152266e-07\" style=\"stop-color:#71CAEE\" id=\"stop25\" /><stop offset=\"4.104413e-02\" style=\"stop-color:#83CAE2\" id=\"stop26\" /><stop offset=\"0.1206\" style=\"stop-color:#9FCACE\" id=\"stop27\" /><stop offset=\"0.2107\" style=\"stop-color:#B6CBBE\" id=\"stop28\" /><stop offset=\"0.3139\" style=\"stop-color:#C7CBB1\" id=\"stop29\" /><stop offset=\"0.4384\" style=\"stop-color:#D4CBA8\" id=\"stop30\" /><stop offset=\"0.6058\" style=\"stop-color:#DBCBA3\" id=\"stop31\" /><stop offset=\"1\" style=\"stop-color:#DDCBA2\" id=\"stop32\" /></linearGradient><path class=\"st7\" d=\"m 261.9,283.5 c -0.1,4.2 4.3,7.3 8.4,7.6 4.1,0.3 8.2,-1.3 12.2,-2.6 1.4,-0.4 2.9,-0.8 4.2,-0.2 1.8,0.9 2.7,4.1 1.8,5.9 -0.9,1.8 -3.4,3.5 -5.3,4.4 -6.5,3 -12.9,3.6 -19.9,2 -5.3,-1.2 -11.3,-4.3 -13,-13.5\" id=\"path32\" style=\"fill:url(#SVGID_2_)\" /><path class=\"st5\" d=\"m 261.9,283.5 c -0.1,4.2 4.3,7.3 8.4,7.6 4.1,0.3 8.2,-1.3 12.2,-2.6 1.4,-0.4 2.9,-0.8 4.2,-0.2 1.8,0.9 2.7,4.1 1.8,5.9 -0.9,1.8 -3.4,3.5 -5.3,4.4 -6.5,3 -12.9,3.6 -19.9,2 -5.3,-1.2 -11.3,-4.3 -13,-13.5\" id=\"path33\" /></g><path d=\"m 318.4,198.4 c -2,-0.3 -4.1,0.1 -5.9,1.3 -3.2,2.1 -4.7,6.2 -4.7,9.9 0,1.9 0.4,3.8 1.4,5.3 1.2,1.7 3.1,2.9 5.2,3.4 3.4,0.8 8.2,0.7 10.5,-2.5 1,-1.5 1.4,-3.3 1.5,-5.1 0.5,-5.7 -1.8,-11.4 -8,-12.3 z\" id=\"path34\" /><path class=\"st8\" d=\"m 320.4,203.3 c 0.9,0.3 1.7,0.8 2.1,1.7 0.4,0.8 0.4,1.7 0.3,2.5 -0.1,1 -0.6,2 -1.5,2.7 -0.7,0.5 -1.7,0.7 -2.6,0.5 -0.9,-0.2 -1.7,-0.8 -2.2,-1.6 -1.1,-1.6 -0.9,-4.4 0.9,-5.5 0.9,-0.4 2,-0.6 3,-0.3 z\" id=\"path35\" /></g></g></g></svg>"
@@ -56488,24 +56510,32 @@ function createNotificationOutputProvider(deps) {
56488
56510
  const iconUrlFor = deps.iconUrlFor;
56489
56511
  const iconMediaTypeFor = deps.iconMediaTypeFor;
56490
56512
  return {
56491
- listTargetKinds: async () => deps.adapters.map((a) => {
56492
- const descriptor = {
56493
- ...a.descriptor,
56494
- addonId,
56495
- destinationKeys: [...a.destinationKeys]
56496
- };
56497
- const iconUrl = iconUrlFor?.(a.descriptor.kind);
56498
- if (iconUrl === void 0) return descriptor;
56499
- const iconMediaType = iconMediaTypeFor?.(a.descriptor.kind);
56500
- return iconMediaType !== void 0 ? {
56501
- ...descriptor,
56502
- iconUrl,
56503
- iconMediaType
56504
- } : {
56505
- ...descriptor,
56506
- iconUrl
56507
- };
56508
- }),
56513
+ listTargetKinds: async () => {
56514
+ const kinds = [];
56515
+ for (const a of deps.adapters) {
56516
+ const base = a.hydrateDescriptor !== void 0 ? await a.hydrateDescriptor() : a.descriptor;
56517
+ const descriptor = {
56518
+ ...base,
56519
+ addonId,
56520
+ destinationKeys: [...a.destinationKeys]
56521
+ };
56522
+ const iconUrl = iconUrlFor?.(base.kind);
56523
+ if (iconUrl === void 0) {
56524
+ kinds.push(descriptor);
56525
+ continue;
56526
+ }
56527
+ const iconMediaType = iconMediaTypeFor?.(base.kind);
56528
+ kinds.push(iconMediaType !== void 0 ? {
56529
+ ...descriptor,
56530
+ iconUrl,
56531
+ iconMediaType
56532
+ } : {
56533
+ ...descriptor,
56534
+ iconUrl
56535
+ });
56536
+ }
56537
+ return kinds;
56538
+ },
56509
56539
  listTargets: async () => {
56510
56540
  return (await store.list()).map((target) => {
56511
56541
  const adapter = adapterByKind.get(target.kind);
@@ -56812,16 +56842,56 @@ var NotifiersAddon = class extends BaseAddon {
56812
56842
  if (!api) this.ctx.logger.warn("notifiers: no ctx.api — targets persist in-memory only");
56813
56843
  const store = new TargetStore(port);
56814
56844
  await store.init();
56815
- const adapters = buildNotifierAdapters(api !== void 0 ? { sendEmail: async (input) => {
56816
- return { messageId: (await api.smtpProvider.sendEmail({
56817
- to: input.to,
56818
- subject: input.subject,
56819
- text: input.text,
56820
- ...input.html !== void 0 ? { html: input.html } : {},
56821
- ...input.from !== void 0 ? { from: input.from } : {},
56822
- ...input.addonId !== void 0 ? { addonId: input.addonId } : {}
56823
- })).messageId };
56824
- } } : void 0);
56845
+ const listProviders = async () => {
56846
+ if (api === void 0) return [];
56847
+ const [providers, addons] = await Promise.all([api.addons.listCapabilityProviders.query({ capName: "smtp-provider" }), api.addons.list.query()]);
56848
+ const names = /* @__PURE__ */ new Map();
56849
+ for (const row of addons) {
56850
+ const id = row.manifest.id;
56851
+ names.set(id, row.manifest.name ?? row.manifest.packageDisplayName ?? id);
56852
+ }
56853
+ const out = [];
56854
+ for (const p of providers) {
56855
+ if (!p.isActive) continue;
56856
+ const name = names.get(p.addonId) ?? p.addonId;
56857
+ try {
56858
+ const status = await api.smtpProvider.getStatus.query({ addonId: p.addonId });
56859
+ const hostBit = status.host !== "" ? status.host : p.addonId;
56860
+ const label = status.ready ? `${name} — ${hostBit}` : `${name} — ${hostBit} (not verified)`;
56861
+ out.push({
56862
+ value: p.addonId,
56863
+ label,
56864
+ description: p.addonId,
56865
+ ready: status.ready
56866
+ });
56867
+ } catch {
56868
+ out.push({
56869
+ value: p.addonId,
56870
+ label: `${name} (status unavailable)`,
56871
+ description: p.addonId,
56872
+ ready: false
56873
+ });
56874
+ }
56875
+ }
56876
+ return out;
56877
+ };
56878
+ const adapters = buildNotifierAdapters(api !== void 0 ? {
56879
+ sendEmail: async (input) => {
56880
+ return { messageId: (await api.smtpProvider.sendEmail.mutate({
56881
+ to: typeof input.to === "string" ? input.to : [...input.to],
56882
+ subject: input.subject,
56883
+ text: input.text,
56884
+ ...input.html !== void 0 ? { html: input.html } : {},
56885
+ ...input.from !== void 0 ? { from: input.from } : {},
56886
+ ...input.addonId !== void 0 ? { addonId: input.addonId } : {}
56887
+ })).messageId };
56888
+ },
56889
+ listProviders,
56890
+ resolveDefaultAddonId: async () => {
56891
+ const providers = await listProviders();
56892
+ return providers.find((p) => p.ready === true)?.value ?? providers[0]?.value;
56893
+ }
56894
+ } : void 0);
56825
56895
  const provider = createNotificationOutputProvider({
56826
56896
  store,
56827
56897
  adapters,
package/dist/addon.mjs CHANGED
@@ -53325,65 +53325,79 @@ var discordAdapter = {
53325
53325
  };
53326
53326
  }
53327
53327
  };
53328
- var descriptor$2 = {
53329
- kind: "email",
53330
- label: "Email",
53331
- icon: "mail",
53332
- addonId: "notifiers",
53333
- supportsDiscovery: false,
53334
- configSchema: { sections: [{
53335
- id: "email",
53336
- title: "Email",
53337
- description: "Send via a Connectivity → Email provider (Google Services or SMTP). Install and Verify a provider first.",
53338
- fields: [
53339
- {
53340
- type: "text",
53341
- key: "to",
53342
- label: "To",
53343
- description: "Recipient address, or comma-separated list.",
53344
- required: true
53345
- },
53346
- {
53347
- type: "text",
53348
- key: "smtpAddonId",
53349
- label: "Email provider addon id (optional)",
53350
- description: "Leave blank to use the first ready smtp-provider. Examples: google-services, smtp-nodemailer."
53328
+ //#endregion
53329
+ //#region src/adapters/email.ts
53330
+ var EMAIL_KIND = "email";
53331
+ var BODY_MAX = 1e5;
53332
+ /** Build the email kind descriptor, optionally stamping live provider options. */
53333
+ function buildEmailDescriptor(providers = []) {
53334
+ const options = providers.map((p) => ({
53335
+ value: p.value,
53336
+ label: p.label,
53337
+ ...p.description !== void 0 ? { description: p.description } : {}
53338
+ }));
53339
+ return {
53340
+ kind: EMAIL_KIND,
53341
+ label: "Email",
53342
+ icon: "mail",
53343
+ addonId: "notifiers",
53344
+ supportsDiscovery: false,
53345
+ configSchema: { sections: [{
53346
+ id: "email",
53347
+ title: "Email",
53348
+ description: "Send via a Connectivity → Email provider (Google Services or SMTP). Install and Verify a provider first.",
53349
+ fields: [
53350
+ {
53351
+ type: "text",
53352
+ key: "to",
53353
+ label: "To",
53354
+ description: "Recipient address, or comma-separated list.",
53355
+ required: true
53356
+ },
53357
+ {
53358
+ type: "select",
53359
+ key: "smtpAddonId",
53360
+ label: "Email provider",
53361
+ description: options.length === 0 ? "No Email provider installed. Open Connectivity → Email, install Google Services or SMTP, then Verify." : "Which Connectivity → Email entry delivers this target. Verify it under Connectivity → Email if the label says not verified.",
53362
+ required: true,
53363
+ options
53364
+ },
53365
+ {
53366
+ type: "text",
53367
+ key: "from",
53368
+ label: "From (optional)",
53369
+ description: "Override From when the relay allows it."
53370
+ }
53371
+ ]
53372
+ }] },
53373
+ caps: {
53374
+ attachments: {
53375
+ mediaTypes: ["image"],
53376
+ mode: "url",
53377
+ max: 0
53351
53378
  },
53352
- {
53353
- type: "text",
53354
- key: "from",
53355
- label: "From (optional)",
53356
- description: "Override From when the relay allows it."
53357
- }
53358
- ]
53359
- }] },
53360
- caps: {
53361
- attachments: {
53362
- mediaTypes: ["image"],
53363
- mode: "url",
53364
- max: 0
53365
- },
53366
- actions: 0,
53367
- levels: [{
53368
- id: "normal",
53369
- label: "Normal",
53370
- ordinal: 3
53371
- }, {
53372
- id: "high",
53373
- label: "High",
53374
- ordinal: 4
53375
- }],
53376
- format: [
53377
- "text",
53378
- "html",
53379
- "markdown"
53380
- ],
53381
- clickUrl: true,
53382
- sound: false,
53383
- ttl: false,
53384
- bodyMaxLen: 1e5
53385
- }
53386
- };
53379
+ actions: 0,
53380
+ levels: [{
53381
+ id: "normal",
53382
+ label: "Normal",
53383
+ ordinal: 3
53384
+ }, {
53385
+ id: "high",
53386
+ label: "High",
53387
+ ordinal: 4
53388
+ }],
53389
+ format: [
53390
+ "text",
53391
+ "html",
53392
+ "markdown"
53393
+ ],
53394
+ clickUrl: true,
53395
+ sound: false,
53396
+ ttl: false,
53397
+ bodyMaxLen: BODY_MAX
53398
+ }
53399
+ };
53400
+ }
53387
53401
  function requireTo(config) {
53388
53402
  const raw = config["to"];
53389
53403
  if (typeof raw !== "string" || raw.trim() === "") throw new Error("email: missing required config 'to'");
@@ -53408,13 +53422,17 @@ function escapeHtml$1(value) {
53408
53422
  /** Build the email adapter bound to a live smtp-provider client. */
53409
53423
  function createEmailAdapter(smtp) {
53410
53424
  return {
53411
- descriptor: descriptor$2,
53412
- destinationKeys: ["to"],
53425
+ descriptor: buildEmailDescriptor(),
53426
+ hydrateDescriptor: async () => {
53427
+ return buildEmailDescriptor(await smtp.listProviders?.() ?? []);
53428
+ },
53429
+ destinationKeys: ["to", "smtpAddonId"],
53413
53430
  async sendDirect(config, prepared) {
53414
53431
  try {
53415
53432
  const to = requireTo(config);
53416
53433
  const bodies = renderBodies(prepared);
53417
53434
  const addonId = (typeof config["smtpAddonId"] === "string" && config["smtpAddonId"].trim() !== "" ? config["smtpAddonId"].trim() : void 0) ?? await smtp.resolveDefaultAddonId?.();
53435
+ if (addonId === void 0) throw new Error("email: pick an Email provider (Connectivity → Email) — none ready or none selected");
53418
53436
  const subject = prepared.title?.trim() && prepared.title.trim().length > 0 ? prepared.title.trim() : "CamStack notification";
53419
53437
  const from = typeof config["from"] === "string" && config["from"].trim() !== "" ? config["from"].trim() : void 0;
53420
53438
  await smtp.sendEmail({
@@ -53422,7 +53440,7 @@ function createEmailAdapter(smtp) {
53422
53440
  subject,
53423
53441
  text: bodies.text,
53424
53442
  ...bodies.html !== void 0 ? { html: bodies.html } : {},
53425
- ...addonId !== void 0 ? { addonId } : {},
53443
+ addonId,
53426
53444
  ...from !== void 0 ? { from } : {}
53427
53445
  });
53428
53446
  return { success: true };
@@ -55559,6 +55577,10 @@ var NOTIFIER_ICONS = {
55559
55577
  contentType: "image/svg+xml",
55560
55578
  body: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"none\" stroke=\"#7C3AED\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4.876 13.61a4 4 0 1 0 6.124 3.39h6\" /><path d=\"M15.066 20.502a4 4 0 1 0 1.934 -7.502c-.706 0 -1.424 .179 -2 .5l-3 -5.5\" /><path d=\"M16 8a4 4 0 1 0 -8 0c0 1.506 .77 2.818 2 3.5l-3 5.5\" /></svg>"
55561
55579
  },
55580
+ email: {
55581
+ contentType: "image/svg+xml",
55582
+ body: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" fill=\"#EA4335\"><path d=\"M22 6c0-1.1-.9-2-2-2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6zm-2 0-8 5-8-5h16zm0 12H4V8l8 5 8-5v10z\"/></svg>"
55583
+ },
55562
55584
  gotify: {
55563
55585
  contentType: "image/svg+xml",
55564
55586
  body: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 500 500\" width=\"500\" height=\"500\"><style type=\"text/css\" id=\"style1\"> .st0{fill:#DDCBA2;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st1{fill:#71CAEE;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st2{fill:#FFFFFF;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st3{fill:#888E93;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st4{fill:#F0F0F0;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st5{fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10;} .st6{fill:url(#SVGID_1_);} .st7{fill:url(#SVGID_2_);} .st8{fill:#FFFFFF;} .st9{fill:url(#SVGID_3_);} .st10{fill:url(#SVGID_4_);} .st11{fill:url(#SVGID_5_);} .st12{fill:none;stroke:#FFFFFF;stroke-width:63;stroke-linecap:round;stroke-miterlimit:10;} .st13{fill:none;stroke:#FFFFFF;stroke-width:56;stroke-linecap:round;stroke-miterlimit:10;} .st14{fill:none;stroke:#A4C639;stroke-width:45.1385;stroke-linecap:round;stroke-miterlimit:10;} .st15{fill:none;stroke:#FFFFFF;stroke-width:16;} .st16{fill:#A4C639;} .st17{fill:#E6E6E6;stroke:#FFFFFF;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;} .st18{fill:none;stroke:#FFFFFF;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;} .st19{fill:url(#SVGID_6_);} .st20{fill:url(#SVGID_7_);} .st21{fill:url(#SVGID_8_);} </style><g transform=\"matrix(2.3327641,0,0,2.3327641,-431.80457,-323.21807)\"><g id=\"g48\" transform=\"translate(-24.881692,25.94805)\"><g id=\"g47\"><path class=\"st1\" d=\"m 258.9,119.7 c -3,-0.9 -6,-1.8 -9,-2.7 -4.6,-1.4 -9.2,-2.8 -14,-2.5 -2.8,0.2 -6.1,1.3 -6.9,4 -0.6,2 -1.6,7.3 -1.3,7.9 1.5,3.4 13.9,6.7 18.3,6.7\" id=\"path2\" /><path d=\"m 392.6,177.9 c -1.4,1.4 -2.2,3.5 -2.5,5.5 -0.2,1.4 -0.1,3 0.5,4.3 0.6,1.3 1.8,2.3 3.1,3 1.3,0.6 2.8,0.9 4.3,0.9 1.1,0 2.3,-0.1 3.1,-0.9 0.6,-0.7 0.8,-1.6 0.9,-2.5 0.2,-2.3 -0.1,-4.7 -0.9,-6.9 -0.4,-1.1 -0.9,-2.3 -1.8,-3.1 -1.7,-1.8 -4.5,-2.2 -6.4,-0.5 -0.1,0 -0.2,0.1 -0.3,0.2 z\" id=\"path3\" /><path class=\"st2\" d=\"m 358.5,164.2 c -1,-1 0,-2.7 1,-3.7 5.8,-5.2 15.1,-4.6 21.8,-0.6 10.9,6.6 15.6,19.9 17.2,32.5 0.6,5.2 0.9,10.6 -0.5,15.7 -1.4,5.1 -4.6,9.9 -9.3,12.1 -1.1,0.5 -2.3,0.9 -3.4,0.5 -1.1,-0.4 -1.9,-1.8 -1.2,-2.8 -9.4,-13.6 -19,-26.8 -20.9,-43.2 -0.5,-4.1 -1.8,-7.4 -4.7,-10.5 z\" id=\"path4\" /><path class=\"st1\" d=\"m 220.05771,133 c 34.58546,-18 79.30862,-19.6 112.16964,-8.7 23.69194,7.9 41.3449,26.7 49.4515,50 7.11442,20.6 7.1441,43.6 3.04307,65.7 -7.4942,40.2 -26.19597,77.9 -48.96683,112.6 -12.56244,19 -24.57093,36 -44.23305,48.5 -38.69347,24.6 -88.90104,22.1 -129.28516,11.5 -19.50745,-5.1 -38.36842,-17.3 -44.32901,-37.3 -3.81479,-12.8 -2.07563,-27.6 4.5788,-40 13.50886,-24.8 46.15565,-38.4 50.82627,-67.9 1.36964,-8.7 -0.26842,-17.3 -1.62187,-25.7 -3.7989,-23.4 -5.37477,-45.8 6.68784,-68.7 9.46237,-17.7 24.28607,-31 41.6788,-40 z\" id=\"path6\" /><path class=\"st2\" d=\"m 264.5,174.9 c -0.5,0.5 -0.9,1 -1.3,1.6 -9,11.6 -12,27.9 -9.3,42.1 1.7,9 5.9,17.9 13.2,23.4 19.3,14.6 51.5,13.5 68.4,-1.5 24.4,-21.7 13,-67.6 -14,-78.8 -17.6,-7.2 -43.7,-1.6 -57,13.2 z\" id=\"path9\" /><g id=\"g11\"><path class=\"st2\" d=\"m 382.1,237.1 c 1.4,-0.1 2.9,-0.1 4.3,0.1 0.3,0 0.7,0.1 1,0.4 0.2,0.3 0.4,0.7 0.5,1.1 1,3.9 0.5,8.2 0.1,12.4 -0.1,0.9 -0.2,1.8 -0.6,2.6 -1,2.1 -3.1,2.7 -4.7,2.7 -0.1,0 -0.2,0 -0.3,-0.1 -0.3,-0.2 -0.3,-0.7 -0.2,-1.2 0.3,-5.9 -0.1,-11.9 -0.1,-18 0,0.1 0,0.1 0,0 z\" id=\"path10\" /><path class=\"st2\" d=\"m 378.7,236.8 c -1.4,0.4 -2.5,2 -2.8,4.4 -0.5,4.4 -0.7,8.9 -0.5,13.4 0,0.9 0.1,1.9 0.5,2.4 0.2,0.3 0.5,0.4 0.8,0.4 1.6,0.3 4.1,-0.6 5.6,-1 0,0 0,-5.2 -0.1,-8 -0.1,-2.8 -0.1,-6.1 -0.2,-8.9 0,-0.6 0,-1.5 0,-2.2 0.1,-0.7 -2.6,-0.7 -3.3,-0.5 z\" id=\"path11\" /></g><path class=\"st0\" d=\"m 358.3,231.8 c -0.3,2.2 0.1,4.7 1.7,7.4 2.6,4.4 7,6.1 11.9,5.8 8.9,-0.6 25.3,-5.4 27.5,-15.7 0.6,-3 -0.3,-6.1 -2.2,-8.5 -6.2,-7.8 -17.8,-5.7 -25.6,-2 -5.9,2.7 -12.4,7 -13.3,13 z\" id=\"path12\" /><path class=\"st3\" d=\"m 386.4,208.6 c 2.2,1.4 3.7,3.8 4,7 0.3,3.6 -1.4,7.5 -5,8.8 -2.9,1.1 -6.2,0.6 -9.1,-0.4 -2.9,-1 -5.8,-2.8 -6.8,-5.7 -0.7,-2 -0.3,-4.3 0.7,-6.1 1.1,-1.8 2.8,-3.2 4.7,-4.1 3.9,-1.8 8.4,-1.6 11.5,0.5 z\" id=\"path13\" /><path class=\"st0\" d=\"m 414.7,262.6 c 2.4,0.6 4.8,2.1 5.6,4.4 0.8,2.3 0.1,4.9 -1.6,6.7 -1.7,1.8 -4.2,2.5 -6.6,2.5 -0.8,0 -1.7,-0.1 -2.4,-0.5 -2.5,-1.1 -3.5,-4 -4.2,-6.6 -1.8,-6.8 3.6,-7.8 9.2,-6.5 z\" id=\"path14\" /><g id=\"g17\"><path class=\"st4\" d=\"m 267.1,284.7 c 2.3,-4.5 141.3,-36.2 144.7,-31.6 3.4,4.5 15.8,88.2 9,90.4 -6.8,2.3 -119.8,37.3 -126.6,35 -6.8,-2.3 -29.4,-89.3 -27.1,-93.8 z\" id=\"path15\" /><path class=\"st5\" d=\"m 294.2,378.5 c 0,0 54.3,-74.6 59.9,-76.9 5.7,-2.3 67.3,41.3 67.3,41.3\" id=\"path16\" /><path class=\"st4\" d=\"m 267,287.7 c 0,0 86,38.8 91.6,36.6 5.7,-2.3 53.1,-71.2 53.1,-71.2\" id=\"path17\" /></g><g id=\"g33\"><linearGradient id=\"SVGID_2_\" gradientUnits=\"userSpaceOnUse\" x1=\"265.03339\" y1=\"280.2951\" x2=\"275.3009\" y2=\"302.31369\"><stop offset=\"5.152266e-07\" style=\"stop-color:#71CAEE\" id=\"stop25\" /><stop offset=\"4.104413e-02\" style=\"stop-color:#83CAE2\" id=\"stop26\" /><stop offset=\"0.1206\" style=\"stop-color:#9FCACE\" id=\"stop27\" /><stop offset=\"0.2107\" style=\"stop-color:#B6CBBE\" id=\"stop28\" /><stop offset=\"0.3139\" style=\"stop-color:#C7CBB1\" id=\"stop29\" /><stop offset=\"0.4384\" style=\"stop-color:#D4CBA8\" id=\"stop30\" /><stop offset=\"0.6058\" style=\"stop-color:#DBCBA3\" id=\"stop31\" /><stop offset=\"1\" style=\"stop-color:#DDCBA2\" id=\"stop32\" /></linearGradient><path class=\"st7\" d=\"m 261.9,283.5 c -0.1,4.2 4.3,7.3 8.4,7.6 4.1,0.3 8.2,-1.3 12.2,-2.6 1.4,-0.4 2.9,-0.8 4.2,-0.2 1.8,0.9 2.7,4.1 1.8,5.9 -0.9,1.8 -3.4,3.5 -5.3,4.4 -6.5,3 -12.9,3.6 -19.9,2 -5.3,-1.2 -11.3,-4.3 -13,-13.5\" id=\"path32\" style=\"fill:url(#SVGID_2_)\" /><path class=\"st5\" d=\"m 261.9,283.5 c -0.1,4.2 4.3,7.3 8.4,7.6 4.1,0.3 8.2,-1.3 12.2,-2.6 1.4,-0.4 2.9,-0.8 4.2,-0.2 1.8,0.9 2.7,4.1 1.8,5.9 -0.9,1.8 -3.4,3.5 -5.3,4.4 -6.5,3 -12.9,3.6 -19.9,2 -5.3,-1.2 -11.3,-4.3 -13,-13.5\" id=\"path33\" /></g><path d=\"m 318.4,198.4 c -2,-0.3 -4.1,0.1 -5.9,1.3 -3.2,2.1 -4.7,6.2 -4.7,9.9 0,1.9 0.4,3.8 1.4,5.3 1.2,1.7 3.1,2.9 5.2,3.4 3.4,0.8 8.2,0.7 10.5,-2.5 1,-1.5 1.4,-3.3 1.5,-5.1 0.5,-5.7 -1.8,-11.4 -8,-12.3 z\" id=\"path34\" /><path class=\"st8\" d=\"m 320.4,203.3 c 0.9,0.3 1.7,0.8 2.1,1.7 0.4,0.8 0.4,1.7 0.3,2.5 -0.1,1 -0.6,2 -1.5,2.7 -0.7,0.5 -1.7,0.7 -2.6,0.5 -0.9,-0.2 -1.7,-0.8 -2.2,-1.6 -1.1,-1.6 -0.9,-4.4 0.9,-5.5 0.9,-0.4 2,-0.6 3,-0.3 z\" id=\"path35\" /></g></g></g></svg>"
@@ -56461,24 +56483,32 @@ function createNotificationOutputProvider(deps) {
56461
56483
  const iconUrlFor = deps.iconUrlFor;
56462
56484
  const iconMediaTypeFor = deps.iconMediaTypeFor;
56463
56485
  return {
56464
- listTargetKinds: async () => deps.adapters.map((a) => {
56465
- const descriptor = {
56466
- ...a.descriptor,
56467
- addonId,
56468
- destinationKeys: [...a.destinationKeys]
56469
- };
56470
- const iconUrl = iconUrlFor?.(a.descriptor.kind);
56471
- if (iconUrl === void 0) return descriptor;
56472
- const iconMediaType = iconMediaTypeFor?.(a.descriptor.kind);
56473
- return iconMediaType !== void 0 ? {
56474
- ...descriptor,
56475
- iconUrl,
56476
- iconMediaType
56477
- } : {
56478
- ...descriptor,
56479
- iconUrl
56480
- };
56481
- }),
56486
+ listTargetKinds: async () => {
56487
+ const kinds = [];
56488
+ for (const a of deps.adapters) {
56489
+ const base = a.hydrateDescriptor !== void 0 ? await a.hydrateDescriptor() : a.descriptor;
56490
+ const descriptor = {
56491
+ ...base,
56492
+ addonId,
56493
+ destinationKeys: [...a.destinationKeys]
56494
+ };
56495
+ const iconUrl = iconUrlFor?.(base.kind);
56496
+ if (iconUrl === void 0) {
56497
+ kinds.push(descriptor);
56498
+ continue;
56499
+ }
56500
+ const iconMediaType = iconMediaTypeFor?.(base.kind);
56501
+ kinds.push(iconMediaType !== void 0 ? {
56502
+ ...descriptor,
56503
+ iconUrl,
56504
+ iconMediaType
56505
+ } : {
56506
+ ...descriptor,
56507
+ iconUrl
56508
+ });
56509
+ }
56510
+ return kinds;
56511
+ },
56482
56512
  listTargets: async () => {
56483
56513
  return (await store.list()).map((target) => {
56484
56514
  const adapter = adapterByKind.get(target.kind);
@@ -56785,16 +56815,56 @@ var NotifiersAddon = class extends BaseAddon {
56785
56815
  if (!api) this.ctx.logger.warn("notifiers: no ctx.api — targets persist in-memory only");
56786
56816
  const store = new TargetStore(port);
56787
56817
  await store.init();
56788
- const adapters = buildNotifierAdapters(api !== void 0 ? { sendEmail: async (input) => {
56789
- return { messageId: (await api.smtpProvider.sendEmail({
56790
- to: input.to,
56791
- subject: input.subject,
56792
- text: input.text,
56793
- ...input.html !== void 0 ? { html: input.html } : {},
56794
- ...input.from !== void 0 ? { from: input.from } : {},
56795
- ...input.addonId !== void 0 ? { addonId: input.addonId } : {}
56796
- })).messageId };
56797
- } } : void 0);
56818
+ const listProviders = async () => {
56819
+ if (api === void 0) return [];
56820
+ const [providers, addons] = await Promise.all([api.addons.listCapabilityProviders.query({ capName: "smtp-provider" }), api.addons.list.query()]);
56821
+ const names = /* @__PURE__ */ new Map();
56822
+ for (const row of addons) {
56823
+ const id = row.manifest.id;
56824
+ names.set(id, row.manifest.name ?? row.manifest.packageDisplayName ?? id);
56825
+ }
56826
+ const out = [];
56827
+ for (const p of providers) {
56828
+ if (!p.isActive) continue;
56829
+ const name = names.get(p.addonId) ?? p.addonId;
56830
+ try {
56831
+ const status = await api.smtpProvider.getStatus.query({ addonId: p.addonId });
56832
+ const hostBit = status.host !== "" ? status.host : p.addonId;
56833
+ const label = status.ready ? `${name} — ${hostBit}` : `${name} — ${hostBit} (not verified)`;
56834
+ out.push({
56835
+ value: p.addonId,
56836
+ label,
56837
+ description: p.addonId,
56838
+ ready: status.ready
56839
+ });
56840
+ } catch {
56841
+ out.push({
56842
+ value: p.addonId,
56843
+ label: `${name} (status unavailable)`,
56844
+ description: p.addonId,
56845
+ ready: false
56846
+ });
56847
+ }
56848
+ }
56849
+ return out;
56850
+ };
56851
+ const adapters = buildNotifierAdapters(api !== void 0 ? {
56852
+ sendEmail: async (input) => {
56853
+ return { messageId: (await api.smtpProvider.sendEmail.mutate({
56854
+ to: typeof input.to === "string" ? input.to : [...input.to],
56855
+ subject: input.subject,
56856
+ text: input.text,
56857
+ ...input.html !== void 0 ? { html: input.html } : {},
56858
+ ...input.from !== void 0 ? { from: input.from } : {},
56859
+ ...input.addonId !== void 0 ? { addonId: input.addonId } : {}
56860
+ })).messageId };
56861
+ },
56862
+ listProviders,
56863
+ resolveDefaultAddonId: async () => {
56864
+ const providers = await listProviders();
56865
+ return providers.find((p) => p.ready === true)?.value ?? providers[0]?.value;
56866
+ }
56867
+ } : void 0);
56798
56868
  const provider = createNotificationOutputProvider({
56799
56869
  store,
56800
56870
  adapters,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-notifiers",
3
- "version": "1.2.131",
3
+ "version": "1.2.133",
4
4
  "description": "System notifiers addon for CamStack — a `notification-output` collection provider hosting per-kind notifier adapters (ntfy, pushover, gotify, telegram, discord, webhook, zentik).",
5
5
  "keywords": [
6
6
  "camstack",