@attraccess/plugin-wago 0.1.0-nightly.979.1 → 0.1.0-nightly.981.1
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.js +212 -123
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -53808,13 +53808,13 @@ async function configurationFlowImpacts(context, controllerId, previous, current
|
|
|
53808
53808
|
}
|
|
53809
53809
|
const nodes = await context.dataSource.getRepository(import_plugins_backend_sdk5.ResourceFlowNode).createQueryBuilder("node").select(["node.id", "node.resourceId", "node.type", "node.data"]).where("node.type LIKE :type", { type: "plugin.wago.%" }).andWhere("node.data ->> 'controllerId' = :controllerId", { controllerId }).getMany();
|
|
53810
53810
|
for (const node of nodes) {
|
|
53811
|
-
const
|
|
53812
|
-
if (String(node.type) !== "plugin.wago.command" || typeof
|
|
53811
|
+
const channelId2 = node.data?.channelId;
|
|
53812
|
+
if (String(node.type) !== "plugin.wago.command" || typeof channelId2 !== "string" || !channelId2) continue;
|
|
53813
53813
|
const message = "Publication changes the configuration revision. Reopen and save this channel's command nodes after it applies.";
|
|
53814
|
-
const impact = impacts.find((item) => item.channelId ===
|
|
53814
|
+
const impact = impacts.find((item) => item.channelId === channelId2);
|
|
53815
53815
|
if (impact) {
|
|
53816
53816
|
if (!impact.message.includes(message)) impact.message += ` ${message}`;
|
|
53817
|
-
} else impacts.push({ channelId, message });
|
|
53817
|
+
} else impacts.push({ channelId: channelId2, message });
|
|
53818
53818
|
}
|
|
53819
53819
|
return impacts.map((impact) => ({
|
|
53820
53820
|
...impact,
|
|
@@ -53900,21 +53900,21 @@ var WagoCommandHandler = class {
|
|
|
53900
53900
|
async schema(config, resourceId) {
|
|
53901
53901
|
const controllers = await this.dependencies.controllers().find({ where: { trustState: "claimed" }, order: { name: "ASC" } });
|
|
53902
53902
|
const controllerId = positiveInteger2(config.controllerId);
|
|
53903
|
-
const
|
|
53904
|
-
const snapshot =
|
|
53905
|
-
const
|
|
53903
|
+
const revision2 = controllerId ? await this.dependencies.appliedRevision(controllerId) : null;
|
|
53904
|
+
const snapshot = revision2 ? JSON.parse(revision2.snapshot) : null;
|
|
53905
|
+
const channelId2 = typeof config.channelId === "string" ? config.channelId : void 0;
|
|
53906
53906
|
const outputChannels = snapshot?.logicalChannels.filter((item) => item.capabilities.includes("output")) ?? [];
|
|
53907
53907
|
let names = {};
|
|
53908
53908
|
if (controllerId) {
|
|
53909
53909
|
const draft = await this.dependencies.context.getRepository(WagoConfigurationDraft).findOneBy({ controllerId });
|
|
53910
53910
|
try {
|
|
53911
|
-
const storedNames = JSON.parse(
|
|
53911
|
+
const storedNames = JSON.parse(revision2?.presetProvenance ?? draft?.presetProvenance ?? "null")?.editor?.names;
|
|
53912
53912
|
if (storedNames && typeof storedNames === "object" && !Array.isArray(storedNames)) names = storedNames;
|
|
53913
53913
|
} catch {
|
|
53914
53914
|
}
|
|
53915
53915
|
}
|
|
53916
|
-
const channel = outputChannels.find((item) => item.id ===
|
|
53917
|
-
const references =
|
|
53916
|
+
const channel = outputChannels.find((item) => item.id === channelId2);
|
|
53917
|
+
const references = channelId2 && controllerId ? await this.references(controllerId, channelId2, resourceId) : [];
|
|
53918
53918
|
const properties = {
|
|
53919
53919
|
controllerId: {
|
|
53920
53920
|
type: "number",
|
|
@@ -53925,10 +53925,10 @@ var WagoCommandHandler = class {
|
|
|
53925
53925
|
title: controller.name ?? controller.hardwareId
|
|
53926
53926
|
})),
|
|
53927
53927
|
refreshesSchema: true,
|
|
53928
|
-
description: controllerId && !
|
|
53928
|
+
description: controllerId && !revision2 ? "Publish a configuration and wait for the controller to apply it before authoring commands." : void 0
|
|
53929
53929
|
}
|
|
53930
53930
|
};
|
|
53931
|
-
if (controllerId &&
|
|
53931
|
+
if (controllerId && revision2 && snapshot) {
|
|
53932
53932
|
properties.channelId = {
|
|
53933
53933
|
type: "string",
|
|
53934
53934
|
title: "Logical Channel",
|
|
@@ -53956,7 +53956,7 @@ var WagoCommandHandler = class {
|
|
|
53956
53956
|
properties.expectedConfigurationRevision = {
|
|
53957
53957
|
type: "number",
|
|
53958
53958
|
title: "Configuration revision",
|
|
53959
|
-
default:
|
|
53959
|
+
default: revision2.revision,
|
|
53960
53960
|
readOnly: true
|
|
53961
53961
|
};
|
|
53962
53962
|
properties.completionBehavior = {
|
|
@@ -54007,7 +54007,7 @@ var WagoCommandHandler = class {
|
|
|
54007
54007
|
async validate(config, validationContext = /* @__PURE__ */ new Map()) {
|
|
54008
54008
|
const parsed = this.parse(config);
|
|
54009
54009
|
if ("errors" in parsed) return parsed.errors;
|
|
54010
|
-
const { controllerId, channelId, action, expectedConfigurationRevision } = parsed.value;
|
|
54010
|
+
const { controllerId, channelId: channelId2, action, expectedConfigurationRevision } = parsed.value;
|
|
54011
54011
|
const controller = await this.cached(
|
|
54012
54012
|
validationContext,
|
|
54013
54013
|
`wago-controller:${controllerId}`,
|
|
@@ -54015,21 +54015,21 @@ var WagoCommandHandler = class {
|
|
|
54015
54015
|
);
|
|
54016
54016
|
if (!controller || controller.trustState !== "claimed")
|
|
54017
54017
|
return [{ field: "controllerId", message: "Select a claimed WAGO controller." }];
|
|
54018
|
-
const
|
|
54018
|
+
const revision2 = await this.cached(
|
|
54019
54019
|
validationContext,
|
|
54020
54020
|
`wago-applied-revision:${controllerId}`,
|
|
54021
54021
|
() => this.dependencies.appliedRevision(controllerId)
|
|
54022
54022
|
);
|
|
54023
|
-
if (!
|
|
54024
|
-
if (
|
|
54023
|
+
if (!revision2) return [{ field: "controllerId", message: "The controller has no applied configuration revision." }];
|
|
54024
|
+
if (revision2.revision !== expectedConfigurationRevision)
|
|
54025
54025
|
return [
|
|
54026
54026
|
{
|
|
54027
54027
|
field: "expectedConfigurationRevision",
|
|
54028
54028
|
message: "The controller configuration changed. Reopen the node and save the current revision."
|
|
54029
54029
|
}
|
|
54030
54030
|
];
|
|
54031
|
-
const snapshot = JSON.parse(
|
|
54032
|
-
const channel = snapshot.logicalChannels.find((item) => item.id ===
|
|
54031
|
+
const snapshot = JSON.parse(revision2.snapshot);
|
|
54032
|
+
const channel = snapshot.logicalChannels.find((item) => item.id === channelId2);
|
|
54033
54033
|
if (!channel) return [{ field: "channelId", message: "The selected Logical Channel no longer exists." }];
|
|
54034
54034
|
if (!channel.capabilities.includes("output"))
|
|
54035
54035
|
return [{ field: "channelId", message: "The selected Logical Channel no longer supports output commands." }];
|
|
@@ -54051,7 +54051,7 @@ var WagoCommandHandler = class {
|
|
|
54051
54051
|
throw new WagoCommandError(parsed.errors.map((error) => error.message).join(" "), "controller-rejection");
|
|
54052
54052
|
const {
|
|
54053
54053
|
controllerId,
|
|
54054
|
-
channelId,
|
|
54054
|
+
channelId: channelId2,
|
|
54055
54055
|
action,
|
|
54056
54056
|
value,
|
|
54057
54057
|
expectedConfigurationRevision,
|
|
@@ -54063,11 +54063,11 @@ var WagoCommandHandler = class {
|
|
|
54063
54063
|
throw new WagoCommandError(`WAGO controller ${controllerId} has no MQTT server`, "transport-dispatch");
|
|
54064
54064
|
const settings = await this.dependencies.getSettings();
|
|
54065
54065
|
const id = commandId;
|
|
54066
|
-
this.dependencies.onCommand?.(controllerId,
|
|
54066
|
+
this.dependencies.onCommand?.(controllerId, channelId2, id);
|
|
54067
54067
|
const command = JSON.stringify({
|
|
54068
54068
|
id,
|
|
54069
54069
|
expiresAt: new Date(Date.now() + acknowledgementTimeoutSeconds * 1e3).toISOString(),
|
|
54070
|
-
channelId,
|
|
54070
|
+
channelId: channelId2,
|
|
54071
54071
|
action,
|
|
54072
54072
|
...action === "set" ? { value } : {},
|
|
54073
54073
|
expectedConfigurationRevision
|
|
@@ -54134,22 +54134,22 @@ var WagoCommandHandler = class {
|
|
|
54134
54134
|
this.pending.delete(id);
|
|
54135
54135
|
}
|
|
54136
54136
|
}
|
|
54137
|
-
async references(controllerId,
|
|
54138
|
-
const nodes = await this.dependencies.context.dataSource.getRepository(import_plugins_backend_sdk7.ResourceFlowNode).createQueryBuilder("node").select(["node.id", "node.resourceId"]).where("node.type = :type", { type: "plugin.wago.command" }).andWhere("node.resourceId <> :resourceId", { resourceId }).andWhere("node.data ->> 'controllerId' = :controllerId", { controllerId }).andWhere("node.data ->> 'channelId' = :channelId", { channelId }).getMany();
|
|
54137
|
+
async references(controllerId, channelId2, resourceId) {
|
|
54138
|
+
const nodes = await this.dependencies.context.dataSource.getRepository(import_plugins_backend_sdk7.ResourceFlowNode).createQueryBuilder("node").select(["node.id", "node.resourceId"]).where("node.type = :type", { type: "plugin.wago.command" }).andWhere("node.resourceId <> :resourceId", { resourceId }).andWhere("node.data ->> 'controllerId' = :controllerId", { controllerId }).andWhere("node.data ->> 'channelId' = :channelId", { channelId: channelId2 }).getMany();
|
|
54139
54139
|
return nodes.map((node) => `resource ${node.resourceId} / node ${node.id}`);
|
|
54140
54140
|
}
|
|
54141
54141
|
parse(config) {
|
|
54142
54142
|
const errors = [];
|
|
54143
54143
|
const controllerId = positiveInteger2(config.controllerId);
|
|
54144
54144
|
const expectedConfigurationRevision = positiveInteger2(config.expectedConfigurationRevision);
|
|
54145
|
-
const
|
|
54145
|
+
const channelId2 = typeof config.channelId === "string" && config.channelId.trim() ? config.channelId : void 0;
|
|
54146
54146
|
const action = config.action === "set" || config.action === "pulse" ? config.action : void 0;
|
|
54147
54147
|
const completionBehavior = config.completionBehavior === "dispatch" ? "dispatch" : "acknowledged";
|
|
54148
54148
|
const parsedTimeout = positiveInteger2(config.acknowledgementTimeoutSeconds);
|
|
54149
54149
|
const acknowledgementTimeoutSeconds = parsedTimeout ?? DEFAULT_COMMAND_TIMEOUT_SECONDS;
|
|
54150
54150
|
if (!controllerId)
|
|
54151
54151
|
errors.push({ field: "controllerId", message: "A WAGO controller is required.", value: config.controllerId });
|
|
54152
|
-
if (!
|
|
54152
|
+
if (!channelId2)
|
|
54153
54153
|
errors.push({ field: "channelId", message: "A Logical Channel is required.", value: config.channelId });
|
|
54154
54154
|
if (!action) errors.push({ field: "action", message: "A supported operation is required.", value: config.action });
|
|
54155
54155
|
if (action === "set" && typeof config.value !== "boolean")
|
|
@@ -54188,7 +54188,7 @@ var WagoCommandHandler = class {
|
|
|
54188
54188
|
return {
|
|
54189
54189
|
value: {
|
|
54190
54190
|
controllerId,
|
|
54191
|
-
channelId,
|
|
54191
|
+
channelId: channelId2,
|
|
54192
54192
|
action,
|
|
54193
54193
|
...action === "set" ? { value: config.value } : {},
|
|
54194
54194
|
expectedConfigurationRevision,
|
|
@@ -54396,16 +54396,16 @@ var WagoDiagnosticsStore = class {
|
|
|
54396
54396
|
if (copy.rejection && Date.parse(copy.rejection.receivedAt) < cutoff) delete copy.rejection;
|
|
54397
54397
|
return copy;
|
|
54398
54398
|
}
|
|
54399
|
-
command(controllerId,
|
|
54399
|
+
command(controllerId, channelId2, id) {
|
|
54400
54400
|
this.prune();
|
|
54401
|
-
if (!identifier(
|
|
54401
|
+
if (!identifier(channelId2) || !identifier(id)) return;
|
|
54402
54402
|
if (!this.controllers.has(controllerId) && this.controllers.size >= MAX_CONTROLLERS) return;
|
|
54403
54403
|
const state = this.read(controllerId);
|
|
54404
54404
|
state.touched = this.now();
|
|
54405
54405
|
this.controllers.set(controllerId, state);
|
|
54406
54406
|
const oldest = this.commands.keys().next().value;
|
|
54407
54407
|
if (this.commands.size >= 1024 && oldest !== void 0) this.commands.delete(oldest);
|
|
54408
|
-
this.commands.set(id, { controllerId, channelId, at: this.now() });
|
|
54408
|
+
this.commands.set(id, { controllerId, channelId: channelId2, at: this.now() });
|
|
54409
54409
|
}
|
|
54410
54410
|
commandFailed(id, status) {
|
|
54411
54411
|
this.prune();
|
|
@@ -54522,15 +54522,15 @@ var WagoDiagnosticsStore = class {
|
|
|
54522
54522
|
state.hardwareAvailable = hardwareAvailable;
|
|
54523
54523
|
state.stateSourceAt = canonical ? data.timestamp : void 0;
|
|
54524
54524
|
if (data.outputs && typeof data.outputs === "object" && !Array.isArray(data.outputs)) {
|
|
54525
|
-
for (const [
|
|
54526
|
-
if (identifier(
|
|
54527
|
-
state.outputs[
|
|
54525
|
+
for (const [channelId2, value] of Object.entries(data.outputs).slice(0, MAX_CHANNELS)) {
|
|
54526
|
+
if (identifier(channelId2) && typeof value === "boolean")
|
|
54527
|
+
state.outputs[channelId2] = { kind: "output", value, ...metadata2 };
|
|
54528
54528
|
}
|
|
54529
54529
|
}
|
|
54530
54530
|
if (isObject(data.inputs))
|
|
54531
|
-
for (const [
|
|
54532
|
-
if (identifier(
|
|
54533
|
-
state.inputs[
|
|
54531
|
+
for (const [channelId2, value] of Object.entries(data.inputs).slice(0, MAX_CHANNELS)) {
|
|
54532
|
+
if (identifier(channelId2) && typeof value === "boolean")
|
|
54533
|
+
state.inputs[channelId2] = { kind: "input", value, ...metadata2 };
|
|
54534
54534
|
}
|
|
54535
54535
|
}
|
|
54536
54536
|
if (kind === "measurements" && identifier(data.channelId) && typeof data.value === "number" && Number.isFinite(data.value) && (canonical ? CANONICAL_UNITS : ["ampere", "volt", "watt", "percent"]).includes(data.unit)) {
|
|
@@ -54618,7 +54618,7 @@ var WagoService = class {
|
|
|
54618
54618
|
claimedController: (id) => this.claimedController(id),
|
|
54619
54619
|
getSettings: () => this.getSettings(),
|
|
54620
54620
|
appliedRevision: (id) => this.appliedRevision(id),
|
|
54621
|
-
onCommand: (controllerId,
|
|
54621
|
+
onCommand: (controllerId, channelId2, id) => this.diagnostics.command(controllerId, channelId2, id),
|
|
54622
54622
|
onCommandFailure: (id, status) => this.diagnostics.commandFailed(id, status)
|
|
54623
54623
|
}));
|
|
54624
54624
|
__publicField(this, "claimConfigurationLock", Promise.resolve());
|
|
@@ -54754,12 +54754,12 @@ var WagoService = class {
|
|
|
54754
54754
|
}
|
|
54755
54755
|
async getConfigurationBaseline(controllerId) {
|
|
54756
54756
|
await this.claimedController(controllerId);
|
|
54757
|
-
const [
|
|
54757
|
+
const [revision2] = await this.revisions.find({
|
|
54758
54758
|
where: { controllerId, state: "applied" },
|
|
54759
54759
|
order: { revision: "DESC" },
|
|
54760
54760
|
take: 1
|
|
54761
54761
|
});
|
|
54762
|
-
return
|
|
54762
|
+
return revision2 ?? null;
|
|
54763
54763
|
}
|
|
54764
54764
|
async saveDraft(controllerId, snapshot, metadata2, principal, expectedDraft) {
|
|
54765
54765
|
return this.withConfigurationLock(controllerId, async () => {
|
|
@@ -54953,12 +54953,12 @@ var WagoService = class {
|
|
|
54953
54953
|
() => this.publishDraftWhileLocked(controllerId, force, reviewedHash, principal)
|
|
54954
54954
|
);
|
|
54955
54955
|
}
|
|
54956
|
-
async rollback(controllerId,
|
|
54956
|
+
async rollback(controllerId, revision2, force = false, sourceHash, currentHash, draftHash, principal) {
|
|
54957
54957
|
return this.withConfigurationLock(controllerId, async () => {
|
|
54958
54958
|
const controller = await this.claimedController(controllerId);
|
|
54959
54959
|
this.requireConfigurationCompatibility(controller);
|
|
54960
|
-
const source = await this.revisions.findOneBy({ controllerId, revision });
|
|
54961
|
-
if (!source) throw new import_common3.NotFoundException(`WAGO configuration revision ${
|
|
54960
|
+
const source = await this.revisions.findOneBy({ controllerId, revision: revision2 });
|
|
54961
|
+
if (!source) throw new import_common3.NotFoundException(`WAGO configuration revision ${revision2} not found`);
|
|
54962
54962
|
const current = await this.latestRevision(controllerId);
|
|
54963
54963
|
const draft = await this.drafts.findOneBy({ controllerId });
|
|
54964
54964
|
const snapshot = JSON.parse(source.snapshot);
|
|
@@ -54981,7 +54981,7 @@ var WagoService = class {
|
|
|
54981
54981
|
impacts: approvedImpacts
|
|
54982
54982
|
});
|
|
54983
54983
|
let allocatedRevision;
|
|
54984
|
-
const lifecycle = principal ? new WagoAudit(this.context).begin(principal, controllerId, "rollback", { sourceRevision:
|
|
54984
|
+
const lifecycle = principal ? new WagoAudit(this.context).begin(principal, controllerId, "rollback", { sourceRevision: revision2 }) : void 0;
|
|
54985
54985
|
const persist = async () => {
|
|
54986
54986
|
assertPreview(
|
|
54987
54987
|
await configurationFlowImpacts(
|
|
@@ -55015,11 +55015,11 @@ var WagoService = class {
|
|
|
55015
55015
|
return this.auditRevision(lifecycle, persist, () => allocatedRevision);
|
|
55016
55016
|
});
|
|
55017
55017
|
}
|
|
55018
|
-
async acknowledgeRejection(controllerId,
|
|
55018
|
+
async acknowledgeRejection(controllerId, revision2, expected, principal) {
|
|
55019
55019
|
return this.withConfigurationLock(controllerId, async () => {
|
|
55020
55020
|
await this.claimedController(controllerId);
|
|
55021
|
-
const rejected = await this.revisions.findOneBy({ controllerId, revision });
|
|
55022
|
-
if (!rejected) throw new import_common3.NotFoundException(`WAGO configuration revision ${
|
|
55021
|
+
const rejected = await this.revisions.findOneBy({ controllerId, revision: revision2 });
|
|
55022
|
+
if (!rejected) throw new import_common3.NotFoundException(`WAGO configuration revision ${revision2} not found`);
|
|
55023
55023
|
if (rejected.state !== "rejected" || !rejected.reportedAt || expected.contentHash !== rejected.contentHash || expected.reportedAt !== rejected.reportedAt)
|
|
55024
55024
|
throw new import_common3.ConflictException("rejection changed; refresh and review it before acknowledging");
|
|
55025
55025
|
if (rejected.rejectionAcknowledgedAt) return rejected;
|
|
@@ -55027,7 +55027,7 @@ var WagoService = class {
|
|
|
55027
55027
|
principal,
|
|
55028
55028
|
controllerId,
|
|
55029
55029
|
"rejection_acknowledgement",
|
|
55030
|
-
{ revision },
|
|
55030
|
+
{ revision: revision2 },
|
|
55031
55031
|
async () => {
|
|
55032
55032
|
return this.revisions.save({
|
|
55033
55033
|
...rejected,
|
|
@@ -55038,11 +55038,11 @@ var WagoService = class {
|
|
|
55038
55038
|
);
|
|
55039
55039
|
});
|
|
55040
55040
|
}
|
|
55041
|
-
async previewRevision(controllerId,
|
|
55041
|
+
async previewRevision(controllerId, revision2) {
|
|
55042
55042
|
return this.withConfigurationLock(controllerId, async () => {
|
|
55043
55043
|
await this.claimedController(controllerId);
|
|
55044
|
-
const selected = await this.revisions.findOneBy({ controllerId, revision });
|
|
55045
|
-
if (!selected) throw new import_common3.NotFoundException(`WAGO configuration revision ${
|
|
55044
|
+
const selected = await this.revisions.findOneBy({ controllerId, revision: revision2 });
|
|
55045
|
+
if (!selected) throw new import_common3.NotFoundException(`WAGO configuration revision ${revision2} not found`);
|
|
55046
55046
|
const [current] = await this.revisions.find({ where: { controllerId }, order: { revision: "DESC" }, take: 1 });
|
|
55047
55047
|
const draft = await this.drafts.findOneBy({ controllerId });
|
|
55048
55048
|
const impacts = await configurationFlowImpacts(
|
|
@@ -55064,8 +55064,8 @@ var WagoService = class {
|
|
|
55064
55064
|
};
|
|
55065
55065
|
});
|
|
55066
55066
|
}
|
|
55067
|
-
revisionIdentity(
|
|
55068
|
-
return
|
|
55067
|
+
revisionIdentity(revision2) {
|
|
55068
|
+
return revision2 ? { revision: revision2.revision, contentHash: revision2.contentHash, metadata: revision2.presetProvenance ?? null } : null;
|
|
55069
55069
|
}
|
|
55070
55070
|
impactIdentity(impacts) {
|
|
55071
55071
|
return impacts.map((impact) => ({
|
|
@@ -55184,17 +55184,17 @@ var WagoService = class {
|
|
|
55184
55184
|
if (impacts.length && !force)
|
|
55185
55185
|
throw new import_common3.ConflictException({ message: "acknowledge potential flow impacts before publishing", impacts });
|
|
55186
55186
|
let allocatedRevision;
|
|
55187
|
-
const dispatch = (
|
|
55188
|
-
allocatedRevision =
|
|
55189
|
-
onAllocated?.(
|
|
55190
|
-
return this.publishRevision(controller,
|
|
55187
|
+
const dispatch = (revision2) => {
|
|
55188
|
+
allocatedRevision = revision2.revision;
|
|
55189
|
+
onAllocated?.(revision2.revision);
|
|
55190
|
+
return this.publishRevision(controller, revision2);
|
|
55191
55191
|
};
|
|
55192
55192
|
const lifecycle = principal ? new WagoAudit(this.context).begin(principal, controllerId, force ? "forced_publication" : "publication") : void 0;
|
|
55193
55193
|
const persist = async () => {
|
|
55194
55194
|
if (preparedDraft) await this.drafts.save(preparedDraft);
|
|
55195
55195
|
if (previous?.state === "pending" && previous.contentHash === contentHash && (previous.presetProvenance ?? null) === (draft.presetProvenance ?? null))
|
|
55196
55196
|
return dispatch(previous);
|
|
55197
|
-
const
|
|
55197
|
+
const revision2 = this.revisions.create({
|
|
55198
55198
|
controllerId,
|
|
55199
55199
|
revision: (previous?.revision ?? 0) + 1,
|
|
55200
55200
|
snapshot: draft.snapshot,
|
|
@@ -55205,7 +55205,7 @@ var WagoService = class {
|
|
|
55205
55205
|
publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
55206
55206
|
reportedAt: null
|
|
55207
55207
|
});
|
|
55208
|
-
return dispatch(await this.revisions.save(
|
|
55208
|
+
return dispatch(await this.revisions.save(revision2));
|
|
55209
55209
|
};
|
|
55210
55210
|
return this.auditRevision(lifecycle, persist, () => allocatedRevision);
|
|
55211
55211
|
}
|
|
@@ -55221,8 +55221,8 @@ var WagoService = class {
|
|
|
55221
55221
|
}
|
|
55222
55222
|
}
|
|
55223
55223
|
async latestRevision(controllerId) {
|
|
55224
|
-
const [
|
|
55225
|
-
return
|
|
55224
|
+
const [revision2] = await this.revisions.find({ where: { controllerId }, order: { revision: "DESC" }, take: 1 });
|
|
55225
|
+
return revision2 ?? null;
|
|
55226
55226
|
}
|
|
55227
55227
|
async createEnrollment(hardwareId, mqttServerId, manualCredentials, assertOwned = async () => void 0) {
|
|
55228
55228
|
const normalizedHardwareId = hardwareId.trim();
|
|
@@ -55861,13 +55861,13 @@ var WagoService = class {
|
|
|
55861
55861
|
return;
|
|
55862
55862
|
}
|
|
55863
55863
|
await this.withConfigurationLock(controllerId, async () => {
|
|
55864
|
-
const
|
|
55865
|
-
if (!
|
|
55866
|
-
if (
|
|
55867
|
-
|
|
55868
|
-
|
|
55869
|
-
|
|
55870
|
-
await this.revisions.save(
|
|
55864
|
+
const revision2 = await this.revisions.findOneBy({ controllerId, revision: report.revision });
|
|
55865
|
+
if (!revision2 || revision2.contentHash !== report.contentHash) return;
|
|
55866
|
+
if (revision2.state !== "published") return;
|
|
55867
|
+
revision2.state = report.errors.length ? "rejected" : "applied";
|
|
55868
|
+
revision2.rejectionErrors = report.errors.length ? JSON.stringify(report.errors) : null;
|
|
55869
|
+
revision2.reportedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
55870
|
+
await this.revisions.save(revision2);
|
|
55871
55871
|
});
|
|
55872
55872
|
}
|
|
55873
55873
|
onCommandAcknowledgement(controllerId, payload) {
|
|
@@ -55877,8 +55877,8 @@ var WagoService = class {
|
|
|
55877
55877
|
const queue = this.configurationReportQueues.get(controllerId) ?? { pending: /* @__PURE__ */ new Map(), processing: false };
|
|
55878
55878
|
this.configurationReportQueues.set(controllerId, queue);
|
|
55879
55879
|
if (queue.processing) {
|
|
55880
|
-
const
|
|
55881
|
-
const key =
|
|
55880
|
+
const revision2 = this.configurationReportRevision(payload);
|
|
55881
|
+
const key = revision2 ?? Number.NaN;
|
|
55882
55882
|
if (queue.pending.has(key) || queue.pending.size < MAX_PENDING_CONFIGURATION_REPORTS)
|
|
55883
55883
|
queue.pending.set(key, payload);
|
|
55884
55884
|
else this.context.logger.warn(`Dropping excess WAGO configuration report for controller ${controllerId}`);
|
|
@@ -55898,8 +55898,8 @@ var WagoService = class {
|
|
|
55898
55898
|
const pending = queue.pending.entries().next();
|
|
55899
55899
|
if (pending.done) next = null;
|
|
55900
55900
|
else {
|
|
55901
|
-
const [
|
|
55902
|
-
queue.pending.delete(
|
|
55901
|
+
const [revision2, report] = pending.value;
|
|
55902
|
+
queue.pending.delete(revision2);
|
|
55903
55903
|
next = report;
|
|
55904
55904
|
}
|
|
55905
55905
|
}
|
|
@@ -55914,7 +55914,7 @@ var WagoService = class {
|
|
|
55914
55914
|
return null;
|
|
55915
55915
|
}
|
|
55916
55916
|
}
|
|
55917
|
-
async publishRevision(controller,
|
|
55917
|
+
async publishRevision(controller, revision2) {
|
|
55918
55918
|
if (!controller.mqttServerId) throw new import_common3.ConflictException(`WAGO controller ${controller.id} has no MQTT server`);
|
|
55919
55919
|
const incompatibility = compatibilityError({
|
|
55920
55920
|
protocolVersion: controller.protocolVersion,
|
|
@@ -55927,14 +55927,14 @@ var WagoService = class {
|
|
|
55927
55927
|
configurationDesiredTopic(settings.operationalPrefix ?? "attraccess/wago", controller.hardwareId),
|
|
55928
55928
|
JSON.stringify({
|
|
55929
55929
|
protocolVersion: CONFIGURATION_PROTOCOL_VERSION,
|
|
55930
|
-
revision:
|
|
55931
|
-
contentHash:
|
|
55932
|
-
snapshot: JSON.parse(
|
|
55930
|
+
revision: revision2.revision,
|
|
55931
|
+
contentHash: revision2.contentHash,
|
|
55932
|
+
snapshot: JSON.parse(revision2.snapshot)
|
|
55933
55933
|
}),
|
|
55934
55934
|
{ qos: 1, retain: true }
|
|
55935
55935
|
);
|
|
55936
|
-
|
|
55937
|
-
return this.revisions.save(
|
|
55936
|
+
revision2.state = "published";
|
|
55937
|
+
return this.revisions.save(revision2);
|
|
55938
55938
|
}
|
|
55939
55939
|
connectivity(controller) {
|
|
55940
55940
|
if (controller.trustState === "untrusted") return "untrusted";
|
|
@@ -55942,12 +55942,12 @@ var WagoService = class {
|
|
|
55942
55942
|
return freshness(heartbeatAt, Date.now(), STALE_AFTER_MS) === "fresh" ? "online" : "stale";
|
|
55943
55943
|
}
|
|
55944
55944
|
async appliedRevision(controllerId) {
|
|
55945
|
-
const [
|
|
55945
|
+
const [revision2] = await this.revisions.find({
|
|
55946
55946
|
where: { controllerId, state: "applied" },
|
|
55947
55947
|
order: { revision: "DESC" },
|
|
55948
55948
|
take: 1
|
|
55949
55949
|
});
|
|
55950
|
-
return
|
|
55950
|
+
return revision2 ?? null;
|
|
55951
55951
|
}
|
|
55952
55952
|
matchesVerifier(controller, verifier) {
|
|
55953
55953
|
const value = verifier.trim();
|
|
@@ -57008,11 +57008,11 @@ var WagoCredentialRotationService = class {
|
|
|
57008
57008
|
try {
|
|
57009
57009
|
let row = previous;
|
|
57010
57010
|
if (!retry) {
|
|
57011
|
-
const
|
|
57012
|
-
if (!Number.isSafeInteger(
|
|
57011
|
+
const revision2 = (previous?.revision ?? 0) + 1;
|
|
57012
|
+
if (!Number.isSafeInteger(revision2)) throw new import_common4.ConflictException("Credential rotation revision exhausted.");
|
|
57013
57013
|
row = this.repository.create({
|
|
57014
57014
|
controllerId,
|
|
57015
|
-
revision,
|
|
57015
|
+
revision: revision2,
|
|
57016
57016
|
credentialEpoch,
|
|
57017
57017
|
phase: "provisioning",
|
|
57018
57018
|
mqttServerId: controller.mqttServerId,
|
|
@@ -57146,7 +57146,7 @@ async function commissioningVerification(context, session, runtime) {
|
|
|
57146
57146
|
mqttServerId: session.mqttServerId
|
|
57147
57147
|
});
|
|
57148
57148
|
const enrollment = session.enrollmentId === null ? null : await context.getRepository(WagoEnrollment).findOneBy({ id: session.enrollmentId });
|
|
57149
|
-
const
|
|
57149
|
+
const revision2 = controller ? await context.getRepository(WagoConfigurationRevision).findOne({
|
|
57150
57150
|
where: { controllerId: controller.id },
|
|
57151
57151
|
order: { revision: "DESC" }
|
|
57152
57152
|
}) : null;
|
|
@@ -57157,7 +57157,7 @@ async function commissioningVerification(context, session, runtime) {
|
|
|
57157
57157
|
const runtimeFresh = Boolean(
|
|
57158
57158
|
runtime && runtime.timestamp >= Date.parse(session.createdAt) && Date.now() - runtime.timestamp < 9e4 && runtime.timestamp <= Date.now()
|
|
57159
57159
|
);
|
|
57160
|
-
const hardwareReadiness = !runtime ? "unverified" : !runtimeFresh ? "stale" : runtime.connected && runtime.ready && runtime.hardwareAvailable && runtime.configurationAccepted &&
|
|
57160
|
+
const hardwareReadiness = !runtime ? "unverified" : !runtimeFresh ? "stale" : runtime.connected && runtime.ready && runtime.hardwareAvailable && runtime.configurationAccepted && revision2?.state === "applied" && runtime.revision === revision2.revision && runtime.contentHash === revision2.contentHash ? "ready" : "not_ready";
|
|
57161
57161
|
return {
|
|
57162
57162
|
controllerId: controller?.trustState === "claimed" && controller.enrollmentId === session.enrollmentId ? controller.id : null,
|
|
57163
57163
|
permanentConnection,
|
|
@@ -57165,7 +57165,7 @@ async function commissioningVerification(context, session, runtime) {
|
|
|
57165
57165
|
enrollment?.revokedAt && enrollment.hardwareId === session.hardwareId && enrollment.mqttServerId === session.mqttServerId
|
|
57166
57166
|
),
|
|
57167
57167
|
configurationApplied: Boolean(
|
|
57168
|
-
|
|
57168
|
+
revision2?.state === "applied" && revision2.reportedAt && Date.parse(revision2.reportedAt) >= Date.parse(session.createdAt)
|
|
57169
57169
|
),
|
|
57170
57170
|
// No qualified firmware-31 management transition or hardware health evidence exists yet.
|
|
57171
57171
|
// Never turn a successful claim publication into a hardened-device success signal.
|
|
@@ -61964,10 +61964,10 @@ var WagoControllerApi = class {
|
|
|
61964
61964
|
publishDraft(id, request, body) {
|
|
61965
61965
|
return this.wago.publishDraft(id, body?.force === true, body?.reviewedHash, wagoAuditPrincipal(request));
|
|
61966
61966
|
}
|
|
61967
|
-
rollback(id,
|
|
61967
|
+
rollback(id, revision2, request, body) {
|
|
61968
61968
|
return this.wago.rollback(
|
|
61969
61969
|
id,
|
|
61970
|
-
|
|
61970
|
+
revision2,
|
|
61971
61971
|
body?.force === true,
|
|
61972
61972
|
body?.sourceHash,
|
|
61973
61973
|
body?.currentHash,
|
|
@@ -61975,11 +61975,11 @@ var WagoControllerApi = class {
|
|
|
61975
61975
|
wagoAuditPrincipal(request)
|
|
61976
61976
|
);
|
|
61977
61977
|
}
|
|
61978
|
-
acknowledgeRejection(id,
|
|
61979
|
-
return this.wago.acknowledgeRejection(id,
|
|
61978
|
+
acknowledgeRejection(id, revision2, request, body) {
|
|
61979
|
+
return this.wago.acknowledgeRejection(id, revision2, body ?? {}, wagoAuditPrincipal(request));
|
|
61980
61980
|
}
|
|
61981
|
-
previewRevision(id,
|
|
61982
|
-
return this.wago.previewRevision(id,
|
|
61981
|
+
previewRevision(id, revision2) {
|
|
61982
|
+
return this.wago.previewRevision(id, revision2);
|
|
61983
61983
|
}
|
|
61984
61984
|
};
|
|
61985
61985
|
__decorateClass([
|
|
@@ -62430,19 +62430,19 @@ var import_plugins_backend_sdk17 = require("@attraccess/plugins-backend-sdk");
|
|
|
62430
62430
|
function own(values, key) {
|
|
62431
62431
|
return Object.prototype.hasOwnProperty.call(values, key) ? values[key] : void 0;
|
|
62432
62432
|
}
|
|
62433
|
-
function diagnosticReferences(nodes, channelIds,
|
|
62433
|
+
function diagnosticReferences(nodes, channelIds, revision2, capabilities) {
|
|
62434
62434
|
return nodes.map((node) => {
|
|
62435
|
-
const
|
|
62435
|
+
const channelId2 = typeof node.data.channelId === "string" ? node.data.channelId : "";
|
|
62436
62436
|
const control = node.type === "plugin.wago.command";
|
|
62437
62437
|
return {
|
|
62438
62438
|
nodeId: node.id,
|
|
62439
62439
|
resourceId: node.resourceId,
|
|
62440
|
-
channelId,
|
|
62440
|
+
channelId: channelId2,
|
|
62441
62441
|
control,
|
|
62442
62442
|
href: `/resources/${node.resourceId}/flows?node=${encodeURIComponent(node.id)}`,
|
|
62443
|
-
invalid: !channelIds.includes(
|
|
62443
|
+
invalid: !channelIds.includes(channelId2) || control && (node.data.expectedConfigurationRevision !== revision2 || capabilities && (!own(capabilities, channelId2)?.includes("output") || node.data.action === "pulse" && !own(capabilities, channelId2)?.includes("pulse"))),
|
|
62444
62444
|
conflict: control && nodes.some(
|
|
62445
|
-
(other) => other.type === "plugin.wago.command" && other.resourceId !== node.resourceId && other.data.channelId ===
|
|
62445
|
+
(other) => other.type === "plugin.wago.command" && other.resourceId !== node.resourceId && other.data.channelId === channelId2
|
|
62446
62446
|
)
|
|
62447
62447
|
};
|
|
62448
62448
|
});
|
|
@@ -62470,7 +62470,7 @@ var WagoDiagnosticsService = class {
|
|
|
62470
62470
|
const localNodes = nodes.slice(0, 1e3);
|
|
62471
62471
|
const localChannelIds = [
|
|
62472
62472
|
...new Set(
|
|
62473
|
-
localNodes.map((node) => node.data.channelId).filter((
|
|
62473
|
+
localNodes.map((node) => node.data.channelId).filter((channelId2) => typeof channelId2 === "string")
|
|
62474
62474
|
)
|
|
62475
62475
|
];
|
|
62476
62476
|
const controllerIdsForQuery = selectedControllerIds;
|
|
@@ -62482,7 +62482,7 @@ var WagoDiagnosticsService = class {
|
|
|
62482
62482
|
localChannelIds.length ? this.context.dataSource.getRepository(import_plugins_backend_sdk17.ResourceFlowNode).createQueryBuilder("node").where("node.data ->> 'controllerId' IN (:...controllerIds)", { controllerIds: controllerIdsForQuery }).andWhere("node.data ->> 'channelId' IN (:...channelIds)", { channelIds: localChannelIds }).andWhere("node.type = :type", { type: "plugin.wago.command" }).take(1001).getMany() : Promise.resolve([])
|
|
62483
62483
|
]);
|
|
62484
62484
|
const controllersById = new Map(controllers.map((controller) => [controller.id, controller]));
|
|
62485
|
-
const appliedByControllerId = new Map(appliedRevisions.map((
|
|
62485
|
+
const appliedByControllerId = new Map(appliedRevisions.map((revision2) => [revision2.controllerId, revision2]));
|
|
62486
62486
|
const referencesTruncated = conflictNodes.length > 1e3;
|
|
62487
62487
|
const conflictNodesByControllerId = /* @__PURE__ */ new Map();
|
|
62488
62488
|
for (const node of conflictNodes.slice(0, 1e3)) {
|
|
@@ -62620,7 +62620,7 @@ var WagoDiagnosticsService = class {
|
|
|
62620
62620
|
acknowledgement: own(runtime.acknowledgements, channel.id) ?? null
|
|
62621
62621
|
};
|
|
62622
62622
|
}),
|
|
62623
|
-
faults: Object.entries(runtime.faults).map(([
|
|
62623
|
+
faults: Object.entries(runtime.faults).map(([channelId2, fault]) => ({ channelId: channelId2, ...fault })),
|
|
62624
62624
|
references,
|
|
62625
62625
|
referencesTruncated: nodes.length > 1e3,
|
|
62626
62626
|
events: runtime.events,
|
|
@@ -62804,7 +62804,7 @@ var WagoFlowService = class {
|
|
|
62804
62804
|
for (const id of this.streams.keys()) if (!controllerIds.has(id)) this.streams.delete(id);
|
|
62805
62805
|
this.channelCache.clear();
|
|
62806
62806
|
const revisions = await this.loadLatestAppliedRevisions(controllers.map((controller) => controller.id));
|
|
62807
|
-
for (const
|
|
62807
|
+
for (const revision2 of revisions) this.cacheChannels(revision2);
|
|
62808
62808
|
for (const controller of controllers)
|
|
62809
62809
|
if (!this.channelCache.has(controller.id)) this.channelCache.set(controller.id, []);
|
|
62810
62810
|
const validChannels = new Map(
|
|
@@ -62851,7 +62851,7 @@ var WagoFlowService = class {
|
|
|
62851
62851
|
() => this.controllers.find({ where: { trustState: "claimed" }, order: { name: "ASC" } })
|
|
62852
62852
|
);
|
|
62853
62853
|
const selected = typeof config.controllerId === "number" ? controllers.find((controller) => controller.id === config.controllerId) : void 0;
|
|
62854
|
-
const
|
|
62854
|
+
const revision2 = selected ? await this.cached(validationContext, `wago-applied-revision:${selected.id}`, async () => {
|
|
62855
62855
|
const [latest] = await this.revisions.find({
|
|
62856
62856
|
where: { controllerId: selected.id, state: "applied" },
|
|
62857
62857
|
order: { revision: "DESC" },
|
|
@@ -62859,10 +62859,10 @@ var WagoFlowService = class {
|
|
|
62859
62859
|
});
|
|
62860
62860
|
return latest ?? null;
|
|
62861
62861
|
}) : null;
|
|
62862
|
-
const channels =
|
|
62862
|
+
const channels = revision2 ? JSON.parse(revision2.snapshot).logicalChannels : [];
|
|
62863
62863
|
let names = {};
|
|
62864
62864
|
try {
|
|
62865
|
-
names = JSON.parse(
|
|
62865
|
+
names = JSON.parse(revision2?.presetProvenance ?? "null")?.editor?.names ?? {};
|
|
62866
62866
|
} catch {
|
|
62867
62867
|
}
|
|
62868
62868
|
const channel = channels.find((item) => item.id === config.channelId);
|
|
@@ -62875,7 +62875,7 @@ var WagoFlowService = class {
|
|
|
62875
62875
|
const: controller.id,
|
|
62876
62876
|
title: controller.name ?? controller.hardwareId
|
|
62877
62877
|
})),
|
|
62878
|
-
description: selected && !
|
|
62878
|
+
description: selected && !revision2 ? "Publish a configuration and wait for the controller to apply it first." : void 0
|
|
62879
62879
|
},
|
|
62880
62880
|
channelId: {
|
|
62881
62881
|
type: "string",
|
|
@@ -63081,11 +63081,11 @@ var WagoFlowService = class {
|
|
|
63081
63081
|
this.store(controller, event.channelId, event, event.category === "measurement" ? event.value : event);
|
|
63082
63082
|
}
|
|
63083
63083
|
}
|
|
63084
|
-
store(controller,
|
|
63084
|
+
store(controller, channelId2, event, value) {
|
|
63085
63085
|
const state = {
|
|
63086
63086
|
controllerId: controller.id,
|
|
63087
63087
|
hardwareId: controller.hardwareId,
|
|
63088
|
-
channelId,
|
|
63088
|
+
channelId: channelId2,
|
|
63089
63089
|
category: event.category,
|
|
63090
63090
|
value,
|
|
63091
63091
|
timestamp: event.timestamp,
|
|
@@ -63097,7 +63097,7 @@ var WagoFlowService = class {
|
|
|
63097
63097
|
offline: this.offlineControllers.has(controller.id),
|
|
63098
63098
|
invalidated: this.unavailableHardware.has(controller.id) || this.unavailableConfiguration.has(controller.id) || Date.parse(event.timestamp) < (this.streams.get(controller.id)?.sampleNotBefore ?? 0)
|
|
63099
63099
|
};
|
|
63100
|
-
const cacheKey = this.cacheKey(controller.id,
|
|
63100
|
+
const cacheKey = this.cacheKey(controller.id, channelId2, event.category);
|
|
63101
63101
|
const previous = this.cache.get(cacheKey);
|
|
63102
63102
|
this.cache.set(cacheKey, state);
|
|
63103
63103
|
if (this.cache.size > MAX_CACHE_ENTRIES) {
|
|
@@ -63115,16 +63115,16 @@ var WagoFlowService = class {
|
|
|
63115
63115
|
async channels(controllerId) {
|
|
63116
63116
|
const cached = this.channelCache.get(controllerId);
|
|
63117
63117
|
if (cached) return cached;
|
|
63118
|
-
const [
|
|
63118
|
+
const [revision2] = await this.revisions.find({
|
|
63119
63119
|
where: { controllerId, state: "applied" },
|
|
63120
63120
|
order: { revision: "DESC" },
|
|
63121
63121
|
take: 1
|
|
63122
63122
|
});
|
|
63123
|
-
if (!
|
|
63123
|
+
if (!revision2) {
|
|
63124
63124
|
this.channelCache.set(controllerId, []);
|
|
63125
63125
|
return [];
|
|
63126
63126
|
}
|
|
63127
|
-
return this.cacheChannels(
|
|
63127
|
+
return this.cacheChannels(revision2);
|
|
63128
63128
|
}
|
|
63129
63129
|
async loadLatestAppliedRevisions(controllerIds) {
|
|
63130
63130
|
if (!controllerIds.length) return [];
|
|
@@ -63134,28 +63134,28 @@ var WagoFlowService = class {
|
|
|
63134
63134
|
"latest.controllerId = revision.controllerId AND latest.revision = revision.revision"
|
|
63135
63135
|
).where("revision.state = :state", { state: "applied" }).getMany();
|
|
63136
63136
|
}
|
|
63137
|
-
cacheChannels(
|
|
63137
|
+
cacheChannels(revision2) {
|
|
63138
63138
|
try {
|
|
63139
|
-
const channels = JSON.parse(
|
|
63140
|
-
const previous = this.appliedConfigurations.get(
|
|
63141
|
-
if (previous?.revision !==
|
|
63142
|
-
this.unavailableConfiguration.add(
|
|
63139
|
+
const channels = JSON.parse(revision2.snapshot).logicalChannels;
|
|
63140
|
+
const previous = this.appliedConfigurations.get(revision2.controllerId);
|
|
63141
|
+
if (previous?.revision !== revision2.revision || previous?.contentHash !== revision2.contentHash) {
|
|
63142
|
+
this.unavailableConfiguration.add(revision2.controllerId);
|
|
63143
63143
|
for (const state of this.cache.values())
|
|
63144
|
-
if (state.controllerId ===
|
|
63144
|
+
if (state.controllerId === revision2.controllerId) state.invalidated = true;
|
|
63145
63145
|
}
|
|
63146
|
-
this.appliedConfigurations.set(
|
|
63147
|
-
revision:
|
|
63148
|
-
contentHash:
|
|
63146
|
+
this.appliedConfigurations.set(revision2.controllerId, {
|
|
63147
|
+
revision: revision2.revision,
|
|
63148
|
+
contentHash: revision2.contentHash
|
|
63149
63149
|
});
|
|
63150
|
-
this.channelCache.set(
|
|
63150
|
+
this.channelCache.set(revision2.controllerId, channels);
|
|
63151
63151
|
return channels;
|
|
63152
63152
|
} catch {
|
|
63153
|
-
this.channelCache.set(
|
|
63153
|
+
this.channelCache.set(revision2.controllerId, []);
|
|
63154
63154
|
return [];
|
|
63155
63155
|
}
|
|
63156
63156
|
}
|
|
63157
|
-
cacheKey(controllerId,
|
|
63158
|
-
return `${controllerId}:${
|
|
63157
|
+
cacheKey(controllerId, channelId2, category) {
|
|
63158
|
+
return `${controllerId}:${channelId2}:${category}`;
|
|
63159
63159
|
}
|
|
63160
63160
|
categories(channel) {
|
|
63161
63161
|
return [
|
|
@@ -63230,6 +63230,94 @@ WagoFlowService = __decorateClass([
|
|
|
63230
63230
|
__decorateParam(0, (0, import_common13.Inject)(PLUGIN_CONTEXT5))
|
|
63231
63231
|
], WagoFlowService);
|
|
63232
63232
|
|
|
63233
|
+
// backend/wago-audit-policy.ts
|
|
63234
|
+
var summaryFields = {
|
|
63235
|
+
"before.physicalPointCount": { type: "number", integer: true, min: 0 },
|
|
63236
|
+
"before.logicalChannelCount": { type: "number", integer: true, min: 0 },
|
|
63237
|
+
"after.physicalPointCount": { type: "number", integer: true, min: 0 },
|
|
63238
|
+
"after.logicalChannelCount": { type: "number", integer: true, min: 0 }
|
|
63239
|
+
};
|
|
63240
|
+
var revision = { type: "number", integer: true, min: 1 };
|
|
63241
|
+
var channelId = { type: "string", pattern: "[a-zA-Z0-9_-]{1,64}" };
|
|
63242
|
+
var uuidPattern2 = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}";
|
|
63243
|
+
var controllerActions = [
|
|
63244
|
+
{ action: "wago.claim", subjectTypes: ["wago.controller"] },
|
|
63245
|
+
{ action: "wago.unclaim", subjectTypes: ["wago.controller"] },
|
|
63246
|
+
{ action: "wago.credential_rotation", subjectTypes: ["wago.controller"] },
|
|
63247
|
+
{ action: "wago.manual_credential_fallback", subjectTypes: ["wago.controller"] },
|
|
63248
|
+
{ action: "wago.publication", subjectTypes: ["wago.controller"], details: { revision } },
|
|
63249
|
+
{ action: "wago.forced_publication", subjectTypes: ["wago.controller"], details: { revision } },
|
|
63250
|
+
{
|
|
63251
|
+
action: "wago.rollback",
|
|
63252
|
+
subjectTypes: ["wago.controller"],
|
|
63253
|
+
details: { sourceRevision: revision, revision }
|
|
63254
|
+
},
|
|
63255
|
+
{ action: "wago.rejection_acknowledgement", subjectTypes: ["wago.controller"], details: { revision } },
|
|
63256
|
+
{
|
|
63257
|
+
action: "wago.preset_application",
|
|
63258
|
+
subjectTypes: ["wago.controller"],
|
|
63259
|
+
details: {
|
|
63260
|
+
presetId: { type: "string", oneOf: WAGO_PRESETS.map((preset) => preset.id) },
|
|
63261
|
+
channelId,
|
|
63262
|
+
...summaryFields
|
|
63263
|
+
}
|
|
63264
|
+
},
|
|
63265
|
+
{
|
|
63266
|
+
action: "wago.preset_reapplication",
|
|
63267
|
+
subjectTypes: ["wago.controller"],
|
|
63268
|
+
details: {
|
|
63269
|
+
presetId: { type: "string", oneOf: WAGO_PRESETS.map((preset) => preset.id) },
|
|
63270
|
+
channelId,
|
|
63271
|
+
...summaryFields
|
|
63272
|
+
}
|
|
63273
|
+
},
|
|
63274
|
+
{
|
|
63275
|
+
action: "wago.profile_creation",
|
|
63276
|
+
subjectTypes: ["wago.controller"],
|
|
63277
|
+
details: {
|
|
63278
|
+
profileId: { type: "string", maxLength: 160, pattern: "(?=[\\s\\S]*\\S)[\\s\\S]*" },
|
|
63279
|
+
profileVersion: { type: "number", integer: true, min: 1, max: 1e6 },
|
|
63280
|
+
...summaryFields
|
|
63281
|
+
}
|
|
63282
|
+
},
|
|
63283
|
+
{
|
|
63284
|
+
action: "wago.profile_change",
|
|
63285
|
+
subjectTypes: ["wago.controller"],
|
|
63286
|
+
details: {
|
|
63287
|
+
profileId: { type: "string", maxLength: 160, pattern: "(?=[\\s\\S]*\\S)[\\s\\S]*" },
|
|
63288
|
+
profileVersion: { type: "number", integer: true, min: 1, max: 1e6 },
|
|
63289
|
+
...summaryFields
|
|
63290
|
+
}
|
|
63291
|
+
},
|
|
63292
|
+
{
|
|
63293
|
+
action: "wago.manual_command",
|
|
63294
|
+
subjectTypes: ["wago.controller"],
|
|
63295
|
+
details: {
|
|
63296
|
+
channelId,
|
|
63297
|
+
commandId: { type: "string", pattern: uuidPattern2 },
|
|
63298
|
+
operation: { type: "string", oneOf: ["set", "pulse"] },
|
|
63299
|
+
result: { type: "string", oneOf: ["dispatched", "acknowledged", "rejected", "timeout", "transport_failure"] }
|
|
63300
|
+
}
|
|
63301
|
+
}
|
|
63302
|
+
];
|
|
63303
|
+
var commissioningActions = [
|
|
63304
|
+
"install",
|
|
63305
|
+
"recover",
|
|
63306
|
+
"security_inspect",
|
|
63307
|
+
"security_review",
|
|
63308
|
+
"security_apply",
|
|
63309
|
+
"security_recover",
|
|
63310
|
+
"platform_inspect",
|
|
63311
|
+
"platform_activate",
|
|
63312
|
+
"platform_recover",
|
|
63313
|
+
"lease_recover"
|
|
63314
|
+
].map((action) => ({ action: `wago.commissioning.${action}`, subjectTypes: ["wago.commissioning"] }));
|
|
63315
|
+
var WAGO_AUDIT_DOMAIN = {
|
|
63316
|
+
domain: "wago",
|
|
63317
|
+
labels: { en: "WAGO controllers", de: "WAGO-Controller" },
|
|
63318
|
+
actions: [...controllerActions, ...commissioningActions]
|
|
63319
|
+
};
|
|
63320
|
+
|
|
63233
63321
|
// backend/plugin.ts
|
|
63234
63322
|
var PLUGIN_CONTEXT6 = /* @__PURE__ */ Symbol.for("attraccess.plugin.context");
|
|
63235
63323
|
var WagoPluginModule = class {
|
|
@@ -63256,6 +63344,7 @@ var plugin = {
|
|
|
63256
63344
|
createWagoCommandNode(() => services(context).command),
|
|
63257
63345
|
...createWagoStateNodes(() => services(context).state)
|
|
63258
63346
|
],
|
|
63347
|
+
auditDomains: [WAGO_AUDIT_DOMAIN],
|
|
63259
63348
|
register(context) {
|
|
63260
63349
|
return {
|
|
63261
63350
|
module: WagoPluginModule,
|