@camstack/addon-remote-storage 1.1.13 → 1.1.14

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/dist/s3.addon.js CHANGED
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_shared = require("./shared-a5hRX888.js");
5
+ const require_shared = require("./shared-N5OfEciV.js");
6
6
  let node_stream = require("node:stream");
7
7
  let _aws_sdk_client_s3 = require("@aws-sdk/client-s3");
8
8
  let _aws_sdk_lib_storage = require("@aws-sdk/lib-storage");
package/dist/s3.addon.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { c as BaseAddon, i as rearmIdleAbort, n as getOptionalBasePath, o as scheduleIdleAbort, s as storageProviderCapability, t as createSessionId } from "./shared-DwqiKj85.mjs";
1
+ import { c as BaseAddon, i as rearmIdleAbort, n as getOptionalBasePath, o as scheduleIdleAbort, s as storageProviderCapability, t as createSessionId } from "./shared-D9u4CXu8.mjs";
2
2
  import { PassThrough } from "node:stream";
3
3
  import { DeleteObjectCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
4
4
  import { Upload } from "@aws-sdk/lib-storage";
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_shared = require("./shared-a5hRX888.js");
5
+ const require_shared = require("./shared-N5OfEciV.js");
6
6
  let ssh2 = require("ssh2");
7
7
  let node_path = require("node:path");
8
8
  node_path = require_shared.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { a as safeJoinRemotePath, c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, r as getRequiredBasePath, s as storageProviderCapability, t as createSessionId } from "./shared-DwqiKj85.mjs";
1
+ import { a as safeJoinRemotePath, c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, r as getRequiredBasePath, s as storageProviderCapability, t as createSessionId } from "./shared-D9u4CXu8.mjs";
2
2
  import { Client } from "ssh2";
3
3
  import * as path from "node:path";
4
4
  //#region src/providers/sftp/sftp-config-schema.ts
@@ -4629,7 +4629,7 @@ function _instanceof(cls, params = {}) {
4629
4629
  return inst;
4630
4630
  }
4631
4631
  //#endregion
4632
- //#region ../types/dist/sleep-C2M2zF7x.mjs
4632
+ //#region ../types/dist/sleep-MHm--th-.mjs
4633
4633
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4634
4634
  EventCategory["SystemBoot"] = "system.boot";
4635
4635
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5891,6 +5891,7 @@ var CamStreamKindSchema = _enum([
5891
5891
  "pull-rtsp",
5892
5892
  "pull-rtmp",
5893
5893
  "pull-http",
5894
+ "pull-flv",
5894
5895
  "pull-rfc4571",
5895
5896
  "push-annexb",
5896
5897
  "derived"
@@ -13188,7 +13189,7 @@ var AddBrokerInputSchema = object({
13188
13189
  });
13189
13190
  var AddBrokerResultSchema = object({ id: string() });
13190
13191
  var IdInputSchema = object({ id: string() });
13191
- var TestResultSchema = discriminatedUnion("ok", [object({
13192
+ var TestResultSchema$1 = discriminatedUnion("ok", [object({
13192
13193
  ok: literal(true),
13193
13194
  latencyMs: number()
13194
13195
  }), object({
@@ -13211,7 +13212,7 @@ var StatusSchema = object({
13211
13212
  brokerCount: number(),
13212
13213
  embeddedRunning: boolean()
13213
13214
  });
13214
- method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema), method(AddBrokerInputSchema, AddBrokerResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(IdInputSchema, TestResultSchema, { kind: "mutation" }), method(StartEmbeddedInputSchema, StartEmbeddedResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(_void(), StatusSchema);
13215
+ method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema), method(AddBrokerInputSchema, AddBrokerResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(IdInputSchema, TestResultSchema$1, { kind: "mutation" }), method(StartEmbeddedInputSchema, StartEmbeddedResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(_void(), StatusSchema);
13215
13216
  var NetworkEndpointSchema = object({
13216
13217
  url: string(),
13217
13218
  hostname: string(),
@@ -13245,23 +13246,198 @@ var NetworkEndpointEntrySchema = NetworkEndpointSchema.extend({
13245
13246
  sourcePort: number().optional()
13246
13247
  });
13247
13248
  method(_void(), NetworkEndpointSchema, { kind: "mutation" }), method(_void(), _void(), { kind: "mutation" }), method(_void(), NetworkEndpointSchema.nullable()), method(_void(), NetworkAccessStatusSchema), method(_void(), array(NetworkEndpointEntrySchema).readonly());
13248
- method(object({
13249
- title: string(),
13249
+ /**
13250
+ * notification-output — canonical, capability-gated notification delivery.
13251
+ *
13252
+ * Apprise-derived model (see
13253
+ * `docs/superpowers/specs/2026-07-03-notification-output-notifier-matrix.md`):
13254
+ * callers emit ONE canonical `Notification`; each provider declares a
13255
+ * per-kind capability descriptor (`TargetKind`), and the pure degrade
13256
+ * engine (`@camstack/types` `prepareNotification`) transcodes / degrades the
13257
+ * message to what the kind supports — callers never special-case a service.
13258
+ *
13259
+ * DESIGN DECISIONS (locked):
13260
+ * - Target CRUD lives on THIS cap (`upsertTarget` / `deleteTarget` /
13261
+ * `setTargetEnabled`), each provider persisting via the `settings-store`
13262
+ * cap. Rationale: the admin UI needs one uniform surface across the
13263
+ * notifiers addon AND the HA addon; the addon-`globalSettingsSchema`-array
13264
+ * alternative would fork the UI per addon and cannot host the
13265
+ * discovery→adopt flow.
13266
+ * - `listTargetKinds` / `listTargets` / `discoverTargets` return arrays →
13267
+ * the generated cap-mount auto-`concatCollection`-fans them across every
13268
+ * registered provider (notifiers addon + HA addon) so one catalog is
13269
+ * routable. `send` / `testTarget` / CRUD route to ONE provider by the
13270
+ * `addonId` the generated collection router extracts from the call input.
13271
+ * - `Attachment.bytes` is `Uint8Array`. Transport-safe: superjson (the tRPC
13272
+ * transformer) + UDS MsgPack both round-trip typed arrays — already used by
13273
+ * `storage` / `storage-provider` / `recording` caps over the same path. No
13274
+ * base64 fallback needed.
13275
+ *
13276
+ * TODO (deferred, closed-set change — separate decision): add
13277
+ * `providerKind: 'notify'` so notification providers surface on the unified
13278
+ * admin "Integrations" page.
13279
+ */
13280
+ /**
13281
+ * Zentik-derived typed-media enum — the superset across every kind. Each
13282
+ * adapter picks what it supports and the degrade engine filters the rest.
13283
+ */
13284
+ var AttachmentMediaTypeSchema = _enum([
13285
+ "image",
13286
+ "video",
13287
+ "gif",
13288
+ "audio",
13289
+ "icon"
13290
+ ]);
13291
+ /**
13292
+ * A single attachment. Exactly one of `url` (remote source, most adapters
13293
+ * prefer this) or `bytes` (inline source; required for Pushover-style
13294
+ * bytes-only kinds) MUST be present — the degrade engine expresses a
13295
+ * url→bytes fetch as a `needsFetch` directive the adapter executes.
13296
+ */
13297
+ var AttachmentSchema = object({
13298
+ mediaType: AttachmentMediaTypeSchema,
13299
+ url: string().optional(),
13300
+ bytes: _instanceof(Uint8Array).optional(),
13301
+ mime: string().optional(),
13302
+ name: string().optional()
13303
+ }).refine((a) => a.url !== void 0 || a.bytes !== void 0, { message: "Attachment requires either `url` or `bytes`" });
13304
+ var NotificationFormatSchema = _enum([
13305
+ "text",
13306
+ "markdown",
13307
+ "html"
13308
+ ]);
13309
+ /** A single tap-through action button. */
13310
+ var NotificationActionSchema = object({
13311
+ id: string(),
13312
+ label: string(),
13313
+ url: string().optional()
13314
+ });
13315
+ /**
13316
+ * The canonical notification. `body` is the only hard field (Apprise model).
13317
+ * `priority` is a 5-level ORDINAL (1=lowest … 3=normal(default) … 5=urgent),
13318
+ * NOT a fixed severity enum — each kind declares its own `caps.levels` and
13319
+ * the adapter maps this ordinal onto its native level. `level?` is an
13320
+ * optional kind-native level id (`emergency`, `silent`, …) that overrides
13321
+ * `priority` for that one target.
13322
+ */
13323
+ var NotificationSchema = object({
13250
13324
  body: string(),
13251
- imageUrl: string().optional(),
13325
+ title: string().optional(),
13326
+ format: NotificationFormatSchema.default("text"),
13327
+ priority: number().int().min(1).max(5).default(3),
13328
+ level: string().optional(),
13329
+ attachments: array(AttachmentSchema).optional(),
13330
+ clickUrl: string().optional(),
13331
+ actions: array(NotificationActionSchema).optional(),
13332
+ sound: string().optional(),
13333
+ ttl: number().optional(),
13334
+ tag: string().optional(),
13252
13335
  deviceId: number().optional(),
13253
13336
  eventId: string().optional(),
13254
- priority: _enum([
13255
- "low",
13256
- "normal",
13257
- "high",
13258
- "critical"
13259
- ]).default("normal"),
13260
13337
  metadata: record(string(), unknown()).optional()
13261
- }), _void(), { kind: "mutation" }), method(_void(), object({
13338
+ });
13339
+ /** One declared native severity/priority level for a kind. */
13340
+ var TargetKindLevelSchema = object({
13341
+ id: string(),
13342
+ label: string(),
13343
+ /** Which canonical priority (1..5) this level maps to. `null` = qualitative-only. */
13344
+ ordinal: number().int().min(1).max(5).nullable(),
13345
+ flags: object({
13346
+ critical: boolean().optional(),
13347
+ silent: boolean().optional(),
13348
+ noPush: boolean().optional()
13349
+ }).optional(),
13350
+ /** e.g. Pushover `emergency` requires `retry` / `expire`. */
13351
+ requires: array(string()).optional(),
13352
+ description: string().optional()
13353
+ });
13354
+ /** The full capability block consulted before dispatch. */
13355
+ var TargetKindCapsSchema = object({
13356
+ attachments: object({
13357
+ mediaTypes: array(AttachmentMediaTypeSchema),
13358
+ mode: _enum([
13359
+ "url",
13360
+ "bytes",
13361
+ "both"
13362
+ ]),
13363
+ max: number().int().nonnegative(),
13364
+ maxBytes: number().int().positive().optional()
13365
+ }),
13366
+ /** Max action buttons (0 = none). */
13367
+ actions: number().int().nonnegative(),
13368
+ levels: array(TargetKindLevelSchema),
13369
+ format: array(NotificationFormatSchema),
13370
+ clickUrl: boolean(),
13371
+ sound: boolean(),
13372
+ ttl: boolean(),
13373
+ bodyMaxLen: number().int().positive()
13374
+ });
13375
+ /**
13376
+ * `configSchema` is a `ConfigUISchema` tree passed through to the admin
13377
+ * FormBuilder. Stored as `z.unknown()` at the cap seam (mirrors
13378
+ * `device-provider.getChildCreationSchema` `CreationSchemaOutputSchema`) —
13379
+ * the union is large and not meant for runtime validation here; the exported
13380
+ * `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
13381
+ */
13382
+ var ConfigSchemaPassthrough = unknown();
13383
+ var TargetKindSchema = object({
13384
+ kind: string(),
13385
+ label: string(),
13386
+ icon: string(),
13387
+ /** Stamped by each provider so the concat-fanned catalog stays routable. */
13388
+ addonId: string(),
13389
+ configSchema: ConfigSchemaPassthrough,
13390
+ supportsDiscovery: boolean(),
13391
+ caps: TargetKindCapsSchema
13392
+ });
13393
+ /**
13394
+ * A persisted target. `config` holds secrets; providers REDACT secret fields
13395
+ * (return a presence marker only) when serving `listTargets` — never
13396
+ * round-trip a stored secret to the UI.
13397
+ */
13398
+ var TargetSchema = object({
13399
+ id: string(),
13400
+ name: string(),
13401
+ kind: string(),
13402
+ addonId: string(),
13403
+ enabled: boolean(),
13404
+ config: record(string(), unknown())
13405
+ });
13406
+ /** A discovery-surfaced candidate (config is partial + non-secret). */
13407
+ var DiscoveredTargetSchema = object({
13408
+ kind: string(),
13409
+ suggestedName: string(),
13410
+ config: record(string(), unknown())
13411
+ });
13412
+ /** The degrade engine's report — what was resolved / dropped / degraded. */
13413
+ var RenderedAsSchema = object({
13414
+ level: string(),
13415
+ format: NotificationFormatSchema,
13416
+ attachmentsSent: number().int().nonnegative(),
13417
+ actionsSent: number().int().nonnegative(),
13418
+ truncated: boolean(),
13419
+ dropped: array(string())
13420
+ });
13421
+ var SendResultSchema = object({
13262
13422
  success: boolean(),
13263
- error: string().optional()
13264
- }), { kind: "mutation" });
13423
+ error: string().optional(),
13424
+ renderedAs: RenderedAsSchema.optional()
13425
+ });
13426
+ /** Same shape as SendResult — kept as a distinct name for the test panel. */
13427
+ var TestResultSchema = SendResultSchema;
13428
+ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSchema)), method(object({
13429
+ kind: string(),
13430
+ config: record(string(), unknown()).optional()
13431
+ }), array(DiscoveredTargetSchema)), method(object({
13432
+ targetId: string(),
13433
+ notification: NotificationSchema
13434
+ }), SendResultSchema, { kind: "mutation" }), method(object({
13435
+ targetId: string(),
13436
+ sample: NotificationSchema.optional()
13437
+ }), TestResultSchema, { kind: "mutation" }), method(object({ target: TargetSchema }), TargetSchema, { kind: "mutation" }), method(object({ targetId: string() }), _void(), { kind: "mutation" }), method(object({
13438
+ targetId: string(),
13439
+ enabled: boolean()
13440
+ }), _void(), { kind: "mutation" });
13265
13441
  /**
13266
13442
  * Zod schemas for persisted record types.
13267
13443
  *
@@ -19301,13 +19477,49 @@ Object.freeze({
19301
19477
  addonId: null,
19302
19478
  access: "create"
19303
19479
  },
19480
+ "notificationOutput.deleteTarget": {
19481
+ capName: "notification-output",
19482
+ capScope: "system",
19483
+ addonId: null,
19484
+ access: "delete"
19485
+ },
19486
+ "notificationOutput.discoverTargets": {
19487
+ capName: "notification-output",
19488
+ capScope: "system",
19489
+ addonId: null,
19490
+ access: "view"
19491
+ },
19492
+ "notificationOutput.listTargetKinds": {
19493
+ capName: "notification-output",
19494
+ capScope: "system",
19495
+ addonId: null,
19496
+ access: "view"
19497
+ },
19498
+ "notificationOutput.listTargets": {
19499
+ capName: "notification-output",
19500
+ capScope: "system",
19501
+ addonId: null,
19502
+ access: "view"
19503
+ },
19304
19504
  "notificationOutput.send": {
19305
19505
  capName: "notification-output",
19306
19506
  capScope: "system",
19307
19507
  addonId: null,
19308
19508
  access: "create"
19309
19509
  },
19310
- "notificationOutput.sendTest": {
19510
+ "notificationOutput.setTargetEnabled": {
19511
+ capName: "notification-output",
19512
+ capScope: "system",
19513
+ addonId: null,
19514
+ access: "create"
19515
+ },
19516
+ "notificationOutput.testTarget": {
19517
+ capName: "notification-output",
19518
+ capScope: "system",
19519
+ addonId: null,
19520
+ access: "create"
19521
+ },
19522
+ "notificationOutput.upsertTarget": {
19311
19523
  capName: "notification-output",
19312
19524
  capScope: "system",
19313
19525
  addonId: null,
@@ -4652,7 +4652,7 @@ function _instanceof(cls, params = {}) {
4652
4652
  return inst;
4653
4653
  }
4654
4654
  //#endregion
4655
- //#region ../types/dist/sleep-C2M2zF7x.mjs
4655
+ //#region ../types/dist/sleep-MHm--th-.mjs
4656
4656
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
4657
4657
  EventCategory["SystemBoot"] = "system.boot";
4658
4658
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -5914,6 +5914,7 @@ var CamStreamKindSchema = _enum([
5914
5914
  "pull-rtsp",
5915
5915
  "pull-rtmp",
5916
5916
  "pull-http",
5917
+ "pull-flv",
5917
5918
  "pull-rfc4571",
5918
5919
  "push-annexb",
5919
5920
  "derived"
@@ -13211,7 +13212,7 @@ var AddBrokerInputSchema = object({
13211
13212
  });
13212
13213
  var AddBrokerResultSchema = object({ id: string() });
13213
13214
  var IdInputSchema = object({ id: string() });
13214
- var TestResultSchema = discriminatedUnion("ok", [object({
13215
+ var TestResultSchema$1 = discriminatedUnion("ok", [object({
13215
13216
  ok: literal(true),
13216
13217
  latencyMs: number()
13217
13218
  }), object({
@@ -13234,7 +13235,7 @@ var StatusSchema = object({
13234
13235
  brokerCount: number(),
13235
13236
  embeddedRunning: boolean()
13236
13237
  });
13237
- method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema), method(AddBrokerInputSchema, AddBrokerResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(IdInputSchema, TestResultSchema, { kind: "mutation" }), method(StartEmbeddedInputSchema, StartEmbeddedResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(_void(), StatusSchema);
13238
+ method(_void(), array(BrokerInfoSchema)), method(IdInputSchema, BrokerConnectionDetailsSchema), method(AddBrokerInputSchema, AddBrokerResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(IdInputSchema, TestResultSchema$1, { kind: "mutation" }), method(StartEmbeddedInputSchema, StartEmbeddedResultSchema, { kind: "mutation" }), method(IdInputSchema, _void(), { kind: "mutation" }), method(_void(), StatusSchema);
13238
13239
  var NetworkEndpointSchema = object({
13239
13240
  url: string(),
13240
13241
  hostname: string(),
@@ -13268,23 +13269,198 @@ var NetworkEndpointEntrySchema = NetworkEndpointSchema.extend({
13268
13269
  sourcePort: number().optional()
13269
13270
  });
13270
13271
  method(_void(), NetworkEndpointSchema, { kind: "mutation" }), method(_void(), _void(), { kind: "mutation" }), method(_void(), NetworkEndpointSchema.nullable()), method(_void(), NetworkAccessStatusSchema), method(_void(), array(NetworkEndpointEntrySchema).readonly());
13271
- method(object({
13272
- title: string(),
13272
+ /**
13273
+ * notification-output — canonical, capability-gated notification delivery.
13274
+ *
13275
+ * Apprise-derived model (see
13276
+ * `docs/superpowers/specs/2026-07-03-notification-output-notifier-matrix.md`):
13277
+ * callers emit ONE canonical `Notification`; each provider declares a
13278
+ * per-kind capability descriptor (`TargetKind`), and the pure degrade
13279
+ * engine (`@camstack/types` `prepareNotification`) transcodes / degrades the
13280
+ * message to what the kind supports — callers never special-case a service.
13281
+ *
13282
+ * DESIGN DECISIONS (locked):
13283
+ * - Target CRUD lives on THIS cap (`upsertTarget` / `deleteTarget` /
13284
+ * `setTargetEnabled`), each provider persisting via the `settings-store`
13285
+ * cap. Rationale: the admin UI needs one uniform surface across the
13286
+ * notifiers addon AND the HA addon; the addon-`globalSettingsSchema`-array
13287
+ * alternative would fork the UI per addon and cannot host the
13288
+ * discovery→adopt flow.
13289
+ * - `listTargetKinds` / `listTargets` / `discoverTargets` return arrays →
13290
+ * the generated cap-mount auto-`concatCollection`-fans them across every
13291
+ * registered provider (notifiers addon + HA addon) so one catalog is
13292
+ * routable. `send` / `testTarget` / CRUD route to ONE provider by the
13293
+ * `addonId` the generated collection router extracts from the call input.
13294
+ * - `Attachment.bytes` is `Uint8Array`. Transport-safe: superjson (the tRPC
13295
+ * transformer) + UDS MsgPack both round-trip typed arrays — already used by
13296
+ * `storage` / `storage-provider` / `recording` caps over the same path. No
13297
+ * base64 fallback needed.
13298
+ *
13299
+ * TODO (deferred, closed-set change — separate decision): add
13300
+ * `providerKind: 'notify'` so notification providers surface on the unified
13301
+ * admin "Integrations" page.
13302
+ */
13303
+ /**
13304
+ * Zentik-derived typed-media enum — the superset across every kind. Each
13305
+ * adapter picks what it supports and the degrade engine filters the rest.
13306
+ */
13307
+ var AttachmentMediaTypeSchema = _enum([
13308
+ "image",
13309
+ "video",
13310
+ "gif",
13311
+ "audio",
13312
+ "icon"
13313
+ ]);
13314
+ /**
13315
+ * A single attachment. Exactly one of `url` (remote source, most adapters
13316
+ * prefer this) or `bytes` (inline source; required for Pushover-style
13317
+ * bytes-only kinds) MUST be present — the degrade engine expresses a
13318
+ * url→bytes fetch as a `needsFetch` directive the adapter executes.
13319
+ */
13320
+ var AttachmentSchema = object({
13321
+ mediaType: AttachmentMediaTypeSchema,
13322
+ url: string().optional(),
13323
+ bytes: _instanceof(Uint8Array).optional(),
13324
+ mime: string().optional(),
13325
+ name: string().optional()
13326
+ }).refine((a) => a.url !== void 0 || a.bytes !== void 0, { message: "Attachment requires either `url` or `bytes`" });
13327
+ var NotificationFormatSchema = _enum([
13328
+ "text",
13329
+ "markdown",
13330
+ "html"
13331
+ ]);
13332
+ /** A single tap-through action button. */
13333
+ var NotificationActionSchema = object({
13334
+ id: string(),
13335
+ label: string(),
13336
+ url: string().optional()
13337
+ });
13338
+ /**
13339
+ * The canonical notification. `body` is the only hard field (Apprise model).
13340
+ * `priority` is a 5-level ORDINAL (1=lowest … 3=normal(default) … 5=urgent),
13341
+ * NOT a fixed severity enum — each kind declares its own `caps.levels` and
13342
+ * the adapter maps this ordinal onto its native level. `level?` is an
13343
+ * optional kind-native level id (`emergency`, `silent`, …) that overrides
13344
+ * `priority` for that one target.
13345
+ */
13346
+ var NotificationSchema = object({
13273
13347
  body: string(),
13274
- imageUrl: string().optional(),
13348
+ title: string().optional(),
13349
+ format: NotificationFormatSchema.default("text"),
13350
+ priority: number().int().min(1).max(5).default(3),
13351
+ level: string().optional(),
13352
+ attachments: array(AttachmentSchema).optional(),
13353
+ clickUrl: string().optional(),
13354
+ actions: array(NotificationActionSchema).optional(),
13355
+ sound: string().optional(),
13356
+ ttl: number().optional(),
13357
+ tag: string().optional(),
13275
13358
  deviceId: number().optional(),
13276
13359
  eventId: string().optional(),
13277
- priority: _enum([
13278
- "low",
13279
- "normal",
13280
- "high",
13281
- "critical"
13282
- ]).default("normal"),
13283
13360
  metadata: record(string(), unknown()).optional()
13284
- }), _void(), { kind: "mutation" }), method(_void(), object({
13361
+ });
13362
+ /** One declared native severity/priority level for a kind. */
13363
+ var TargetKindLevelSchema = object({
13364
+ id: string(),
13365
+ label: string(),
13366
+ /** Which canonical priority (1..5) this level maps to. `null` = qualitative-only. */
13367
+ ordinal: number().int().min(1).max(5).nullable(),
13368
+ flags: object({
13369
+ critical: boolean().optional(),
13370
+ silent: boolean().optional(),
13371
+ noPush: boolean().optional()
13372
+ }).optional(),
13373
+ /** e.g. Pushover `emergency` requires `retry` / `expire`. */
13374
+ requires: array(string()).optional(),
13375
+ description: string().optional()
13376
+ });
13377
+ /** The full capability block consulted before dispatch. */
13378
+ var TargetKindCapsSchema = object({
13379
+ attachments: object({
13380
+ mediaTypes: array(AttachmentMediaTypeSchema),
13381
+ mode: _enum([
13382
+ "url",
13383
+ "bytes",
13384
+ "both"
13385
+ ]),
13386
+ max: number().int().nonnegative(),
13387
+ maxBytes: number().int().positive().optional()
13388
+ }),
13389
+ /** Max action buttons (0 = none). */
13390
+ actions: number().int().nonnegative(),
13391
+ levels: array(TargetKindLevelSchema),
13392
+ format: array(NotificationFormatSchema),
13393
+ clickUrl: boolean(),
13394
+ sound: boolean(),
13395
+ ttl: boolean(),
13396
+ bodyMaxLen: number().int().positive()
13397
+ });
13398
+ /**
13399
+ * `configSchema` is a `ConfigUISchema` tree passed through to the admin
13400
+ * FormBuilder. Stored as `z.unknown()` at the cap seam (mirrors
13401
+ * `device-provider.getChildCreationSchema` `CreationSchemaOutputSchema`) —
13402
+ * the union is large and not meant for runtime validation here; the exported
13403
+ * `TargetKind` type re-tightens `configSchema` to `ConfigUISchema`.
13404
+ */
13405
+ var ConfigSchemaPassthrough = unknown();
13406
+ var TargetKindSchema = object({
13407
+ kind: string(),
13408
+ label: string(),
13409
+ icon: string(),
13410
+ /** Stamped by each provider so the concat-fanned catalog stays routable. */
13411
+ addonId: string(),
13412
+ configSchema: ConfigSchemaPassthrough,
13413
+ supportsDiscovery: boolean(),
13414
+ caps: TargetKindCapsSchema
13415
+ });
13416
+ /**
13417
+ * A persisted target. `config` holds secrets; providers REDACT secret fields
13418
+ * (return a presence marker only) when serving `listTargets` — never
13419
+ * round-trip a stored secret to the UI.
13420
+ */
13421
+ var TargetSchema = object({
13422
+ id: string(),
13423
+ name: string(),
13424
+ kind: string(),
13425
+ addonId: string(),
13426
+ enabled: boolean(),
13427
+ config: record(string(), unknown())
13428
+ });
13429
+ /** A discovery-surfaced candidate (config is partial + non-secret). */
13430
+ var DiscoveredTargetSchema = object({
13431
+ kind: string(),
13432
+ suggestedName: string(),
13433
+ config: record(string(), unknown())
13434
+ });
13435
+ /** The degrade engine's report — what was resolved / dropped / degraded. */
13436
+ var RenderedAsSchema = object({
13437
+ level: string(),
13438
+ format: NotificationFormatSchema,
13439
+ attachmentsSent: number().int().nonnegative(),
13440
+ actionsSent: number().int().nonnegative(),
13441
+ truncated: boolean(),
13442
+ dropped: array(string())
13443
+ });
13444
+ var SendResultSchema = object({
13285
13445
  success: boolean(),
13286
- error: string().optional()
13287
- }), { kind: "mutation" });
13446
+ error: string().optional(),
13447
+ renderedAs: RenderedAsSchema.optional()
13448
+ });
13449
+ /** Same shape as SendResult — kept as a distinct name for the test panel. */
13450
+ var TestResultSchema = SendResultSchema;
13451
+ method(object({}), array(TargetKindSchema)), method(object({}), array(TargetSchema)), method(object({
13452
+ kind: string(),
13453
+ config: record(string(), unknown()).optional()
13454
+ }), array(DiscoveredTargetSchema)), method(object({
13455
+ targetId: string(),
13456
+ notification: NotificationSchema
13457
+ }), SendResultSchema, { kind: "mutation" }), method(object({
13458
+ targetId: string(),
13459
+ sample: NotificationSchema.optional()
13460
+ }), TestResultSchema, { kind: "mutation" }), method(object({ target: TargetSchema }), TargetSchema, { kind: "mutation" }), method(object({ targetId: string() }), _void(), { kind: "mutation" }), method(object({
13461
+ targetId: string(),
13462
+ enabled: boolean()
13463
+ }), _void(), { kind: "mutation" });
13288
13464
  /**
13289
13465
  * Zod schemas for persisted record types.
13290
13466
  *
@@ -19324,13 +19500,49 @@ Object.freeze({
19324
19500
  addonId: null,
19325
19501
  access: "create"
19326
19502
  },
19503
+ "notificationOutput.deleteTarget": {
19504
+ capName: "notification-output",
19505
+ capScope: "system",
19506
+ addonId: null,
19507
+ access: "delete"
19508
+ },
19509
+ "notificationOutput.discoverTargets": {
19510
+ capName: "notification-output",
19511
+ capScope: "system",
19512
+ addonId: null,
19513
+ access: "view"
19514
+ },
19515
+ "notificationOutput.listTargetKinds": {
19516
+ capName: "notification-output",
19517
+ capScope: "system",
19518
+ addonId: null,
19519
+ access: "view"
19520
+ },
19521
+ "notificationOutput.listTargets": {
19522
+ capName: "notification-output",
19523
+ capScope: "system",
19524
+ addonId: null,
19525
+ access: "view"
19526
+ },
19327
19527
  "notificationOutput.send": {
19328
19528
  capName: "notification-output",
19329
19529
  capScope: "system",
19330
19530
  addonId: null,
19331
19531
  access: "create"
19332
19532
  },
19333
- "notificationOutput.sendTest": {
19533
+ "notificationOutput.setTargetEnabled": {
19534
+ capName: "notification-output",
19535
+ capScope: "system",
19536
+ addonId: null,
19537
+ access: "create"
19538
+ },
19539
+ "notificationOutput.testTarget": {
19540
+ capName: "notification-output",
19541
+ capScope: "system",
19542
+ addonId: null,
19543
+ access: "create"
19544
+ },
19545
+ "notificationOutput.upsertTarget": {
19334
19546
  capName: "notification-output",
19335
19547
  capScope: "system",
19336
19548
  addonId: null,
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_shared = require("./shared-a5hRX888.js");
5
+ const require_shared = require("./shared-N5OfEciV.js");
6
6
  let node_stream = require("node:stream");
7
7
  let webdav = require("webdav");
8
8
  //#region src/providers/webdav/webdav-config-schema.ts
@@ -1,4 +1,4 @@
1
- import { a as safeJoinRemotePath, c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, r as getRequiredBasePath, s as storageProviderCapability, t as createSessionId } from "./shared-DwqiKj85.mjs";
1
+ import { a as safeJoinRemotePath, c as BaseAddon, i as rearmIdleAbort, o as scheduleIdleAbort, r as getRequiredBasePath, s as storageProviderCapability, t as createSessionId } from "./shared-D9u4CXu8.mjs";
2
2
  import { PassThrough } from "node:stream";
3
3
  import { AuthType, createClient } from "webdav";
4
4
  //#region src/providers/webdav/webdav-config-schema.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-remote-storage",
3
- "version": "1.1.13",
3
+ "version": "1.1.14",
4
4
  "description": "Remote storage providers (SFTP, S3, WebDAV) — unifies remote backends behind the storage-provider cap",
5
5
  "keywords": [
6
6
  "camstack",
@@ -36,6 +36,9 @@
36
36
  "addons": [
37
37
  {
38
38
  "id": "sftp-storage",
39
+ "execution": {
40
+ "group": "remote-storage"
41
+ },
39
42
  "category": "system",
40
43
  "name": "SFTP Storage",
41
44
  "version": "0.1.1",
@@ -52,6 +55,9 @@
52
55
  },
53
56
  {
54
57
  "id": "s3-storage",
58
+ "execution": {
59
+ "group": "remote-storage"
60
+ },
55
61
  "category": "system",
56
62
  "name": "S3 Storage",
57
63
  "version": "0.1.1",
@@ -68,6 +74,9 @@
68
74
  },
69
75
  {
70
76
  "id": "webdav-storage",
77
+ "execution": {
78
+ "group": "remote-storage"
79
+ },
71
80
  "category": "system",
72
81
  "name": "WebDAV Storage",
73
82
  "version": "0.1.1",