@camstack/system 1.2.461 → 1.2.462

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 (104) hide show
  1. package/dist/addon-runner.js +21 -276
  2. package/dist/addon-runner.mjs +21 -276
  3. package/dist/{agent-https-Dnr_nIVx.js → agent-https-C6M6apPV.js} +1 -1
  4. package/dist/{agent-https-Iw3RSQup.mjs → agent-https-CC7jpktS.mjs} +1 -1
  5. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  9. package/dist/builtins/alerts/alerts.addon.js +1 -1
  10. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  11. package/dist/builtins/autotrack/index.js +1 -1
  12. package/dist/builtins/autotrack/index.mjs +1 -1
  13. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +1 -3
  14. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +51 -502
  15. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +51 -502
  16. package/dist/builtins/backup-orchestrator/destination-policy.d.ts +5 -21
  17. package/dist/builtins/backup-orchestrator/record-kinds.d.ts +0 -2
  18. package/dist/builtins/backup-orchestrator/schedule-store.d.ts +5 -13
  19. package/dist/builtins/backup-orchestrator/seed-marker-store.d.ts +9 -19
  20. package/dist/builtins/calendars/calendars.addon.js +1 -1
  21. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  22. package/dist/builtins/camera-grid/index.js +1 -1
  23. package/dist/builtins/camera-grid/index.mjs +1 -1
  24. package/dist/builtins/cluster-agent/record-kinds.d.ts +0 -1
  25. package/dist/builtins/composer/composer.addon.js +2 -2
  26. package/dist/builtins/composer/composer.addon.mjs +2 -2
  27. package/dist/builtins/console-logging/index.js +1 -1
  28. package/dist/builtins/console-logging/index.mjs +1 -1
  29. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  30. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  31. package/dist/builtins/device-history/device-history.addon.js +1 -1
  32. package/dist/builtins/device-history/device-history.addon.mjs +1 -1
  33. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  34. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  35. package/dist/builtins/hub-forwarder/index.js +1 -1
  36. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  37. package/dist/builtins/keychain/index.js +3 -3
  38. package/dist/builtins/keychain/index.mjs +3 -3
  39. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  40. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  41. package/dist/builtins/local-auth/auth-schema.d.ts +2 -12
  42. package/dist/builtins/local-auth/local-auth.addon.js +52 -191
  43. package/dist/builtins/local-auth/local-auth.addon.mjs +52 -191
  44. package/dist/builtins/local-auth/oauth-session-manager.d.ts +13 -4
  45. package/dist/builtins/local-auth/record-kinds.d.ts +1 -1
  46. package/dist/builtins/local-network/local-network.addon.js +2 -2
  47. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  48. package/dist/builtins/loki-logging/index.js +1 -1
  49. package/dist/builtins/loki-logging/index.mjs +1 -1
  50. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  51. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  52. package/dist/builtins/platform-probe/index.js +1 -1
  53. package/dist/builtins/platform-probe/index.mjs +1 -1
  54. package/dist/builtins/record-entries/index.js +1 -1
  55. package/dist/builtins/record-entries/index.mjs +1 -1
  56. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  57. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  58. package/dist/builtins/snapshot/index.js +1 -1
  59. package/dist/builtins/snapshot/index.mjs +1 -1
  60. package/dist/builtins/sqlite-storage/file-host-protocol.d.ts +0 -9
  61. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  62. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  63. package/dist/builtins/sqlite-storage/index.js +1 -1
  64. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  65. package/dist/builtins/sqlite-storage/owned-sqlite-file.d.ts +0 -8
  66. package/dist/builtins/sqlite-storage/records/records-sql.d.ts +0 -2
  67. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +0 -28
  68. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +1 -2
  69. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +6 -170
  70. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +6 -170
  71. package/dist/builtins/sqlite-storage/storage-admin-provider.d.ts +3 -17
  72. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  73. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  74. package/dist/builtins/system-config/system-config.addon.js +3 -3
  75. package/dist/builtins/system-config/system-config.addon.mjs +280 -280
  76. package/dist/builtins/winston-logging/index.js +1 -1
  77. package/dist/builtins/winston-logging/index.mjs +1 -1
  78. package/dist/{composition-sources-b0e_2I-D.js → composition-sources-BPnpB9XG.js} +1 -1
  79. package/dist/{composition-sources-DNRZWR1j.mjs → composition-sources-BlcYzFwY.mjs} +1 -1
  80. package/dist/{constants-6OeJiZgi.js → constants-7ZMxWr8Z.js} +1 -1
  81. package/dist/{constants-BnkOdj9Q.mjs → constants-CH5UXe_G.mjs} +1 -1
  82. package/dist/{device-ca-Bnkw8GyU.mjs → device-ca-BU_gnd-q.mjs} +1 -1
  83. package/dist/{device-ca-CPTDs--d.js → device-ca-CUEx7sti.js} +1 -1
  84. package/dist/{dist-Wy8cTxg6.mjs → dist-8tWIDoWp.mjs} +15 -55
  85. package/dist/{dist-Bn-RNanh.js → dist-Ct-4tTeX.js} +14 -66
  86. package/dist/file-host-worker.js +1 -1
  87. package/dist/file-host-worker.mjs +1 -1
  88. package/dist/{hub-mdns-ciao-CJu0nhla.mjs → hub-mdns-ciao-Cuy7LUdz.mjs} +2 -2
  89. package/dist/{hub-mdns-ciao-CTBTlia4.js → hub-mdns-ciao-DJ-Amqd7.js} +2 -2
  90. package/dist/index.d.ts +1 -1
  91. package/dist/index.js +88 -240
  92. package/dist/index.mjs +89 -236
  93. package/dist/kernel/index.d.ts +0 -1
  94. package/dist/kernel/moleculer/runner-addon-settings.d.ts +1 -6
  95. package/dist/kernel/moleculer/runner-device-settings.d.ts +2 -2
  96. package/dist/{restore-archive-CM23Pq9B.mjs → restore-archive-BDua3jO6.mjs} +78 -78
  97. package/dist/{restore-archive-DM1OBYq4.js → restore-archive-HwOA83v3.js} +1 -1
  98. package/dist/{retired-settings-keys-D_VwZiDt.js → retired-settings-keys-CGUqX-Oz.js} +0 -6
  99. package/dist/{retired-settings-keys-Bhwe4ymb.mjs → retired-settings-keys-C_Kjp-Bj.mjs} +1 -1
  100. package/dist/{wal-maintenance-Bj_MmDkr.mjs → wal-maintenance-BvzVehem.mjs} +0 -0
  101. package/dist/{wal-maintenance-CaJjuLHq.js → wal-maintenance-DBvuVU9s.js} +0 -0
  102. package/package.json +1 -1
  103. package/dist/builtins/sqlite-storage/retired-collections.d.ts +0 -146
  104. package/dist/kernel/legacy-blob-guard.d.ts +0 -63
@@ -1,6 +1,6 @@
1
- import { Dt as backupCapability, Or as storageOccupancyCapability, Ta as EventCategory, Un as mayWriteToLocation, ba as toNodeId, ni as BaseAddon, oa as nodePin } from "../../dist-Wy8cTxg6.mjs";
1
+ import { Ca as EventCategory, Er as storageOccupancyCapability, Tt as backupCapability, Vn as mayWriteToLocation, ei as BaseAddon, ia as nodePin, va as toNodeId } from "../../dist-8tWIDoWp.mjs";
2
2
  import { t as require_read_all_rows } from "../../read-all-rows-TaPqdWNF.mjs";
3
- import { _ as backupRecordStoresOf, a as BackupSnapshotRefusedError, d as ENCRYPTED_BACKUP_SUFFIX, f as generateBackupKeyPair, g as backupOrchestratorRecordKinds, i as BackupCancelledError, l as BackupKeyFormatError, m as parseBackupSecretKey, n as precheckRestoreKey, o as DEFAULT_BACKUP_DATABASES, p as parseBackupPublicKey, r as prepareRestoreArchive, s as SystemBackupService } from "../../restore-archive-CM23Pq9B.mjs";
3
+ import { _ as backupRecordStoresOf, a as BackupSnapshotRefusedError, d as ENCRYPTED_BACKUP_SUFFIX, f as generateBackupKeyPair, g as backupOrchestratorRecordKinds, i as BackupCancelledError, l as BackupKeyFormatError, m as parseBackupSecretKey, n as precheckRestoreKey, o as DEFAULT_BACKUP_DATABASES, p as parseBackupPublicKey, r as prepareRestoreArchive, s as SystemBackupService } from "../../restore-archive-BDua3jO6.mjs";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import * as fsp from "node:fs/promises";
6
6
  import * as path$1 from "node:path";
@@ -79,75 +79,26 @@ async function seedWeeklySchedule(store, markers) {
79
79
  //#endregion
80
80
  //#region src/builtins/backup-orchestrator/seed-marker-store.ts
81
81
  /**
82
- * @durable class=config owner=backup-orchestrator
83
- * write="the orchestrator inserts one row per seed id the first time that
84
- * seed is created (or found already created); never updated"
85
- * retention="none — one tiny row per seed ever made; deleting it lets the
86
- * seed be re-created once more on the next boot"
82
+ * One `seed-markers` row per seed id (D902: no `backup_seed_markers` table).
83
+ * Written once, never updated; deleting one lets that seed run once more.
87
84
  */
88
- var BACKUP_SEED_MARKERS_COLLECTION = "backup_seed_markers";
89
- var COLUMNS$1 = [{
90
- name: "seed_id",
91
- type: "TEXT",
92
- primaryKey: true
93
- }, {
94
- name: "seeded_at",
95
- type: "INTEGER",
96
- notNull: true
97
- }];
98
85
  var BackupSeedMarkerStore = class {
99
- store;
100
- now;
101
- declared = false;
102
86
  markersKind;
103
- constructor(store, now = Date.now, markersKind = null) {
104
- this.store = store;
105
- this.now = now;
87
+ now;
88
+ constructor(markersKind, now = Date.now) {
106
89
  this.markersKind = markersKind;
107
- }
108
- async ensureDeclared() {
109
- if (this.markersKind !== null) return;
110
- if (this.declared) return;
111
- await this.store.declareCollection({
112
- collection: BACKUP_SEED_MARKERS_COLLECTION,
113
- columns: COLUMNS$1
114
- });
115
- this.declared = true;
90
+ this.now = now;
116
91
  }
117
92
  async has(seedId) {
118
- await this.ensureDeclared();
119
- const kind = this.markersKind;
120
- if (kind !== null) return await kind.get(seedId) !== null;
121
- return (await this.store.query({
122
- collection: BACKUP_SEED_MARKERS_COLLECTION,
123
- filter: {
124
- where: { seed_id: seedId },
125
- limit: 1
126
- }
127
- })).length > 0;
93
+ return await this.markersKind.get(seedId) !== null;
128
94
  }
129
95
  async mark(seedId) {
130
- await this.ensureDeclared();
131
96
  if (await this.has(seedId)) return;
132
- const kind = this.markersKind;
133
- if (kind !== null) {
134
- const body = { seededAt: this.now() };
135
- const data = backupOrchestratorRecordKinds["seed-markers"].schema.parse(body);
136
- await kind.put({
137
- id: seedId,
138
- data
139
- });
140
- return;
141
- }
142
- await this.store.insert({
143
- collection: BACKUP_SEED_MARKERS_COLLECTION,
144
- record: {
145
- id: seedId,
146
- data: {
147
- seed_id: seedId,
148
- seeded_at: this.now()
149
- }
150
- }
97
+ const body = { seededAt: this.now() };
98
+ const data = backupOrchestratorRecordKinds["seed-markers"].schema.parse(body);
99
+ await this.markersKind.put({
100
+ id: seedId,
101
+ data
151
102
  });
152
103
  }
153
104
  };
@@ -947,165 +898,35 @@ function previewNextRuns(cron, count, after) {
947
898
  //#endregion
948
899
  //#region src/builtins/backup-orchestrator/destination-policy.ts
949
900
  var import_read_all_rows = require_read_all_rows();
950
- /**
951
- * @durable class=config owner=backup-orchestrator
952
- * write="`ensureDefault` auto-creates one row the first time a `backups` storage
953
- * location is listed (enabled, retentionCount 7, no cadence of its own), an operator
954
- * edit rewrites it (`upsert` = delete + insert, carrying `last_run_at` forward so a
955
- * label change does not reset the baseline), and `recordAttempt` stamps
956
- * `last_run_at` + `last_error` on every attempted write to the destination"
957
- * retention="none — `delete(locationId)` exists but NOTHING calls it, so a policy row
958
- * outlives the `StorageLocation` it names and the table only ever grows, by one row
959
- * per backups location ever seen. Losing a row is recoverable: the next
960
- * `listDestinations` pass re-creates it from the defaults, which silently discards
961
- * the operator's own retention count. The legacy `cron` column is written NULL and
962
- * never read — it scheduled nothing after 2026-07-28 and reading it made a
963
- * destination advertise a nightly run nobody performed (D384)."
964
- */
965
- var BACKUP_DESTINATION_POLICIES = "backup_destination_policies";
966
- var BACKUP_DESTINATION_POLICIES_COLUMNS = [
967
- {
968
- name: "location_id",
969
- type: "TEXT",
970
- primaryKey: true
971
- },
972
- {
973
- name: "enabled",
974
- type: "INTEGER",
975
- notNull: true,
976
- defaultValue: 1
977
- },
978
- {
979
- name: "retention_count",
980
- type: "INTEGER",
981
- notNull: true,
982
- defaultValue: 7
983
- },
984
- {
985
- name: "label",
986
- type: "TEXT"
987
- },
988
- {
989
- name: "cron",
990
- type: "TEXT"
991
- },
992
- {
993
- name: "last_run_at",
994
- type: "INTEGER"
995
- },
996
- {
997
- name: "last_error",
998
- type: "TEXT"
999
- }
1000
- ];
1001
901
  var BackupDestinationPolicyService = class {
1002
- store;
1003
- declared = false;
1004
902
  policiesKind;
1005
- constructor(store, policiesKind = null) {
1006
- this.store = store;
903
+ constructor(policiesKind) {
1007
904
  this.policiesKind = policiesKind;
1008
905
  }
1009
- /**
1010
- * Lazy `declareCollection` — called from every read/write path.
1011
- * `declareCollection` is idempotent, so repeated calls collapse to a no-op
1012
- * after the first. This keeps the constructor synchronous and avoids a
1013
- * separate `initialize()` step that callers could forget.
1014
- */
1015
- async initialize() {
1016
- await this.ensureDeclared();
1017
- }
1018
- async ensureDeclared() {
1019
- if (this.policiesKind !== null) return;
1020
- if (this.declared) return;
1021
- await this.store.declareCollection({
1022
- collection: BACKUP_DESTINATION_POLICIES,
1023
- columns: BACKUP_DESTINATION_POLICIES_COLUMNS
1024
- });
1025
- this.declared = true;
1026
- }
1027
906
  async list() {
1028
- await this.ensureDeclared();
1029
- const kind = this.policiesKind;
1030
- if (kind !== null) {
1031
- const rows = await (0, import_read_all_rows.readAllRows)(kind);
1032
- rows.sort((a, b) => a.id.localeCompare(b.id));
1033
- const out = [];
1034
- for (const row of rows) {
1035
- const mapped = bodyToPolicy(row.id, row.data);
1036
- if (mapped) out.push(mapped);
1037
- }
1038
- return out;
1039
- }
1040
- const rows = await this.store.query({
1041
- collection: BACKUP_DESTINATION_POLICIES,
1042
- filter: { orderBy: {
1043
- field: "location_id",
1044
- direction: "asc"
1045
- } }
1046
- });
907
+ const rows = await (0, import_read_all_rows.readAllRows)(this.policiesKind);
908
+ rows.sort((a, b) => a.id.localeCompare(b.id));
1047
909
  const out = [];
1048
910
  for (const row of rows) {
1049
- const mapped = mapRowToPolicy(row.data);
911
+ const mapped = bodyToPolicy(row.id, row.data);
1050
912
  if (mapped) out.push(mapped);
1051
913
  }
1052
914
  return out;
1053
915
  }
1054
916
  async get(locationId) {
1055
- await this.ensureDeclared();
1056
- const kind = this.policiesKind;
1057
- if (kind !== null) {
1058
- const row = await kind.get(locationId);
1059
- return row === null ? null : bodyToPolicy(locationId, row.data);
1060
- }
1061
- const rows = await this.store.query({
1062
- collection: BACKUP_DESTINATION_POLICIES,
1063
- filter: {
1064
- where: { location_id: locationId },
1065
- limit: 1
1066
- }
1067
- });
1068
- return rows[0] ? mapRowToPolicy(rows[0].data) : null;
917
+ const row = await this.policiesKind.get(locationId);
918
+ return row === null ? null : bodyToPolicy(locationId, row.data);
1069
919
  }
1070
- /**
1071
- * Replace-or-insert. Implemented as delete + insert, mirroring the
1072
- * `SqliteLocationStore` contract.
1073
- */
920
+ /** Replace-or-insert: one full `put` of the row. */
1074
921
  async upsert(p) {
1075
- await this.ensureDeclared();
1076
- const kind = this.policiesKind;
1077
- if (kind !== null) {
1078
- const body = policyToBody(p);
1079
- const data = backupOrchestratorRecordKinds["destination-policies"].schema.parse(body);
1080
- await kind.put({
1081
- id: p.locationId,
1082
- data
1083
- });
1084
- return;
1085
- }
1086
- await this.store.deleteWhere({
1087
- collection: BACKUP_DESTINATION_POLICIES,
1088
- filter: { where: { location_id: p.locationId } }
1089
- });
1090
- await this.store.insert({
1091
- collection: BACKUP_DESTINATION_POLICIES,
1092
- record: {
1093
- id: p.locationId,
1094
- data: mapPolicyToRow(p)
1095
- }
922
+ const data = backupOrchestratorRecordKinds["destination-policies"].schema.parse(policyToBody(p));
923
+ await this.policiesKind.put({
924
+ id: p.locationId,
925
+ data
1096
926
  });
1097
927
  }
1098
928
  async delete(locationId) {
1099
- await this.ensureDeclared();
1100
- const kind = this.policiesKind;
1101
- if (kind !== null) {
1102
- await kind.delete(locationId);
1103
- return;
1104
- }
1105
- await this.store.deleteWhere({
1106
- collection: BACKUP_DESTINATION_POLICIES,
1107
- filter: { where: { location_id: locationId } }
1108
- });
929
+ await this.policiesKind.delete(locationId);
1109
930
  }
1110
931
  /**
1111
932
  * Auto-create a default policy for a `backups` location seen for the
@@ -1173,41 +994,6 @@ function bodyToPolicy(locationId, body) {
1173
994
  ...body.lastError !== void 0 ? { lastError: body.lastError } : {}
1174
995
  };
1175
996
  }
1176
- function mapPolicyToRow(p) {
1177
- return {
1178
- location_id: p.locationId,
1179
- enabled: p.enabled ? 1 : 0,
1180
- retention_count: p.retentionCount,
1181
- label: p.label ?? null,
1182
- cron: null,
1183
- last_run_at: p.lastAttemptAt ?? null,
1184
- last_error: p.lastError ?? null
1185
- };
1186
- }
1187
- /**
1188
- * Decode a row pulled from the structured table. Defensive against
1189
- * schema drift / partial migrations: returns `null` on missing
1190
- * `location_id` so corrupt rows skip the result list rather than
1191
- * throwing the whole orchestrator down at boot.
1192
- */
1193
- function mapRowToPolicy(row) {
1194
- const locationId = String(row["location_id"] ?? "");
1195
- if (!locationId) return null;
1196
- const labelRaw = row["label"];
1197
- const label = typeof labelRaw === "string" && labelRaw.length > 0 ? labelRaw : void 0;
1198
- const lastRunRaw = row["last_run_at"];
1199
- const lastAttemptAt = typeof lastRunRaw === "number" && lastRunRaw > 0 ? lastRunRaw : void 0;
1200
- const lastErrorRaw = row["last_error"];
1201
- const lastError = typeof lastErrorRaw === "string" && lastErrorRaw.length > 0 ? lastErrorRaw : void 0;
1202
- return {
1203
- locationId,
1204
- enabled: row["enabled"] === 1 || row["enabled"] === true,
1205
- retentionCount: Number(row["retention_count"] ?? 0),
1206
- ...label !== void 0 ? { label } : {},
1207
- ...lastAttemptAt !== void 0 ? { lastAttemptAt } : {},
1208
- ...lastError !== void 0 ? { lastError } : {}
1209
- };
1210
- }
1211
997
  //#endregion
1212
998
  //#region src/builtins/backup-orchestrator/download-helpers.ts
1213
999
  /**
@@ -1900,176 +1686,35 @@ function requestSignature(request) {
1900
1686
  }
1901
1687
  //#endregion
1902
1688
  //#region src/builtins/backup-orchestrator/schedule-store.ts
1903
- /**
1904
- * @durable class=config owner=backup-orchestrator
1905
- * write="an operator creating or editing a schedule (`upsert`, implemented as
1906
- * delete + insert: cron, enabled, the fan-out `location_ids`, `retention_count`,
1907
- * optional `data_sources`), plus a `last_run_at` stamp the orchestrator writes on
1908
- * every due tick BEFORE the archive runs, so an upload outliving the tick cannot
1909
- * fire the same schedule twice, and a `last_success_at` / `last_error` pair it
1910
- * writes AFTER the run resolves"
1911
- * retention="only the operator's `delete(id)` — no sweep, no expiry, and `retention_count`
1912
- * bounds the ARCHIVES at the destination, never these rows. Losing the table stops
1913
- * every scheduled backup silently: no cron remains to fire, and the fan-out sets and
1914
- * retention counts are gone with it."
1915
- */
1916
- var BACKUP_SCHEDULES = "backup_schedules";
1917
- var BACKUP_SCHEDULES_COLUMNS = [
1918
- {
1919
- name: "id",
1920
- type: "TEXT",
1921
- primaryKey: true
1922
- },
1923
- {
1924
- name: "label",
1925
- type: "TEXT",
1926
- notNull: true,
1927
- defaultValue: ""
1928
- },
1929
- {
1930
- name: "cron",
1931
- type: "TEXT",
1932
- notNull: true,
1933
- defaultValue: ""
1934
- },
1935
- {
1936
- name: "enabled",
1937
- type: "INTEGER",
1938
- notNull: true,
1939
- defaultValue: 1
1940
- },
1941
- {
1942
- name: "location_ids",
1943
- type: "JSON",
1944
- notNull: true,
1945
- defaultValue: "[]"
1946
- },
1947
- {
1948
- name: "retention_count",
1949
- type: "INTEGER",
1950
- notNull: true,
1951
- defaultValue: 7
1952
- },
1953
- {
1954
- name: "data_sources",
1955
- type: "JSON"
1956
- },
1957
- {
1958
- name: "databases",
1959
- type: "JSON"
1960
- },
1961
- {
1962
- name: "last_run_at",
1963
- type: "INTEGER"
1964
- },
1965
- {
1966
- name: "last_success_at",
1967
- type: "INTEGER"
1968
- },
1969
- {
1970
- name: "last_error",
1971
- type: "TEXT"
1972
- }
1973
- ];
1974
1689
  var BackupScheduleService = class {
1975
- store;
1976
- declared = false;
1977
1690
  schedulesKind;
1978
- constructor(store, schedulesKind = null) {
1979
- this.store = store;
1691
+ constructor(schedulesKind) {
1980
1692
  this.schedulesKind = schedulesKind;
1981
1693
  }
1982
- async initialize() {
1983
- await this.ensureDeclared();
1984
- }
1985
- async ensureDeclared() {
1986
- if (this.schedulesKind !== null) return;
1987
- if (this.declared) return;
1988
- await this.store.declareCollection({
1989
- collection: BACKUP_SCHEDULES,
1990
- columns: BACKUP_SCHEDULES_COLUMNS
1991
- });
1992
- this.declared = true;
1993
- }
1994
1694
  async list() {
1995
- await this.ensureDeclared();
1996
- const kind = this.schedulesKind;
1997
- if (kind !== null) {
1998
- const rows = await (0, import_read_all_rows.readAllRows)(kind);
1999
- rows.sort((a, b) => a.id.localeCompare(b.id));
2000
- const out = [];
2001
- for (const row of rows) {
2002
- const mapped = bodyToSchedule(row.id, row.data);
2003
- if (mapped) out.push(mapped);
2004
- }
2005
- return out;
2006
- }
2007
- const rows = await this.store.query({
2008
- collection: BACKUP_SCHEDULES,
2009
- filter: { orderBy: {
2010
- field: "id",
2011
- direction: "asc"
2012
- } }
2013
- });
1695
+ const rows = await (0, import_read_all_rows.readAllRows)(this.schedulesKind);
1696
+ rows.sort((a, b) => a.id.localeCompare(b.id));
2014
1697
  const out = [];
2015
1698
  for (const row of rows) {
2016
- const mapped = mapRowToSchedule(row.data);
1699
+ const mapped = bodyToSchedule(row.id, row.data);
2017
1700
  if (mapped) out.push(mapped);
2018
1701
  }
2019
1702
  return out;
2020
1703
  }
2021
1704
  async get(id) {
2022
- await this.ensureDeclared();
2023
- const kind = this.schedulesKind;
2024
- if (kind !== null) {
2025
- const row = await kind.get(id);
2026
- return row === null ? null : bodyToSchedule(id, row.data);
2027
- }
2028
- const rows = await this.store.query({
2029
- collection: BACKUP_SCHEDULES,
2030
- filter: {
2031
- where: { id },
2032
- limit: 1
2033
- }
2034
- });
2035
- return rows[0] ? mapRowToSchedule(rows[0].data) : null;
1705
+ const row = await this.schedulesKind.get(id);
1706
+ return row === null ? null : bodyToSchedule(id, row.data);
2036
1707
  }
2037
- /** Replace-or-insert (delete + insert — mirrors the policy store). */
1708
+ /** Replace-or-insert: one full `put` of the row. */
2038
1709
  async upsert(s) {
2039
- await this.ensureDeclared();
2040
- const kind = this.schedulesKind;
2041
- if (kind !== null) {
2042
- const body = scheduleToBody(s);
2043
- const data = backupOrchestratorRecordKinds.schedules.schema.parse(body);
2044
- await kind.put({
2045
- id: s.id,
2046
- data
2047
- });
2048
- return;
2049
- }
2050
- await this.store.deleteWhere({
2051
- collection: BACKUP_SCHEDULES,
2052
- filter: { where: { id: s.id } }
2053
- });
2054
- await this.store.insert({
2055
- collection: BACKUP_SCHEDULES,
2056
- record: {
2057
- id: s.id,
2058
- data: mapScheduleToRow(s)
2059
- }
1710
+ const data = backupOrchestratorRecordKinds.schedules.schema.parse(scheduleToBody(s));
1711
+ await this.schedulesKind.put({
1712
+ id: s.id,
1713
+ data
2060
1714
  });
2061
1715
  }
2062
1716
  async delete(id) {
2063
- await this.ensureDeclared();
2064
- const kind = this.schedulesKind;
2065
- if (kind !== null) {
2066
- await kind.delete(id);
2067
- return;
2068
- }
2069
- await this.store.deleteWhere({
2070
- collection: BACKUP_SCHEDULES,
2071
- filter: { where: { id } }
2072
- });
1717
+ await this.schedulesKind.delete(id);
2073
1718
  }
2074
1719
  };
2075
1720
  function scheduleToBody(s) {
@@ -2102,73 +1747,6 @@ function bodyToSchedule(id, body) {
2102
1747
  ...body.lastError !== void 0 ? { lastError: body.lastError } : {}
2103
1748
  };
2104
1749
  }
2105
- function mapScheduleToRow(s) {
2106
- return {
2107
- id: s.id,
2108
- label: s.label,
2109
- cron: s.cron,
2110
- enabled: s.enabled ? 1 : 0,
2111
- location_ids: [...s.locationIds],
2112
- retention_count: s.retentionCount,
2113
- data_sources: s.dataSources ? [...s.dataSources] : null,
2114
- databases: s.databases ? [...s.databases] : null,
2115
- last_run_at: s.lastAttemptAt ?? null,
2116
- last_success_at: s.lastSuccessAt ?? null,
2117
- last_error: s.lastError ?? null
2118
- };
2119
- }
2120
- /**
2121
- * `location_ids` / `data_sources` are `JSON` columns, so the surface hands
2122
- * back real arrays. A STRING still arrives for rows an older build wrote and
2123
- * nothing has rewritten since — a schedule whose fan-out set silently read as
2124
- * empty would back up to nowhere, so both shapes are accepted.
2125
- */
2126
- function parseStringArray(raw) {
2127
- const value = typeof raw === "string" ? tryParseJson(raw) : raw;
2128
- if (!Array.isArray(value)) return [];
2129
- return value.filter((v) => typeof v === "string");
2130
- }
2131
- /** Known database ids only: an unknown name in a stored row is dropped, not carried. */
2132
- function parseDatabaseIds(raw) {
2133
- const out = [];
2134
- for (const id of parseStringArray(raw)) if (id === "settings" || id === "events" || id === "history") out.push(id);
2135
- return out;
2136
- }
2137
- function tryParseJson(raw) {
2138
- if (raw.length === 0) return null;
2139
- try {
2140
- return JSON.parse(raw);
2141
- } catch {
2142
- return null;
2143
- }
2144
- }
2145
- function mapRowToSchedule(row) {
2146
- const id = String(row["id"] ?? "");
2147
- if (!id) return null;
2148
- const dataSourcesRaw = row["data_sources"];
2149
- const dataSources = dataSourcesRaw === null || dataSourcesRaw === void 0 ? void 0 : parseStringArray(dataSourcesRaw);
2150
- const databasesRaw = row["databases"];
2151
- const databases = databasesRaw === null || databasesRaw === void 0 ? void 0 : parseDatabaseIds(databasesRaw);
2152
- const lastRunRaw = row["last_run_at"];
2153
- const lastAttemptAt = typeof lastRunRaw === "number" && lastRunRaw > 0 ? lastRunRaw : void 0;
2154
- const lastSuccessRaw = row["last_success_at"];
2155
- const lastSuccessAt = typeof lastSuccessRaw === "number" && lastSuccessRaw > 0 ? lastSuccessRaw : void 0;
2156
- const lastErrorRaw = row["last_error"];
2157
- const lastError = typeof lastErrorRaw === "string" && lastErrorRaw.length > 0 ? lastErrorRaw : void 0;
2158
- return {
2159
- id,
2160
- label: typeof row["label"] === "string" ? String(row["label"]) : "",
2161
- cron: typeof row["cron"] === "string" ? String(row["cron"]) : "",
2162
- enabled: row["enabled"] === 1 || row["enabled"] === true,
2163
- locationIds: parseStringArray(row["location_ids"]),
2164
- retentionCount: Number(row["retention_count"] ?? 7),
2165
- ...dataSources !== void 0 ? { dataSources } : {},
2166
- ...databases !== void 0 && databases.length > 0 ? { databases } : {},
2167
- ...lastAttemptAt !== void 0 ? { lastAttemptAt } : {},
2168
- ...lastSuccessAt !== void 0 ? { lastSuccessAt } : {},
2169
- ...lastError !== void 0 ? { lastError } : {}
2170
- };
2171
- }
2172
1750
  //#endregion
2173
1751
  //#region src/builtins/backup-orchestrator/staging-paths.ts
2174
1752
  /** Basename of the staging dir under the node data root. */
@@ -2300,8 +1878,8 @@ function selectBackupTargets(input) {
2300
1878
  * Responsibilities:
2301
1879
  * - Schedule (cron-like timer at top of hour, daily/weekly cadence)
2302
1880
  * - Per-destination policy (enable/disable, retention count, label)
2303
- * persisted in `backup_destination_policies` (this builtin owns
2304
- * the table).
1881
+ * persisted in the `destination-policies` records kind (this builtin
1882
+ * owns the kind).
2305
1883
  * - Archive build (one tar.gz with embedded manifest, fanned out to
2306
1884
  * every selected `backups`-typed `StorageLocation` via the
2307
1885
  * consumer-facing `storage` cap's chunked upload protocol).
@@ -2312,7 +1890,7 @@ function selectBackupTargets(input) {
2312
1890
  * Storage routing: destinations are
2313
1891
  * `api.storage.listLocations({ type: 'backups' })` — every operator-
2314
1892
  * visible `backups` location IS a destination. The orchestrator joins
2315
- * that list with the `backup_destination_policies` table to surface
1893
+ * that list with the `destination-policies` records to surface
2316
1894
  * `enabled` / `retentionCount` / `label`. The actual archive bytes
2317
1895
  * travel through `api.storage.beginUpload` / `writeChunk` /
2318
1896
  * `finalizeUpload`, with the staging archive built into
@@ -2408,19 +1986,11 @@ var BackupOrchestratorAddon = class extends BaseAddon {
2408
1986
  this.systemBackup = new SystemBackupService(this.dataDir, this.ctx.logger);
2409
1987
  this.runQueue = new BackupRunQueue((request, signal, progress) => this.runBackupBuild(request, signal, progress));
2410
1988
  await this.cleanStagingArea();
2411
- this.policies = this.resolvePolicyService();
2412
- if (this.policies) try {
2413
- await this.policies.initialize();
2414
- } catch (err) {
2415
- this.ctx.logger.error("backup-orchestrator: policy table init failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
2416
- this.policies = null;
2417
- }
2418
- this.schedules = this.resolveScheduleService();
2419
- if (this.schedules) try {
2420
- await this.schedules.initialize();
2421
- } catch (err) {
2422
- this.ctx.logger.error("backup-orchestrator: schedule table init failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
2423
- this.schedules = null;
1989
+ const backupRecords = this.backupRecords;
1990
+ if (backupRecords === null) this.ctx.logger.warn("backup-orchestrator: no ctx.records — schedules and destination policies will not persist");
1991
+ else {
1992
+ this.policies = new BackupDestinationPolicyService(backupRecords.destinationPolicies);
1993
+ this.schedules = new BackupScheduleService(backupRecords.schedules);
2424
1994
  }
2425
1995
  await this.seedWeekly();
2426
1996
  const settingsStore = this.ctx.kernel.capabilityRegistry?.getSingleton("settings-store");
@@ -2534,7 +2104,7 @@ var BackupOrchestratorAddon = class extends BaseAddon {
2534
2104
  * lazily seeding a default for any `locationId` we haven't seen
2535
2105
  * before. Idempotent — `ensureDefault` no-ops on already-persisted
2536
2106
  * rows. Falls back to the in-memory default policy when the policy
2537
- * service isn't wired (no settings-store backend available).
2107
+ * service isn't wired (no `ctx.records`).
2538
2108
  */
2539
2109
  async loadPoliciesIndexed(locationIds) {
2540
2110
  const out = /* @__PURE__ */ new Map();
@@ -3040,7 +2610,7 @@ var BackupOrchestratorAddon = class extends BaseAddon {
3040
2610
  */
3041
2611
  async upsertDestinationPolicy(input) {
3042
2612
  if (!this.policies) {
3043
- this.ctx.logger.warn("backup upsertDestinationPolicy: no settings-store backend — change will not persist", { meta: { locationId: input.locationId } });
2613
+ this.ctx.logger.warn("backup upsertDestinationPolicy: no ctx.records — change will not persist", { meta: { locationId: input.locationId } });
3044
2614
  return;
3045
2615
  }
3046
2616
  const existing = await this.policies.get(input.locationId).catch(() => null);
@@ -3423,11 +2993,10 @@ var BackupOrchestratorAddon = class extends BaseAddon {
3423
2993
  * anything the operator has: see `planWeeklySeed`.
3424
2994
  */
3425
2995
  async seedWeekly() {
3426
- if (!this.schedules) return;
2996
+ const markers = this.backupRecords?.seedMarkers;
2997
+ if (!this.schedules || markers === void 0) return;
3427
2998
  try {
3428
- const store = this.ctx.kernel.capabilityRegistry?.getSingleton("settings-store");
3429
- if (!store) return;
3430
- const seed = await seedWeeklySchedule(this.schedules, new BackupSeedMarkerStore(store, Date.now, this.backupRecords?.seedMarkers ?? null));
2999
+ const seed = await seedWeeklySchedule(this.schedules, new BackupSeedMarkerStore(markers));
3431
3000
  if (seed === null) return;
3432
3001
  this.ctx.logger.info("backup: seeded the weekly events & history schedule", { meta: {
3433
3002
  scheduleId: seed.id,
@@ -3533,7 +3102,7 @@ var BackupOrchestratorAddon = class extends BaseAddon {
3533
3102
  });
3534
3103
  }
3535
3104
  async upsertSchedule(input) {
3536
- if (!this.schedules) throw new Error("backup upsertSchedule: no settings-store backend — schedule cannot be persisted");
3105
+ if (!this.schedules) throw new Error("backup upsertSchedule: no ctx.records — schedule cannot be persisted");
3537
3106
  const cron = input.cron.trim();
3538
3107
  if (cron.length > 0 && !isValidCron(cron)) throw new Error(`Invalid cron expression: "${cron}"`);
3539
3108
  const id = input.id && input.id.length > 0 ? input.id : randomUUID();
@@ -3576,26 +3145,6 @@ var BackupOrchestratorAddon = class extends BaseAddon {
3576
3145
  if (!this.schedules) return;
3577
3146
  await this.schedules.delete(input.id);
3578
3147
  }
3579
- resolveScheduleService() {
3580
- const reg = this.ctx.kernel.capabilityRegistry;
3581
- if (!reg) return null;
3582
- const store = reg.getSingleton("settings-store");
3583
- if (!store) {
3584
- this.ctx.logger.warn("backup-orchestrator: no settings-store provider — backup schedules will not persist");
3585
- return null;
3586
- }
3587
- return new BackupScheduleService(store, this.backupRecords?.schedules ?? null);
3588
- }
3589
- resolvePolicyService() {
3590
- const reg = this.ctx.kernel.capabilityRegistry;
3591
- if (!reg) return null;
3592
- const store = reg.getSingleton("settings-store");
3593
- if (!store) {
3594
- this.ctx.logger.warn("backup-orchestrator: no settings-store provider — destination policies will not persist");
3595
- return null;
3596
- }
3597
- return new BackupDestinationPolicyService(store, this.backupRecords?.destinationPolicies ?? null);
3598
- }
3599
3148
  /**
3600
3149
  * Narrow `ctx.api.storage` to the subset the manifest helpers need.
3601
3150
  * Lets the helpers be unit-tested with a Map-backed fake without