@camstack/system 1.2.458 → 1.2.460
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/addon-runner.js +26 -11
- package/dist/addon-runner.mjs +26 -11
- package/dist/addon-utils.mjs +1 -1
- package/dist/{agent-https-DOELEug8.js → agent-https-Dnr_nIVx.js} +3 -723
- package/dist/{agent-https-CQA3W-3e.mjs → agent-https-Iw3RSQup.mjs} +4 -616
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +4 -4
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +5 -5
- package/dist/builtins/alerts/alerts.addon.js +5 -7
- package/dist/builtins/alerts/alerts.addon.mjs +5 -7
- package/dist/builtins/alerts/record-kinds.d.ts +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +242 -4
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +243 -5
- package/dist/builtins/calendars/calendars.addon.js +2 -10
- package/dist/builtins/calendars/calendars.addon.mjs +2 -3
- package/dist/builtins/calendars/record-kinds.d.ts +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +4 -6
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +4 -6
- package/dist/builtins/device-history/device-history.addon.js +1 -1
- package/dist/builtins/device-history/device-history.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +2 -4
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -4
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/keychain/index.js +41 -43
- package/dist/builtins/keychain/index.mjs +41 -43
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +24 -40
- package/dist/builtins/local-auth/local-auth.addon.mjs +27 -43
- package/dist/builtins/local-network/local-network.addon.js +2 -2
- package/dist/builtins/local-network/local-network.addon.mjs +2 -2
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +39 -4
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +48 -13
- package/dist/builtins/native-metrics/node-metrics-history-recorder.d.ts +16 -2
- package/dist/builtins/platform-probe/coral-accelerators.d.ts +10 -1
- package/dist/builtins/platform-probe/index.js +7 -4
- package/dist/builtins/platform-probe/index.mjs +13 -10
- package/dist/builtins/platform-probe/platform-scorer.d.ts +4 -1
- package/dist/builtins/record-entries/index.js +1 -1
- package/dist/builtins/record-entries/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/file-host-protocol.d.ts +0 -15
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +20 -20
- package/dist/builtins/sqlite-storage/index.js +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/owned-sqlite-file.d.ts +0 -44
- package/dist/builtins/sqlite-storage/records/records-catalog.d.ts +0 -2
- package/dist/builtins/sqlite-storage/records/records-engine-types.d.ts +0 -21
- package/dist/builtins/sqlite-storage/records/records-engine.d.ts +3 -20
- package/dist/builtins/sqlite-storage/records/records-plan.d.ts +9 -4
- package/dist/builtins/sqlite-storage/records/records-provider.d.ts +4 -18
- package/dist/builtins/sqlite-storage/records/records-sql.d.ts +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +0 -17
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +21 -196
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +21 -196
- package/dist/builtins/sqlite-storage/storage-admin-provider.d.ts +6 -14
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +2 -2
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +7 -9
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +7 -9
- package/dist/builtins/system-config/system-config.addon.js +667 -40
- package/dist/builtins/system-config/system-config.addon.mjs +737 -127
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-BVguN7VV.mjs → composition-sources-DNRZWR1j.mjs} +1 -1
- package/dist/{composition-sources-DURQNDJ4.js → composition-sources-b0e_2I-D.js} +1 -1
- package/dist/{constants-Njka8Cv6.js → constants-6OeJiZgi.js} +1 -1
- package/dist/{constants-FGjnsE2x.mjs → constants-BnkOdj9Q.mjs} +1 -1
- package/dist/{coral-accelerators-DcnZvctM.mjs → coral-accelerators-Qhn5TOYZ.mjs} +18 -15
- package/dist/{coral-accelerators-Bi_c3Rft.js → coral-accelerators-oUXmmbc2.js} +13 -10
- package/dist/{custom-action-registry-stpC3Zy-.mjs → custom-action-registry-DStvrQKI.mjs} +37 -37
- package/dist/{device-ca-lEaAQ9Xi.mjs → device-ca-Bnkw8GyU.mjs} +1 -1
- package/dist/{device-ca-BrVK_5s3.js → device-ca-CPTDs--d.js} +1 -1
- package/dist/{dist-BZQjLPiz.js → dist-Bn-RNanh.js} +29 -130
- package/dist/{dist-B_GRPhnY.mjs → dist-Wy8cTxg6.mjs} +30 -113
- package/dist/file-host-worker.js +1 -1
- package/dist/file-host-worker.mjs +1 -1
- package/dist/{hub-mdns-ciao-Bg2HfTwP.mjs → hub-mdns-ciao-CJu0nhla.mjs} +2 -2
- package/dist/{hub-mdns-ciao-nce3TXs_.js → hub-mdns-ciao-CTBTlia4.js} +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +56 -31
- package/dist/index.mjs +257 -233
- package/dist/kernel/deps/addon-deps-manager.d.ts +9 -0
- package/dist/{restore-archive-C7kLDI_0.mjs → restore-archive-CM23Pq9B.mjs} +177 -424
- package/dist/{restore-archive-FyfZ8YMC.js → restore-archive-DM1OBYq4.js} +89 -342
- package/dist/{wal-maintenance-Duejh7Lx.mjs → wal-maintenance-Bj_MmDkr.mjs} +0 -0
- package/dist/{wal-maintenance-DfSIOj24.js → wal-maintenance-CaJjuLHq.js} +0 -0
- package/package.json +1 -1
- package/dist/builtins/records/legacy-table-row-count.d.ts +0 -5
- package/dist/builtins/records/phase6-declare-gate.d.ts +0 -28
- package/dist/builtins/sqlite-storage/records/count-settings-array-legacy.d.ts +0 -5
- package/dist/builtins/sqlite-storage/records/count-settings-brokers-legacy.d.ts +0 -6
- package/dist/phase6-declare-gate-Dag1_WR2.js +0 -98
- package/dist/phase6-declare-gate-Lb-mrVvz.mjs +0 -93
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ta as EventCategory, ni as BaseAddon, ti as errMsg, xt as addonWidgetsCapability } from "../../dist-Wy8cTxg6.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
5
|
-
import * as fs from "node:fs";
|
|
5
|
+
import * as fs$1 from "node:fs";
|
|
6
6
|
//#region src/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.ts
|
|
7
7
|
/**
|
|
8
8
|
* Addon Widgets Aggregator — hub-local builtin that owns the singleton
|
|
@@ -204,9 +204,9 @@ var AddonWidgetsAggregatorAddon = class extends BaseAddon {
|
|
|
204
204
|
if (entryPath === null) return String(Math.floor(Date.now()));
|
|
205
205
|
try {
|
|
206
206
|
const dir = path$1.dirname(entryPath);
|
|
207
|
-
const files = fs.readdirSync(dir).filter((f) => fs.statSync(path$1.join(dir, f)).isFile()).sort();
|
|
207
|
+
const files = fs$1.readdirSync(dir).filter((f) => fs$1.statSync(path$1.join(dir, f)).isFile()).sort();
|
|
208
208
|
const cacheKey = `${dir}#${files.map((f) => {
|
|
209
|
-
const s = fs.statSync(path$1.join(dir, f));
|
|
209
|
+
const s = fs$1.statSync(path$1.join(dir, f));
|
|
210
210
|
return `${f}:${s.size}:${s.mtimeMs}`;
|
|
211
211
|
}).join("|")}`;
|
|
212
212
|
const cached = this.bundleHashCache.get(cacheKey);
|
|
@@ -214,7 +214,7 @@ var AddonWidgetsAggregatorAddon = class extends BaseAddon {
|
|
|
214
214
|
const hash = createHash("sha1");
|
|
215
215
|
for (const f of files) {
|
|
216
216
|
hash.update(f);
|
|
217
|
-
hash.update(fs.readFileSync(path$1.join(dir, f)));
|
|
217
|
+
hash.update(fs$1.readFileSync(path$1.join(dir, f)));
|
|
218
218
|
}
|
|
219
219
|
const digest = hash.digest("hex").slice(0, 12);
|
|
220
220
|
this.bundleHashCache.set(cacheKey, digest);
|
|
@@ -3,9 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bn-RNanh.js");
|
|
7
7
|
const require_read_all_rows$1 = require("../../read-all-rows-CVoO1ONM.js");
|
|
8
|
-
const require_phase6_declare_gate = require("../../phase6-declare-gate-Dag1_WR2.js");
|
|
9
8
|
//#region src/builtins/alerts/alert-episode-policy.ts
|
|
10
9
|
/**
|
|
11
10
|
* When does an alert open a new EPISODE, and which edge of it is announced?
|
|
@@ -225,7 +224,7 @@ var import_read_all_rows = require_read_all_rows$1.require_read_all_rows();
|
|
|
225
224
|
/**
|
|
226
225
|
* Record kinds owned by alert-center (records plan phase 4).
|
|
227
226
|
*/
|
|
228
|
-
/**
|
|
227
|
+
/** The legacy collection the kind replaced (canonical KV before phase 4); read only without records. */
|
|
229
228
|
var ALERTS_COLLECTION = "alerts";
|
|
230
229
|
var AlertBodySchema = require_dist.AlertSchema.omit({ id: true });
|
|
231
230
|
var _alertCenterRecordKinds = require_dist.defineRecordKinds({ alerts: {
|
|
@@ -251,8 +250,7 @@ var _alertCenterRecordKinds = require_dist.defineRecordKinds({ alerts: {
|
|
|
251
250
|
retention: {
|
|
252
251
|
owner: "alert-center",
|
|
253
252
|
reason: "maxAlerts cap and retentionDays enforced on write (enforceMaxAlerts / enforceRetention); read alerts preferred when trimming overflow"
|
|
254
|
-
}
|
|
255
|
-
adoptsFrom: ALERTS_COLLECTION
|
|
253
|
+
}
|
|
256
254
|
} });
|
|
257
255
|
var alertCenterRecordKinds = _alertCenterRecordKinds;
|
|
258
256
|
/** Narrow kind for `records.kind()` — `IsolatedRecordKinds` string index is `| undefined`. */
|
|
@@ -644,8 +642,8 @@ var AlertCenterAddon = class extends require_dist.BaseAddon {
|
|
|
644
642
|
async onInitialize() {
|
|
645
643
|
const records = this.ctx.records;
|
|
646
644
|
const store = this.ctx.api?.settingsStore;
|
|
647
|
-
|
|
648
|
-
this.alertStore =
|
|
645
|
+
if (records !== void 0) await records.declare(alertCenterRecordKinds);
|
|
646
|
+
this.alertStore = records !== void 0 ? AlertStore.of(records) : store === void 0 ? null : AlertStore.legacy(store);
|
|
649
647
|
if (this.alertStore === null) throw new Error("alert-center needs ctx.records or settings-store on the hub");
|
|
650
648
|
const alertsProvider = {
|
|
651
649
|
emit: (alert) => this.emitAlert(alert),
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Ct as alertEpisodePayload,
|
|
1
|
+
import { Ct as alertEpisodePayload, Gi as defineRecordKinds, Hi as createEvent, Sn as isAlertEpisodeSeverity, St as alertEpisodeId, Ta as EventCategory, i as AlertSchema, ni as BaseAddon, ti as errMsg, wt as alertsCapability, xn as isAlertEpisodeOpen } from "../../dist-Wy8cTxg6.mjs";
|
|
2
2
|
import { t as require_read_all_rows } from "../../read-all-rows-TaPqdWNF.mjs";
|
|
3
|
-
import { t as resolvePhase6UseRecordsPathForHub } from "../../phase6-declare-gate-Lb-mrVvz.mjs";
|
|
4
3
|
//#region src/builtins/alerts/alert-episode-policy.ts
|
|
5
4
|
/**
|
|
6
5
|
* When does an alert open a new EPISODE, and which edge of it is announced?
|
|
@@ -220,7 +219,7 @@ var import_read_all_rows = require_read_all_rows();
|
|
|
220
219
|
/**
|
|
221
220
|
* Record kinds owned by alert-center (records plan phase 4).
|
|
222
221
|
*/
|
|
223
|
-
/**
|
|
222
|
+
/** The legacy collection the kind replaced (canonical KV before phase 4); read only without records. */
|
|
224
223
|
var ALERTS_COLLECTION = "alerts";
|
|
225
224
|
var _alertCenterRecordKinds = defineRecordKinds({ alerts: {
|
|
226
225
|
schema: AlertSchema.omit({ id: true }),
|
|
@@ -245,8 +244,7 @@ var _alertCenterRecordKinds = defineRecordKinds({ alerts: {
|
|
|
245
244
|
retention: {
|
|
246
245
|
owner: "alert-center",
|
|
247
246
|
reason: "maxAlerts cap and retentionDays enforced on write (enforceMaxAlerts / enforceRetention); read alerts preferred when trimming overflow"
|
|
248
|
-
}
|
|
249
|
-
adoptsFrom: ALERTS_COLLECTION
|
|
247
|
+
}
|
|
250
248
|
} });
|
|
251
249
|
var alertCenterRecordKinds = _alertCenterRecordKinds;
|
|
252
250
|
/** Narrow kind for `records.kind()` — `IsolatedRecordKinds` string index is `| undefined`. */
|
|
@@ -638,8 +636,8 @@ var AlertCenterAddon = class extends BaseAddon {
|
|
|
638
636
|
async onInitialize() {
|
|
639
637
|
const records = this.ctx.records;
|
|
640
638
|
const store = this.ctx.api?.settingsStore;
|
|
641
|
-
|
|
642
|
-
this.alertStore =
|
|
639
|
+
if (records !== void 0) await records.declare(alertCenterRecordKinds);
|
|
640
|
+
this.alertStore = records !== void 0 ? AlertStore.of(records) : store === void 0 ? null : AlertStore.legacy(store);
|
|
643
641
|
if (this.alertStore === null) throw new Error("alert-center needs ctx.records or settings-store on the hub");
|
|
644
642
|
const alertsProvider = {
|
|
645
643
|
emit: (alert) => this.emitAlert(alert),
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { type Alert, type DefinedRecordKind } from "@camstack/types";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
/**
|
|
6
|
+
/** The legacy collection the kind replaced (canonical KV before phase 4); read only without records. */
|
|
7
7
|
export declare const ALERTS_COLLECTION = "alerts";
|
|
8
8
|
export type AlertBody = Omit<Alert, "id">;
|
|
9
9
|
export declare const AlertBodySchema: z.ZodType<AlertBody>;
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bn-RNanh.js");
|
|
7
7
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
8
8
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
9
9
|
deadZoneFraction: .5,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { L as FIRST_LEVEL_MACRO_CLASSES, Ot as bareAddonId, Qi as isEvent, Ta as EventCategory, ni as BaseAddon, rr as ptzAutotrackCapability, ti as errMsg } from "../../dist-Wy8cTxg6.mjs";
|
|
2
2
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
3
3
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
4
4
|
deadZoneFraction: .5,
|
|
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-Bn-RNanh.js");
|
|
7
7
|
const require_read_all_rows$1 = require("../../read-all-rows-CVoO1ONM.js");
|
|
8
|
-
const require_restore_archive = require("../../restore-archive-
|
|
8
|
+
const require_restore_archive = require("../../restore-archive-DM1OBYq4.js");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
10
10
|
let node_fs_promises = require("node:fs/promises");
|
|
11
11
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -85,6 +85,81 @@ async function seedWeeklySchedule(store, markers) {
|
|
|
85
85
|
return seed;
|
|
86
86
|
}
|
|
87
87
|
//#endregion
|
|
88
|
+
//#region src/builtins/backup-orchestrator/seed-marker-store.ts
|
|
89
|
+
/**
|
|
90
|
+
* @durable class=config owner=backup-orchestrator
|
|
91
|
+
* write="the orchestrator inserts one row per seed id the first time that
|
|
92
|
+
* seed is created (or found already created); never updated"
|
|
93
|
+
* retention="none — one tiny row per seed ever made; deleting it lets the
|
|
94
|
+
* seed be re-created once more on the next boot"
|
|
95
|
+
*/
|
|
96
|
+
var BACKUP_SEED_MARKERS_COLLECTION = "backup_seed_markers";
|
|
97
|
+
var COLUMNS$1 = [{
|
|
98
|
+
name: "seed_id",
|
|
99
|
+
type: "TEXT",
|
|
100
|
+
primaryKey: true
|
|
101
|
+
}, {
|
|
102
|
+
name: "seeded_at",
|
|
103
|
+
type: "INTEGER",
|
|
104
|
+
notNull: true
|
|
105
|
+
}];
|
|
106
|
+
var BackupSeedMarkerStore = class {
|
|
107
|
+
store;
|
|
108
|
+
now;
|
|
109
|
+
declared = false;
|
|
110
|
+
markersKind;
|
|
111
|
+
constructor(store, now = Date.now, markersKind = null) {
|
|
112
|
+
this.store = store;
|
|
113
|
+
this.now = now;
|
|
114
|
+
this.markersKind = markersKind;
|
|
115
|
+
}
|
|
116
|
+
async ensureDeclared() {
|
|
117
|
+
if (this.markersKind !== null) return;
|
|
118
|
+
if (this.declared) return;
|
|
119
|
+
await this.store.declareCollection({
|
|
120
|
+
collection: BACKUP_SEED_MARKERS_COLLECTION,
|
|
121
|
+
columns: COLUMNS$1
|
|
122
|
+
});
|
|
123
|
+
this.declared = true;
|
|
124
|
+
}
|
|
125
|
+
async has(seedId) {
|
|
126
|
+
await this.ensureDeclared();
|
|
127
|
+
const kind = this.markersKind;
|
|
128
|
+
if (kind !== null) return await kind.get(seedId) !== null;
|
|
129
|
+
return (await this.store.query({
|
|
130
|
+
collection: BACKUP_SEED_MARKERS_COLLECTION,
|
|
131
|
+
filter: {
|
|
132
|
+
where: { seed_id: seedId },
|
|
133
|
+
limit: 1
|
|
134
|
+
}
|
|
135
|
+
})).length > 0;
|
|
136
|
+
}
|
|
137
|
+
async mark(seedId) {
|
|
138
|
+
await this.ensureDeclared();
|
|
139
|
+
if (await this.has(seedId)) return;
|
|
140
|
+
const kind = this.markersKind;
|
|
141
|
+
if (kind !== null) {
|
|
142
|
+
const body = { seededAt: this.now() };
|
|
143
|
+
const data = require_restore_archive.backupOrchestratorRecordKinds["seed-markers"].schema.parse(body);
|
|
144
|
+
await kind.put({
|
|
145
|
+
id: seedId,
|
|
146
|
+
data
|
|
147
|
+
});
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
await this.store.insert({
|
|
151
|
+
collection: BACKUP_SEED_MARKERS_COLLECTION,
|
|
152
|
+
record: {
|
|
153
|
+
id: seedId,
|
|
154
|
+
data: {
|
|
155
|
+
seed_id: seedId,
|
|
156
|
+
seeded_at: this.now()
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
//#endregion
|
|
88
163
|
//#region ../../node_modules/croner/dist/croner.js
|
|
89
164
|
function T(s) {
|
|
90
165
|
return Date.UTC(s.y, s.m - 1, s.d, s.h, s.i, s.s);
|
|
@@ -1209,6 +1284,169 @@ async function downloadArchiveToCache(input) {
|
|
|
1209
1284
|
}
|
|
1210
1285
|
}
|
|
1211
1286
|
//#endregion
|
|
1287
|
+
//#region src/builtins/backup-orchestrator/encryption-key-store.ts
|
|
1288
|
+
/**
|
|
1289
|
+
* @durable class=config owner=backup-orchestrator
|
|
1290
|
+
* write="`setupEncryption` inserts one row per generated key and retires the
|
|
1291
|
+
* previous active row; `disableEncryption` retires the active row"
|
|
1292
|
+
* retention="none — one small row per key ever generated; a retired row
|
|
1293
|
+
* names the key older archives need"
|
|
1294
|
+
*/
|
|
1295
|
+
var BACKUP_ENCRYPTION_KEYS_COLLECTION = "backup_encryption_keys";
|
|
1296
|
+
var COLUMNS = [
|
|
1297
|
+
{
|
|
1298
|
+
name: "key_id",
|
|
1299
|
+
type: "TEXT",
|
|
1300
|
+
primaryKey: true
|
|
1301
|
+
},
|
|
1302
|
+
{
|
|
1303
|
+
name: "public_key",
|
|
1304
|
+
type: "TEXT",
|
|
1305
|
+
notNull: true
|
|
1306
|
+
},
|
|
1307
|
+
{
|
|
1308
|
+
name: "created_at",
|
|
1309
|
+
type: "INTEGER",
|
|
1310
|
+
notNull: true
|
|
1311
|
+
},
|
|
1312
|
+
{
|
|
1313
|
+
name: "retired_at",
|
|
1314
|
+
type: "INTEGER"
|
|
1315
|
+
}
|
|
1316
|
+
];
|
|
1317
|
+
var BackupEncryptionKeyStore = class {
|
|
1318
|
+
store;
|
|
1319
|
+
now;
|
|
1320
|
+
declared = false;
|
|
1321
|
+
keysKind;
|
|
1322
|
+
constructor(store, now = Date.now, keysKind = null) {
|
|
1323
|
+
this.store = store;
|
|
1324
|
+
this.now = now;
|
|
1325
|
+
this.keysKind = keysKind;
|
|
1326
|
+
}
|
|
1327
|
+
async ensureDeclared() {
|
|
1328
|
+
if (this.keysKind !== null) return;
|
|
1329
|
+
if (this.declared) return;
|
|
1330
|
+
await this.store.declareCollection({
|
|
1331
|
+
collection: BACKUP_ENCRYPTION_KEYS_COLLECTION,
|
|
1332
|
+
columns: COLUMNS
|
|
1333
|
+
});
|
|
1334
|
+
this.declared = true;
|
|
1335
|
+
}
|
|
1336
|
+
/** Every key, newest first. */
|
|
1337
|
+
async list() {
|
|
1338
|
+
await this.ensureDeclared();
|
|
1339
|
+
const kind = this.keysKind;
|
|
1340
|
+
if (kind !== null) {
|
|
1341
|
+
const rows = await (0, import_read_all_rows.readAllRows)(kind);
|
|
1342
|
+
rows.sort((a, b) => b.data.createdAt - a.data.createdAt);
|
|
1343
|
+
const out = [];
|
|
1344
|
+
for (const row of rows) {
|
|
1345
|
+
const record = bodyToRecord(row.id, row.data);
|
|
1346
|
+
if (record !== null) out.push(record);
|
|
1347
|
+
}
|
|
1348
|
+
return out;
|
|
1349
|
+
}
|
|
1350
|
+
const rows = await this.store.query({
|
|
1351
|
+
collection: BACKUP_ENCRYPTION_KEYS_COLLECTION,
|
|
1352
|
+
filter: { orderBy: {
|
|
1353
|
+
field: "created_at",
|
|
1354
|
+
direction: "desc"
|
|
1355
|
+
} }
|
|
1356
|
+
});
|
|
1357
|
+
const out = [];
|
|
1358
|
+
for (const row of rows) {
|
|
1359
|
+
const record = toRecord(row.data);
|
|
1360
|
+
if (record !== null) out.push(record);
|
|
1361
|
+
}
|
|
1362
|
+
return out;
|
|
1363
|
+
}
|
|
1364
|
+
/** The key new archives are encrypted to; `null` = encryption off. */
|
|
1365
|
+
async active() {
|
|
1366
|
+
return (await this.list()).find((k) => k.retiredAt === null) ?? null;
|
|
1367
|
+
}
|
|
1368
|
+
/** Make `publicKey` the active key; the previous one is retired, kept listed. */
|
|
1369
|
+
async activate(input) {
|
|
1370
|
+
const parsed = require_restore_archive.parseBackupPublicKey(input.publicKey);
|
|
1371
|
+
const t = this.now();
|
|
1372
|
+
await this.retireActive(t);
|
|
1373
|
+
const record = {
|
|
1374
|
+
keyId: parsed.keyId,
|
|
1375
|
+
publicKey: input.publicKey.trim(),
|
|
1376
|
+
createdAt: t,
|
|
1377
|
+
retiredAt: null
|
|
1378
|
+
};
|
|
1379
|
+
await this.write(record);
|
|
1380
|
+
return record;
|
|
1381
|
+
}
|
|
1382
|
+
/** Encryption off: the active key is retired. Archives already made keep needing it. */
|
|
1383
|
+
async disable() {
|
|
1384
|
+
await this.retireActive(this.now());
|
|
1385
|
+
}
|
|
1386
|
+
async retireActive(at) {
|
|
1387
|
+
for (const key of await this.list()) if (key.retiredAt === null) await this.write({
|
|
1388
|
+
...key,
|
|
1389
|
+
retiredAt: at
|
|
1390
|
+
});
|
|
1391
|
+
}
|
|
1392
|
+
async write(record) {
|
|
1393
|
+
await this.ensureDeclared();
|
|
1394
|
+
const kind = this.keysKind;
|
|
1395
|
+
if (kind !== null) {
|
|
1396
|
+
const body = {
|
|
1397
|
+
keyId: record.keyId,
|
|
1398
|
+
publicKey: record.publicKey,
|
|
1399
|
+
createdAt: record.createdAt,
|
|
1400
|
+
retiredAt: record.retiredAt
|
|
1401
|
+
};
|
|
1402
|
+
const data = require_restore_archive.backupOrchestratorRecordKinds["encryption-keys"].schema.parse(body);
|
|
1403
|
+
await kind.put({
|
|
1404
|
+
id: record.keyId,
|
|
1405
|
+
data
|
|
1406
|
+
});
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
await this.store.deleteWhere({
|
|
1410
|
+
collection: BACKUP_ENCRYPTION_KEYS_COLLECTION,
|
|
1411
|
+
filter: { where: { key_id: record.keyId } }
|
|
1412
|
+
});
|
|
1413
|
+
await this.store.insert({
|
|
1414
|
+
collection: BACKUP_ENCRYPTION_KEYS_COLLECTION,
|
|
1415
|
+
record: {
|
|
1416
|
+
id: record.keyId,
|
|
1417
|
+
data: {
|
|
1418
|
+
key_id: record.keyId,
|
|
1419
|
+
public_key: record.publicKey,
|
|
1420
|
+
created_at: record.createdAt,
|
|
1421
|
+
retired_at: record.retiredAt
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
});
|
|
1425
|
+
}
|
|
1426
|
+
};
|
|
1427
|
+
function bodyToRecord(keyId, body) {
|
|
1428
|
+
if (!keyId) return null;
|
|
1429
|
+
return {
|
|
1430
|
+
keyId: body.keyId,
|
|
1431
|
+
publicKey: body.publicKey,
|
|
1432
|
+
createdAt: body.createdAt,
|
|
1433
|
+
retiredAt: body.retiredAt
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
function toRecord(row) {
|
|
1437
|
+
const keyId = row["key_id"];
|
|
1438
|
+
const publicKey = row["public_key"];
|
|
1439
|
+
const createdAt = row["created_at"];
|
|
1440
|
+
if (typeof keyId !== "string" || typeof publicKey !== "string") return null;
|
|
1441
|
+
const retired = row["retired_at"];
|
|
1442
|
+
return {
|
|
1443
|
+
keyId,
|
|
1444
|
+
publicKey,
|
|
1445
|
+
createdAt: typeof createdAt === "number" ? createdAt : Number(createdAt ?? 0),
|
|
1446
|
+
retiredAt: typeof retired === "number" ? retired : null
|
|
1447
|
+
};
|
|
1448
|
+
}
|
|
1449
|
+
//#endregion
|
|
1212
1450
|
//#region src/builtins/backup-orchestrator/manifest-store.ts
|
|
1213
1451
|
/** File path (relative to the location root) where the index lives. */
|
|
1214
1452
|
var MANIFESTS_FILENAME = "manifests.json";
|
|
@@ -2194,7 +2432,7 @@ var BackupOrchestratorAddon = class extends require_dist.BaseAddon {
|
|
|
2194
2432
|
}
|
|
2195
2433
|
await this.seedWeekly();
|
|
2196
2434
|
const settingsStore = this.ctx.kernel.capabilityRegistry?.getSingleton("settings-store");
|
|
2197
|
-
this.encryptionKeys = settingsStore ? new
|
|
2435
|
+
this.encryptionKeys = settingsStore ? new BackupEncryptionKeyStore(settingsStore, Date.now, this.backupRecords?.encryptionKeys ?? null) : null;
|
|
2198
2436
|
const provider = {
|
|
2199
2437
|
listDestinations: () => this.listDestinations(),
|
|
2200
2438
|
list: () => this.aggregatedList(),
|
|
@@ -3197,7 +3435,7 @@ var BackupOrchestratorAddon = class extends require_dist.BaseAddon {
|
|
|
3197
3435
|
try {
|
|
3198
3436
|
const store = this.ctx.kernel.capabilityRegistry?.getSingleton("settings-store");
|
|
3199
3437
|
if (!store) return;
|
|
3200
|
-
const seed = await seedWeeklySchedule(this.schedules, new
|
|
3438
|
+
const seed = await seedWeeklySchedule(this.schedules, new BackupSeedMarkerStore(store, Date.now, this.backupRecords?.seedMarkers ?? null));
|
|
3201
3439
|
if (seed === null) return;
|
|
3202
3440
|
this.ctx.logger.info("backup: seeded the weekly events & history schedule", { meta: {
|
|
3203
3441
|
scheduleId: seed.id,
|