@camstack/core 0.1.12 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  addonTableToDdl
8
8
  } from "./chunk-R3DIIBBX.mjs";
9
9
  import "./chunk-SPA4JBKN.mjs";
10
- import "./chunk-YXNXYYHL.mjs";
10
+ import "./chunk-SMNR44VG.mjs";
11
11
  import {
12
12
  WinstonDestination,
13
13
  WinstonLoggingAddon
@@ -3378,6 +3378,320 @@ var InferenceConfigResolver = class {
3378
3378
  }
3379
3379
  };
3380
3380
 
3381
+ // src/builtins/sqlite-storage/integration-registry.ts
3382
+ function serializeSetting(value) {
3383
+ if (typeof value === "number") return { value: String(value), valueType: "number" };
3384
+ if (typeof value === "boolean") return { value: String(value), valueType: "boolean" };
3385
+ if (typeof value === "string") return { value, valueType: "string" };
3386
+ return { value: JSON.stringify(value), valueType: "json" };
3387
+ }
3388
+ function deserializeSetting(value, valueType) {
3389
+ switch (valueType) {
3390
+ case "number":
3391
+ return Number(value);
3392
+ case "boolean":
3393
+ return value === "true";
3394
+ case "json":
3395
+ try {
3396
+ return JSON.parse(value);
3397
+ } catch {
3398
+ return value;
3399
+ }
3400
+ default:
3401
+ return value;
3402
+ }
3403
+ }
3404
+ var integrationCounter = 0;
3405
+ var deviceCounter = 0;
3406
+ function nextIntegrationId() {
3407
+ return `int_${String(++integrationCounter).padStart(4, "0")}`;
3408
+ }
3409
+ function nextDeviceId() {
3410
+ return `dev_${String(++deviceCounter).padStart(4, "0")}`;
3411
+ }
3412
+ var INTEGRATIONS_SCHEMA = {
3413
+ columns: [
3414
+ { name: "id", type: "TEXT", primaryKey: true },
3415
+ { name: "addon_id", type: "TEXT", notNull: true },
3416
+ { name: "name", type: "TEXT", notNull: true },
3417
+ { name: "enabled", type: "INTEGER", notNull: true, defaultValue: 1 },
3418
+ { name: "info", type: "TEXT", notNull: true, defaultValue: "{}" },
3419
+ { name: "created_at", type: "INTEGER", notNull: true },
3420
+ { name: "updated_at", type: "INTEGER", notNull: true }
3421
+ ],
3422
+ indexes: [
3423
+ { name: "idx_integrations_addon", columns: ["addon_id"] }
3424
+ ]
3425
+ };
3426
+ var INTEGRATION_SETTINGS_SCHEMA = {
3427
+ columns: [
3428
+ { name: "integration_id", type: "TEXT", notNull: true },
3429
+ { name: "key", type: "TEXT", notNull: true },
3430
+ { name: "value", type: "TEXT", notNull: true },
3431
+ { name: "value_type", type: "TEXT", notNull: true, defaultValue: "string" }
3432
+ ]
3433
+ };
3434
+ var DEVICES_SCHEMA = {
3435
+ columns: [
3436
+ { name: "id", type: "TEXT", primaryKey: true },
3437
+ { name: "integration_id", type: "TEXT", notNull: true },
3438
+ { name: "stable_id", type: "TEXT", notNull: true, unique: true },
3439
+ { name: "type", type: "TEXT", notNull: true, defaultValue: "camera" },
3440
+ { name: "name", type: "TEXT", notNull: true },
3441
+ { name: "enabled", type: "INTEGER", notNull: true, defaultValue: 1 },
3442
+ { name: "info", type: "TEXT", notNull: true, defaultValue: "{}" },
3443
+ { name: "created_at", type: "INTEGER", notNull: true },
3444
+ { name: "updated_at", type: "INTEGER", notNull: true }
3445
+ ],
3446
+ indexes: [
3447
+ { name: "idx_devices_integration", columns: ["integration_id"] },
3448
+ { name: "idx_devices_stable", columns: ["stable_id"], unique: true },
3449
+ { name: "idx_devices_type", columns: ["type"] }
3450
+ ]
3451
+ };
3452
+ var DEVICE_SETTINGS_SCHEMA = {
3453
+ columns: [
3454
+ { name: "device_id", type: "TEXT", notNull: true },
3455
+ { name: "key", type: "TEXT", notNull: true },
3456
+ { name: "value", type: "TEXT", notNull: true },
3457
+ { name: "value_type", type: "TEXT", notNull: true, defaultValue: "string" }
3458
+ ]
3459
+ };
3460
+ var IntegrationRegistry = class {
3461
+ backend;
3462
+ constructor(backend) {
3463
+ this.backend = backend;
3464
+ }
3465
+ async initialize() {
3466
+ await this.backend.ensureTable?.("integrations", INTEGRATIONS_SCHEMA);
3467
+ await this.backend.ensureTable?.("integration_settings", INTEGRATION_SETTINGS_SCHEMA);
3468
+ await this.backend.ensureTable?.("devices", DEVICES_SCHEMA);
3469
+ await this.backend.ensureTable?.("device_settings_kv", DEVICE_SETTINGS_SCHEMA);
3470
+ const ints = await this.backend.tableQuery?.("integrations", { orderBy: { field: "id", direction: "desc" }, limit: 1 }) ?? [];
3471
+ if (ints[0]) {
3472
+ const num = parseInt(String(ints[0]["id"]).replace("int_", ""), 10);
3473
+ if (!isNaN(num)) integrationCounter = num;
3474
+ }
3475
+ const devs = await this.backend.tableQuery?.("devices", { orderBy: { field: "id", direction: "desc" }, limit: 1 }) ?? [];
3476
+ if (devs[0]) {
3477
+ const num = parseInt(String(devs[0]["id"]).replace("dev_", ""), 10);
3478
+ if (!isNaN(num)) deviceCounter = num;
3479
+ }
3480
+ }
3481
+ // --- Integrations ---
3482
+ createIntegration(input) {
3483
+ const id = nextIntegrationId();
3484
+ const now = Math.floor(Date.now() / 1e3);
3485
+ void this.backend.tableInsert?.("integrations", {
3486
+ id,
3487
+ addon_id: input.addonId,
3488
+ name: input.name,
3489
+ enabled: input.enabled !== false ? 1 : 0,
3490
+ info: JSON.stringify(input.info ?? {}),
3491
+ created_at: now,
3492
+ updated_at: now
3493
+ });
3494
+ if (input.settings) {
3495
+ this.setIntegrationSettings(id, input.settings);
3496
+ }
3497
+ return {
3498
+ id,
3499
+ addonId: input.addonId,
3500
+ name: input.name,
3501
+ enabled: input.enabled !== false,
3502
+ info: input.info ?? {},
3503
+ createdAt: now,
3504
+ updatedAt: now
3505
+ };
3506
+ }
3507
+ getIntegration(id) {
3508
+ let result = null;
3509
+ void this.backend.tableGet?.("integrations", { id }).then((row) => {
3510
+ if (row) result = this.mapIntegration(row);
3511
+ });
3512
+ return result;
3513
+ }
3514
+ getIntegrationByAddonId(addonId) {
3515
+ let result = null;
3516
+ void this.backend.tableGet?.("integrations", { addon_id: addonId }).then((row) => {
3517
+ if (row) result = this.mapIntegration(row);
3518
+ });
3519
+ return result;
3520
+ }
3521
+ listIntegrations() {
3522
+ let result = [];
3523
+ void this.backend.tableQuery?.("integrations", { orderBy: { field: "created_at", direction: "asc" } }).then((rows) => {
3524
+ result = rows.map((r) => this.mapIntegration(r));
3525
+ });
3526
+ return result;
3527
+ }
3528
+ updateIntegration(id, updates) {
3529
+ const updateRow = { updated_at: Math.floor(Date.now() / 1e3) };
3530
+ if (updates.name !== void 0) updateRow["name"] = updates.name;
3531
+ if (updates.enabled !== void 0) updateRow["enabled"] = updates.enabled ? 1 : 0;
3532
+ if (updates.info !== void 0) updateRow["info"] = JSON.stringify(updates.info);
3533
+ void this.backend.tableUpdate?.("integrations", { id }, updateRow);
3534
+ return this.getIntegration(id);
3535
+ }
3536
+ deleteIntegration(id) {
3537
+ const devices = this.listDevices(id);
3538
+ for (const d of devices) {
3539
+ void this.backend.tableDelete?.("device_settings_kv", { device_id: d.id });
3540
+ }
3541
+ void this.backend.tableDelete?.("devices", { integration_id: id });
3542
+ void this.backend.tableDelete?.("integration_settings", { integration_id: id });
3543
+ void this.backend.tableDelete?.("integrations", { id });
3544
+ return true;
3545
+ }
3546
+ // --- Integration Settings ---
3547
+ getIntegrationSettings(integrationId) {
3548
+ const result = {};
3549
+ void this.backend.tableQuery?.("integration_settings", { where: { integration_id: integrationId } }).then((rows) => {
3550
+ for (const row of rows) {
3551
+ result[String(row["key"])] = deserializeSetting(String(row["value"]), String(row["value_type"]));
3552
+ }
3553
+ });
3554
+ return result;
3555
+ }
3556
+ setIntegrationSetting(integrationId, key, value) {
3557
+ const s = serializeSetting(value);
3558
+ void this.backend.tableDelete?.("integration_settings", { integration_id: integrationId, key });
3559
+ void this.backend.tableInsert?.("integration_settings", {
3560
+ integration_id: integrationId,
3561
+ key,
3562
+ value: s.value,
3563
+ value_type: s.valueType
3564
+ });
3565
+ }
3566
+ setIntegrationSettings(integrationId, settings) {
3567
+ for (const [key, value] of Object.entries(settings)) {
3568
+ this.setIntegrationSetting(integrationId, key, value);
3569
+ }
3570
+ }
3571
+ // --- Devices ---
3572
+ createDevice(input) {
3573
+ const id = nextDeviceId();
3574
+ const now = Math.floor(Date.now() / 1e3);
3575
+ void this.backend.tableInsert?.("devices", {
3576
+ id,
3577
+ integration_id: input.integrationId,
3578
+ stable_id: input.stableId,
3579
+ type: input.type,
3580
+ name: input.name,
3581
+ enabled: input.enabled !== false ? 1 : 0,
3582
+ info: JSON.stringify(input.info ?? {}),
3583
+ created_at: now,
3584
+ updated_at: now
3585
+ });
3586
+ if (input.settings) {
3587
+ this.setDeviceSettings(id, input.settings);
3588
+ }
3589
+ return {
3590
+ id,
3591
+ integrationId: input.integrationId,
3592
+ stableId: input.stableId,
3593
+ type: input.type,
3594
+ name: input.name,
3595
+ enabled: input.enabled !== false,
3596
+ info: input.info ?? {},
3597
+ createdAt: now,
3598
+ updatedAt: now
3599
+ };
3600
+ }
3601
+ getDevice(id) {
3602
+ let result = null;
3603
+ void this.backend.tableGet?.("devices", { id }).then((row) => {
3604
+ if (row) result = this.mapDevice(row);
3605
+ });
3606
+ return result;
3607
+ }
3608
+ getDeviceByStableId(stableId) {
3609
+ let result = null;
3610
+ void this.backend.tableGet?.("devices", { stable_id: stableId }).then((row) => {
3611
+ if (row) result = this.mapDevice(row);
3612
+ });
3613
+ return result;
3614
+ }
3615
+ listDevices(integrationId) {
3616
+ let result = [];
3617
+ const options = integrationId ? { where: { integration_id: integrationId }, orderBy: { field: "created_at", direction: "asc" } } : { orderBy: { field: "created_at", direction: "asc" } };
3618
+ void this.backend.tableQuery?.("devices", options).then((rows) => {
3619
+ result = rows.map((r) => this.mapDevice(r));
3620
+ });
3621
+ return result;
3622
+ }
3623
+ listCameras() {
3624
+ let result = [];
3625
+ void this.backend.tableQuery?.("devices", { where: { type: "camera" }, orderBy: { field: "created_at", direction: "asc" } }).then((rows) => {
3626
+ result = rows.map((r) => this.mapDevice(r));
3627
+ });
3628
+ return result;
3629
+ }
3630
+ updateDevice(id, updates) {
3631
+ const updateRow = { updated_at: Math.floor(Date.now() / 1e3) };
3632
+ if (updates.name !== void 0) updateRow["name"] = updates.name;
3633
+ if (updates.enabled !== void 0) updateRow["enabled"] = updates.enabled ? 1 : 0;
3634
+ if (updates.info !== void 0) updateRow["info"] = JSON.stringify(updates.info);
3635
+ void this.backend.tableUpdate?.("devices", { id }, updateRow);
3636
+ return this.getDevice(id);
3637
+ }
3638
+ deleteDevice(id) {
3639
+ void this.backend.tableDelete?.("device_settings_kv", { device_id: id });
3640
+ void this.backend.tableDelete?.("devices", { id });
3641
+ return true;
3642
+ }
3643
+ // --- Device Settings ---
3644
+ getDeviceSettings(deviceId) {
3645
+ const result = {};
3646
+ void this.backend.tableQuery?.("device_settings_kv", { where: { device_id: deviceId } }).then((rows) => {
3647
+ for (const row of rows) {
3648
+ result[String(row["key"])] = deserializeSetting(String(row["value"]), String(row["value_type"]));
3649
+ }
3650
+ });
3651
+ return result;
3652
+ }
3653
+ setDeviceSetting(deviceId, key, value) {
3654
+ const s = serializeSetting(value);
3655
+ void this.backend.tableDelete?.("device_settings_kv", { device_id: deviceId, key });
3656
+ void this.backend.tableInsert?.("device_settings_kv", {
3657
+ device_id: deviceId,
3658
+ key,
3659
+ value: s.value,
3660
+ value_type: s.valueType
3661
+ });
3662
+ }
3663
+ setDeviceSettings(deviceId, settings) {
3664
+ for (const [key, value] of Object.entries(settings)) {
3665
+ this.setDeviceSetting(deviceId, key, value);
3666
+ }
3667
+ }
3668
+ // --- Mappers ---
3669
+ mapIntegration(row) {
3670
+ return {
3671
+ id: String(row["id"]),
3672
+ addonId: String(row["addon_id"]),
3673
+ name: String(row["name"]),
3674
+ enabled: row["enabled"] === 1,
3675
+ info: typeof row["info"] === "string" ? JSON.parse(row["info"]) : {},
3676
+ createdAt: Number(row["created_at"]),
3677
+ updatedAt: Number(row["updated_at"])
3678
+ };
3679
+ }
3680
+ mapDevice(row) {
3681
+ return {
3682
+ id: String(row["id"]),
3683
+ integrationId: String(row["integration_id"]),
3684
+ stableId: String(row["stable_id"]),
3685
+ type: String(row["type"]),
3686
+ name: String(row["name"]),
3687
+ enabled: row["enabled"] === 1,
3688
+ info: typeof row["info"] === "string" ? JSON.parse(row["info"]) : {},
3689
+ createdAt: Number(row["created_at"]),
3690
+ updatedAt: Number(row["updated_at"])
3691
+ };
3692
+ }
3693
+ };
3694
+
3381
3695
  // src/provider/provider-manager.ts
3382
3696
  import { randomUUID as randomUUID7 } from "crypto";
3383
3697
  var ProviderManager = class {
@@ -3532,6 +3846,7 @@ export {
3532
3846
  FileSystemStorage,
3533
3847
  FsStorageBackend,
3534
3848
  InferenceConfigResolver,
3849
+ IntegrationRegistry,
3535
3850
  LifecycleStateMachine,
3536
3851
  LocalBackupAddon,
3537
3852
  LocalBackupService,