@juhuu/sdk-ts 1.2.264 → 1.2.265
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.d.mts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +305 -0
- package/dist/index.mjs +305 -0
- package/package.json +3 -1
package/dist/index.d.mts
CHANGED
|
@@ -1697,6 +1697,14 @@ declare class FlowsService extends Service {
|
|
|
1697
1697
|
update(FlowUpdateParams: JUHUU.Flow.Update.Params, FlowUpdateOptions?: JUHUU.Flow.Update.Options): Promise<JUHUU.HttpResponse<JUHUU.Flow.Update.Response>>;
|
|
1698
1698
|
delete(FlowDeleteParams: JUHUU.Flow.Delete.Params, FlowDeleteOptions?: JUHUU.Flow.Delete.Options): Promise<JUHUU.HttpResponse<JUHUU.Flow.Delete.Response>>;
|
|
1699
1699
|
execute(FlowExecuteParams: JUHUU.Flow.Execute.Params, FlowExecuteOptions?: JUHUU.Flow.Execute.Options): Promise<JUHUU.HttpResponse<JUHUU.Flow.Execute.Response>>;
|
|
1700
|
+
private areInputsAvailable;
|
|
1701
|
+
private resolveInputs;
|
|
1702
|
+
private isInputConnected;
|
|
1703
|
+
private blockExecutors;
|
|
1704
|
+
executeLocally(flowId: string, context?: Record<string, any>): Promise<{
|
|
1705
|
+
output: Record<string, any>;
|
|
1706
|
+
logArray: FlowLog[];
|
|
1707
|
+
}>;
|
|
1700
1708
|
}
|
|
1701
1709
|
|
|
1702
1710
|
declare class FlowTracesService extends Service {
|
package/dist/index.d.ts
CHANGED
|
@@ -1697,6 +1697,14 @@ declare class FlowsService extends Service {
|
|
|
1697
1697
|
update(FlowUpdateParams: JUHUU.Flow.Update.Params, FlowUpdateOptions?: JUHUU.Flow.Update.Options): Promise<JUHUU.HttpResponse<JUHUU.Flow.Update.Response>>;
|
|
1698
1698
|
delete(FlowDeleteParams: JUHUU.Flow.Delete.Params, FlowDeleteOptions?: JUHUU.Flow.Delete.Options): Promise<JUHUU.HttpResponse<JUHUU.Flow.Delete.Response>>;
|
|
1699
1699
|
execute(FlowExecuteParams: JUHUU.Flow.Execute.Params, FlowExecuteOptions?: JUHUU.Flow.Execute.Options): Promise<JUHUU.HttpResponse<JUHUU.Flow.Execute.Response>>;
|
|
1700
|
+
private areInputsAvailable;
|
|
1701
|
+
private resolveInputs;
|
|
1702
|
+
private isInputConnected;
|
|
1703
|
+
private blockExecutors;
|
|
1704
|
+
executeLocally(flowId: string, context?: Record<string, any>): Promise<{
|
|
1705
|
+
output: Record<string, any>;
|
|
1706
|
+
logArray: FlowLog[];
|
|
1707
|
+
}>;
|
|
1700
1708
|
}
|
|
1701
1709
|
|
|
1702
1710
|
declare class FlowTracesService extends Service {
|
package/dist/index.js
CHANGED
|
@@ -3562,6 +3562,7 @@ var EmzService = class extends Service {
|
|
|
3562
3562
|
};
|
|
3563
3563
|
|
|
3564
3564
|
// src/flows/flows.service.ts
|
|
3565
|
+
var import_json_logic_js = __toESM(require("json-logic-js"));
|
|
3565
3566
|
var FlowsService = class extends Service {
|
|
3566
3567
|
constructor(config) {
|
|
3567
3568
|
super(config);
|
|
@@ -3655,6 +3656,310 @@ var FlowsService = class extends Service {
|
|
|
3655
3656
|
FlowExecuteOptions
|
|
3656
3657
|
);
|
|
3657
3658
|
}
|
|
3659
|
+
areInputsAvailable(block, outputStore, edgeArray) {
|
|
3660
|
+
if (block.in === null || block.in === void 0) {
|
|
3661
|
+
return true;
|
|
3662
|
+
}
|
|
3663
|
+
return Object.values(block.in).every((edgeId) => {
|
|
3664
|
+
const edge = edgeArray.find((e) => e.id === edgeId);
|
|
3665
|
+
if (edge === void 0) {
|
|
3666
|
+
return false;
|
|
3667
|
+
}
|
|
3668
|
+
if (edge.type === "control") {
|
|
3669
|
+
return true;
|
|
3670
|
+
}
|
|
3671
|
+
const srcOutputs = outputStore[edge.from.blockId];
|
|
3672
|
+
return srcOutputs !== null && srcOutputs !== void 0 && edge.from.output in srcOutputs;
|
|
3673
|
+
});
|
|
3674
|
+
}
|
|
3675
|
+
resolveInputs(block, outputStore, edgeArray) {
|
|
3676
|
+
const inputs = {};
|
|
3677
|
+
if (block.in === void 0) {
|
|
3678
|
+
return inputs;
|
|
3679
|
+
}
|
|
3680
|
+
for (const [inputName, edgeId] of Object.entries(block.in)) {
|
|
3681
|
+
const edge = edgeArray.find((e) => e.id === edgeId);
|
|
3682
|
+
if (edge === void 0) {
|
|
3683
|
+
throw new Error(
|
|
3684
|
+
`No edge found with id ${edgeId} for input ${inputName}`
|
|
3685
|
+
);
|
|
3686
|
+
}
|
|
3687
|
+
if (edge.type === "control") {
|
|
3688
|
+
continue;
|
|
3689
|
+
}
|
|
3690
|
+
const srcOutputs = outputStore[edge.from.blockId];
|
|
3691
|
+
if (srcOutputs === void 0 || edge.from.output in srcOutputs === false) {
|
|
3692
|
+
throw new Error(
|
|
3693
|
+
`Missing output '${edge.from.output}' from block '${edge.from.blockId}'`
|
|
3694
|
+
);
|
|
3695
|
+
}
|
|
3696
|
+
inputs[inputName] = srcOutputs[edge.from.output];
|
|
3697
|
+
}
|
|
3698
|
+
return inputs;
|
|
3699
|
+
}
|
|
3700
|
+
isInputConnected(block, inputName) {
|
|
3701
|
+
if (block.in === void 0 || block.in === null) {
|
|
3702
|
+
return false;
|
|
3703
|
+
}
|
|
3704
|
+
return block.in[inputName] !== void 0;
|
|
3705
|
+
}
|
|
3706
|
+
blockExecutors = {
|
|
3707
|
+
"start.custom": async (_inputs, block, context) => {
|
|
3708
|
+
if (block.type !== "start.custom") {
|
|
3709
|
+
throw new Error(
|
|
3710
|
+
`Invalid block type '${block.type}' for start.custom executor`
|
|
3711
|
+
);
|
|
3712
|
+
}
|
|
3713
|
+
const defs = block.data.inputParamDefinitionArray ?? [];
|
|
3714
|
+
if (defs.length === 0) {
|
|
3715
|
+
return { output: {} };
|
|
3716
|
+
}
|
|
3717
|
+
const outputs = {};
|
|
3718
|
+
for (const param of defs) {
|
|
3719
|
+
const value = context[param.name];
|
|
3720
|
+
if (value === void 0 && param.required) {
|
|
3721
|
+
throw new Error(
|
|
3722
|
+
`Missing required input parameter '${param.name}'`
|
|
3723
|
+
);
|
|
3724
|
+
}
|
|
3725
|
+
outputs[param.name] = value;
|
|
3726
|
+
}
|
|
3727
|
+
return {
|
|
3728
|
+
output: outputs
|
|
3729
|
+
};
|
|
3730
|
+
},
|
|
3731
|
+
"control.if": async (inputs, block) => {
|
|
3732
|
+
const fb = block;
|
|
3733
|
+
const result = import_json_logic_js.default.apply(fb.data.condition, inputs);
|
|
3734
|
+
return {
|
|
3735
|
+
output: {},
|
|
3736
|
+
flowBranch: result === true ? "true" : "false"
|
|
3737
|
+
};
|
|
3738
|
+
},
|
|
3739
|
+
"flow.execute": async (inputs, block) => {
|
|
3740
|
+
const fb = block;
|
|
3741
|
+
const finalFlowId = this.isInputConnected(fb, "flowId") ? inputs.flowId : fb.data?.flowId;
|
|
3742
|
+
if (finalFlowId === void 0 || finalFlowId === null) {
|
|
3743
|
+
throw new Error(
|
|
3744
|
+
`Missing required input 'flowId' for block type '${block.type}'`
|
|
3745
|
+
);
|
|
3746
|
+
}
|
|
3747
|
+
const execInput = {};
|
|
3748
|
+
for (const [key, value] of Object.entries(
|
|
3749
|
+
inputs
|
|
3750
|
+
)) {
|
|
3751
|
+
if (key === "flowId") {
|
|
3752
|
+
continue;
|
|
3753
|
+
}
|
|
3754
|
+
execInput[key] = value;
|
|
3755
|
+
}
|
|
3756
|
+
const { output } = await this.executeLocally(finalFlowId, execInput);
|
|
3757
|
+
return { output };
|
|
3758
|
+
},
|
|
3759
|
+
"end.custom": async (inputs) => {
|
|
3760
|
+
return { output: { ...inputs } };
|
|
3761
|
+
},
|
|
3762
|
+
// Placeholder implementations for other block types (they will throw errors if used)
|
|
3763
|
+
"start.quickAction.location": async () => {
|
|
3764
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3765
|
+
},
|
|
3766
|
+
"start.session.update": async () => {
|
|
3767
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3768
|
+
},
|
|
3769
|
+
"start.location.update": async () => {
|
|
3770
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3771
|
+
},
|
|
3772
|
+
"start.parameter.update": async () => {
|
|
3773
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3774
|
+
},
|
|
3775
|
+
"const.number": async () => {
|
|
3776
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3777
|
+
},
|
|
3778
|
+
"const.text": async () => {
|
|
3779
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3780
|
+
},
|
|
3781
|
+
"const.boolean": async () => {
|
|
3782
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3783
|
+
},
|
|
3784
|
+
"math.add": async () => {
|
|
3785
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3786
|
+
},
|
|
3787
|
+
"math.subtract": async () => {
|
|
3788
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3789
|
+
},
|
|
3790
|
+
"math.multiply": async () => {
|
|
3791
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3792
|
+
},
|
|
3793
|
+
"math.divide": async () => {
|
|
3794
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3795
|
+
},
|
|
3796
|
+
"map.destructure": async () => {
|
|
3797
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3798
|
+
},
|
|
3799
|
+
"parameter.retrieve": async () => {
|
|
3800
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3801
|
+
},
|
|
3802
|
+
"property.retrieve": async () => {
|
|
3803
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3804
|
+
},
|
|
3805
|
+
"location.retrieve": async () => {
|
|
3806
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3807
|
+
},
|
|
3808
|
+
"session.retrieve": async () => {
|
|
3809
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3810
|
+
},
|
|
3811
|
+
"device.retrieve": async () => {
|
|
3812
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3813
|
+
},
|
|
3814
|
+
"user.retrieve": async () => {
|
|
3815
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3816
|
+
},
|
|
3817
|
+
"user.create": async () => {
|
|
3818
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3819
|
+
},
|
|
3820
|
+
"incident.retrieve": async () => {
|
|
3821
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3822
|
+
},
|
|
3823
|
+
"parameter.update": async () => {
|
|
3824
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3825
|
+
},
|
|
3826
|
+
"device.update": async () => {
|
|
3827
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3828
|
+
},
|
|
3829
|
+
"location.update": async () => {
|
|
3830
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3831
|
+
},
|
|
3832
|
+
"property.update": async () => {
|
|
3833
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3834
|
+
},
|
|
3835
|
+
"session.terminate": async () => {
|
|
3836
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3837
|
+
},
|
|
3838
|
+
"system.log": async () => {
|
|
3839
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3840
|
+
},
|
|
3841
|
+
"ui.navigate.screen": async () => {
|
|
3842
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3843
|
+
},
|
|
3844
|
+
"incident.create": async () => {
|
|
3845
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3846
|
+
},
|
|
3847
|
+
"control.switch": async () => {
|
|
3848
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3849
|
+
},
|
|
3850
|
+
"http.patch": async () => {
|
|
3851
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3852
|
+
},
|
|
3853
|
+
"http.get": async () => {
|
|
3854
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3855
|
+
},
|
|
3856
|
+
"http.post": async () => {
|
|
3857
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3858
|
+
},
|
|
3859
|
+
"http.delete": async () => {
|
|
3860
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3861
|
+
},
|
|
3862
|
+
"http.put": async () => {
|
|
3863
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3864
|
+
},
|
|
3865
|
+
"mqtt.send": async () => {
|
|
3866
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3867
|
+
}
|
|
3868
|
+
};
|
|
3869
|
+
async executeLocally(flowId, context = {}) {
|
|
3870
|
+
const logArray = [];
|
|
3871
|
+
logArray.push({
|
|
3872
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3873
|
+
message: `Starting local execution of flow '${flowId}'`,
|
|
3874
|
+
severity: "info"
|
|
3875
|
+
});
|
|
3876
|
+
const flowResponse = await this.retrieve({ flowId });
|
|
3877
|
+
if (!flowResponse.ok) {
|
|
3878
|
+
throw new Error(`Failed to retrieve flow: ${flowResponse.data?.message || "Unknown error"}`);
|
|
3879
|
+
}
|
|
3880
|
+
const flow = flowResponse.data.flow;
|
|
3881
|
+
const blocksById = new Map(
|
|
3882
|
+
flow.nodeArray.map((b) => [b.id, b])
|
|
3883
|
+
);
|
|
3884
|
+
blocksById.set(flow.startNode.id, flow.startNode);
|
|
3885
|
+
const edgeArray = flow.edgeArray;
|
|
3886
|
+
const outputStore = {};
|
|
3887
|
+
const runBlock = async (block) => {
|
|
3888
|
+
logArray.push({
|
|
3889
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3890
|
+
message: `Running block ${block.type} (${block.id})`,
|
|
3891
|
+
severity: "info"
|
|
3892
|
+
});
|
|
3893
|
+
const inputs = this.resolveInputs(block, outputStore, edgeArray);
|
|
3894
|
+
const executor = this.blockExecutors[block.type];
|
|
3895
|
+
if (executor === void 0 || executor === null) {
|
|
3896
|
+
throw new Error(`No executor for ${block.type}`);
|
|
3897
|
+
}
|
|
3898
|
+
const raw = await executor(inputs, block, context);
|
|
3899
|
+
const { flowBranch, output } = raw;
|
|
3900
|
+
outputStore[block.id] = output;
|
|
3901
|
+
if (raw.logArray !== void 0) {
|
|
3902
|
+
logArray.push(...raw.logArray);
|
|
3903
|
+
}
|
|
3904
|
+
logArray.push({
|
|
3905
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3906
|
+
message: `Block ${block.type} (${block.id}) executed successfully`,
|
|
3907
|
+
severity: "info"
|
|
3908
|
+
});
|
|
3909
|
+
return flowBranch ?? null;
|
|
3910
|
+
};
|
|
3911
|
+
const getNext = (fromId, branch) => {
|
|
3912
|
+
let ce = edgeArray.find(
|
|
3913
|
+
(e) => e.type === "control" && e.from.blockId === fromId && (e.from.output ?? null) === branch
|
|
3914
|
+
);
|
|
3915
|
+
if ((ce === null || ce === void 0) && branch === null) {
|
|
3916
|
+
ce = edgeArray.find(
|
|
3917
|
+
(e) => e.type === "control" && e.from.blockId === fromId
|
|
3918
|
+
);
|
|
3919
|
+
}
|
|
3920
|
+
if (ce === null || ce === void 0) {
|
|
3921
|
+
return null;
|
|
3922
|
+
}
|
|
3923
|
+
return blocksById.get(ce.to.blockId) ?? null;
|
|
3924
|
+
};
|
|
3925
|
+
if (flow.startNode.type.startsWith("start.") === false) {
|
|
3926
|
+
throw new Error(
|
|
3927
|
+
`Flow ${flowId} has an invalid start block that is not of type 'start.'`
|
|
3928
|
+
);
|
|
3929
|
+
}
|
|
3930
|
+
let current = flow.startNode;
|
|
3931
|
+
await runBlock(current);
|
|
3932
|
+
const next = getNext(current.id, null);
|
|
3933
|
+
if (next === null) {
|
|
3934
|
+
return {
|
|
3935
|
+
output: {},
|
|
3936
|
+
logArray
|
|
3937
|
+
};
|
|
3938
|
+
}
|
|
3939
|
+
current = next;
|
|
3940
|
+
while (current.type.startsWith("end.") === false) {
|
|
3941
|
+
const branch = await runBlock(current);
|
|
3942
|
+
const next2 = getNext(current.id, branch);
|
|
3943
|
+
if (next2 === null) {
|
|
3944
|
+
return {
|
|
3945
|
+
output: {},
|
|
3946
|
+
logArray
|
|
3947
|
+
};
|
|
3948
|
+
}
|
|
3949
|
+
current = next2;
|
|
3950
|
+
}
|
|
3951
|
+
await runBlock(current);
|
|
3952
|
+
const endBlock = current;
|
|
3953
|
+
const result = {};
|
|
3954
|
+
const definitions = endBlock.data.outputParamDefinitionArray ?? [];
|
|
3955
|
+
for (const def of definitions) {
|
|
3956
|
+
result[def.name] = outputStore[current.id]?.[def.name] ?? null;
|
|
3957
|
+
}
|
|
3958
|
+
return {
|
|
3959
|
+
output: result,
|
|
3960
|
+
logArray
|
|
3961
|
+
};
|
|
3962
|
+
}
|
|
3658
3963
|
};
|
|
3659
3964
|
|
|
3660
3965
|
// src/flowTraces/flowTraces.service.ts
|
package/dist/index.mjs
CHANGED
|
@@ -3518,6 +3518,7 @@ var EmzService = class extends Service {
|
|
|
3518
3518
|
};
|
|
3519
3519
|
|
|
3520
3520
|
// src/flows/flows.service.ts
|
|
3521
|
+
import jsonLogic from "json-logic-js";
|
|
3521
3522
|
var FlowsService = class extends Service {
|
|
3522
3523
|
constructor(config) {
|
|
3523
3524
|
super(config);
|
|
@@ -3611,6 +3612,310 @@ var FlowsService = class extends Service {
|
|
|
3611
3612
|
FlowExecuteOptions
|
|
3612
3613
|
);
|
|
3613
3614
|
}
|
|
3615
|
+
areInputsAvailable(block, outputStore, edgeArray) {
|
|
3616
|
+
if (block.in === null || block.in === void 0) {
|
|
3617
|
+
return true;
|
|
3618
|
+
}
|
|
3619
|
+
return Object.values(block.in).every((edgeId) => {
|
|
3620
|
+
const edge = edgeArray.find((e) => e.id === edgeId);
|
|
3621
|
+
if (edge === void 0) {
|
|
3622
|
+
return false;
|
|
3623
|
+
}
|
|
3624
|
+
if (edge.type === "control") {
|
|
3625
|
+
return true;
|
|
3626
|
+
}
|
|
3627
|
+
const srcOutputs = outputStore[edge.from.blockId];
|
|
3628
|
+
return srcOutputs !== null && srcOutputs !== void 0 && edge.from.output in srcOutputs;
|
|
3629
|
+
});
|
|
3630
|
+
}
|
|
3631
|
+
resolveInputs(block, outputStore, edgeArray) {
|
|
3632
|
+
const inputs = {};
|
|
3633
|
+
if (block.in === void 0) {
|
|
3634
|
+
return inputs;
|
|
3635
|
+
}
|
|
3636
|
+
for (const [inputName, edgeId] of Object.entries(block.in)) {
|
|
3637
|
+
const edge = edgeArray.find((e) => e.id === edgeId);
|
|
3638
|
+
if (edge === void 0) {
|
|
3639
|
+
throw new Error(
|
|
3640
|
+
`No edge found with id ${edgeId} for input ${inputName}`
|
|
3641
|
+
);
|
|
3642
|
+
}
|
|
3643
|
+
if (edge.type === "control") {
|
|
3644
|
+
continue;
|
|
3645
|
+
}
|
|
3646
|
+
const srcOutputs = outputStore[edge.from.blockId];
|
|
3647
|
+
if (srcOutputs === void 0 || edge.from.output in srcOutputs === false) {
|
|
3648
|
+
throw new Error(
|
|
3649
|
+
`Missing output '${edge.from.output}' from block '${edge.from.blockId}'`
|
|
3650
|
+
);
|
|
3651
|
+
}
|
|
3652
|
+
inputs[inputName] = srcOutputs[edge.from.output];
|
|
3653
|
+
}
|
|
3654
|
+
return inputs;
|
|
3655
|
+
}
|
|
3656
|
+
isInputConnected(block, inputName) {
|
|
3657
|
+
if (block.in === void 0 || block.in === null) {
|
|
3658
|
+
return false;
|
|
3659
|
+
}
|
|
3660
|
+
return block.in[inputName] !== void 0;
|
|
3661
|
+
}
|
|
3662
|
+
blockExecutors = {
|
|
3663
|
+
"start.custom": async (_inputs, block, context) => {
|
|
3664
|
+
if (block.type !== "start.custom") {
|
|
3665
|
+
throw new Error(
|
|
3666
|
+
`Invalid block type '${block.type}' for start.custom executor`
|
|
3667
|
+
);
|
|
3668
|
+
}
|
|
3669
|
+
const defs = block.data.inputParamDefinitionArray ?? [];
|
|
3670
|
+
if (defs.length === 0) {
|
|
3671
|
+
return { output: {} };
|
|
3672
|
+
}
|
|
3673
|
+
const outputs = {};
|
|
3674
|
+
for (const param of defs) {
|
|
3675
|
+
const value = context[param.name];
|
|
3676
|
+
if (value === void 0 && param.required) {
|
|
3677
|
+
throw new Error(
|
|
3678
|
+
`Missing required input parameter '${param.name}'`
|
|
3679
|
+
);
|
|
3680
|
+
}
|
|
3681
|
+
outputs[param.name] = value;
|
|
3682
|
+
}
|
|
3683
|
+
return {
|
|
3684
|
+
output: outputs
|
|
3685
|
+
};
|
|
3686
|
+
},
|
|
3687
|
+
"control.if": async (inputs, block) => {
|
|
3688
|
+
const fb = block;
|
|
3689
|
+
const result = jsonLogic.apply(fb.data.condition, inputs);
|
|
3690
|
+
return {
|
|
3691
|
+
output: {},
|
|
3692
|
+
flowBranch: result === true ? "true" : "false"
|
|
3693
|
+
};
|
|
3694
|
+
},
|
|
3695
|
+
"flow.execute": async (inputs, block) => {
|
|
3696
|
+
const fb = block;
|
|
3697
|
+
const finalFlowId = this.isInputConnected(fb, "flowId") ? inputs.flowId : fb.data?.flowId;
|
|
3698
|
+
if (finalFlowId === void 0 || finalFlowId === null) {
|
|
3699
|
+
throw new Error(
|
|
3700
|
+
`Missing required input 'flowId' for block type '${block.type}'`
|
|
3701
|
+
);
|
|
3702
|
+
}
|
|
3703
|
+
const execInput = {};
|
|
3704
|
+
for (const [key, value] of Object.entries(
|
|
3705
|
+
inputs
|
|
3706
|
+
)) {
|
|
3707
|
+
if (key === "flowId") {
|
|
3708
|
+
continue;
|
|
3709
|
+
}
|
|
3710
|
+
execInput[key] = value;
|
|
3711
|
+
}
|
|
3712
|
+
const { output } = await this.executeLocally(finalFlowId, execInput);
|
|
3713
|
+
return { output };
|
|
3714
|
+
},
|
|
3715
|
+
"end.custom": async (inputs) => {
|
|
3716
|
+
return { output: { ...inputs } };
|
|
3717
|
+
},
|
|
3718
|
+
// Placeholder implementations for other block types (they will throw errors if used)
|
|
3719
|
+
"start.quickAction.location": async () => {
|
|
3720
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3721
|
+
},
|
|
3722
|
+
"start.session.update": async () => {
|
|
3723
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3724
|
+
},
|
|
3725
|
+
"start.location.update": async () => {
|
|
3726
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3727
|
+
},
|
|
3728
|
+
"start.parameter.update": async () => {
|
|
3729
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3730
|
+
},
|
|
3731
|
+
"const.number": async () => {
|
|
3732
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3733
|
+
},
|
|
3734
|
+
"const.text": async () => {
|
|
3735
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3736
|
+
},
|
|
3737
|
+
"const.boolean": async () => {
|
|
3738
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3739
|
+
},
|
|
3740
|
+
"math.add": async () => {
|
|
3741
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3742
|
+
},
|
|
3743
|
+
"math.subtract": async () => {
|
|
3744
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3745
|
+
},
|
|
3746
|
+
"math.multiply": async () => {
|
|
3747
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3748
|
+
},
|
|
3749
|
+
"math.divide": async () => {
|
|
3750
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3751
|
+
},
|
|
3752
|
+
"map.destructure": async () => {
|
|
3753
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3754
|
+
},
|
|
3755
|
+
"parameter.retrieve": async () => {
|
|
3756
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3757
|
+
},
|
|
3758
|
+
"property.retrieve": async () => {
|
|
3759
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3760
|
+
},
|
|
3761
|
+
"location.retrieve": async () => {
|
|
3762
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3763
|
+
},
|
|
3764
|
+
"session.retrieve": async () => {
|
|
3765
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3766
|
+
},
|
|
3767
|
+
"device.retrieve": async () => {
|
|
3768
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3769
|
+
},
|
|
3770
|
+
"user.retrieve": async () => {
|
|
3771
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3772
|
+
},
|
|
3773
|
+
"user.create": async () => {
|
|
3774
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3775
|
+
},
|
|
3776
|
+
"incident.retrieve": async () => {
|
|
3777
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3778
|
+
},
|
|
3779
|
+
"parameter.update": async () => {
|
|
3780
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3781
|
+
},
|
|
3782
|
+
"device.update": async () => {
|
|
3783
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3784
|
+
},
|
|
3785
|
+
"location.update": async () => {
|
|
3786
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3787
|
+
},
|
|
3788
|
+
"property.update": async () => {
|
|
3789
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3790
|
+
},
|
|
3791
|
+
"session.terminate": async () => {
|
|
3792
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3793
|
+
},
|
|
3794
|
+
"system.log": async () => {
|
|
3795
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3796
|
+
},
|
|
3797
|
+
"ui.navigate.screen": async () => {
|
|
3798
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3799
|
+
},
|
|
3800
|
+
"incident.create": async () => {
|
|
3801
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3802
|
+
},
|
|
3803
|
+
"control.switch": async () => {
|
|
3804
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3805
|
+
},
|
|
3806
|
+
"http.patch": async () => {
|
|
3807
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3808
|
+
},
|
|
3809
|
+
"http.get": async () => {
|
|
3810
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3811
|
+
},
|
|
3812
|
+
"http.post": async () => {
|
|
3813
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3814
|
+
},
|
|
3815
|
+
"http.delete": async () => {
|
|
3816
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3817
|
+
},
|
|
3818
|
+
"http.put": async () => {
|
|
3819
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3820
|
+
},
|
|
3821
|
+
"mqtt.send": async () => {
|
|
3822
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3823
|
+
}
|
|
3824
|
+
};
|
|
3825
|
+
async executeLocally(flowId, context = {}) {
|
|
3826
|
+
const logArray = [];
|
|
3827
|
+
logArray.push({
|
|
3828
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3829
|
+
message: `Starting local execution of flow '${flowId}'`,
|
|
3830
|
+
severity: "info"
|
|
3831
|
+
});
|
|
3832
|
+
const flowResponse = await this.retrieve({ flowId });
|
|
3833
|
+
if (!flowResponse.ok) {
|
|
3834
|
+
throw new Error(`Failed to retrieve flow: ${flowResponse.data?.message || "Unknown error"}`);
|
|
3835
|
+
}
|
|
3836
|
+
const flow = flowResponse.data.flow;
|
|
3837
|
+
const blocksById = new Map(
|
|
3838
|
+
flow.nodeArray.map((b) => [b.id, b])
|
|
3839
|
+
);
|
|
3840
|
+
blocksById.set(flow.startNode.id, flow.startNode);
|
|
3841
|
+
const edgeArray = flow.edgeArray;
|
|
3842
|
+
const outputStore = {};
|
|
3843
|
+
const runBlock = async (block) => {
|
|
3844
|
+
logArray.push({
|
|
3845
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3846
|
+
message: `Running block ${block.type} (${block.id})`,
|
|
3847
|
+
severity: "info"
|
|
3848
|
+
});
|
|
3849
|
+
const inputs = this.resolveInputs(block, outputStore, edgeArray);
|
|
3850
|
+
const executor = this.blockExecutors[block.type];
|
|
3851
|
+
if (executor === void 0 || executor === null) {
|
|
3852
|
+
throw new Error(`No executor for ${block.type}`);
|
|
3853
|
+
}
|
|
3854
|
+
const raw = await executor(inputs, block, context);
|
|
3855
|
+
const { flowBranch, output } = raw;
|
|
3856
|
+
outputStore[block.id] = output;
|
|
3857
|
+
if (raw.logArray !== void 0) {
|
|
3858
|
+
logArray.push(...raw.logArray);
|
|
3859
|
+
}
|
|
3860
|
+
logArray.push({
|
|
3861
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3862
|
+
message: `Block ${block.type} (${block.id}) executed successfully`,
|
|
3863
|
+
severity: "info"
|
|
3864
|
+
});
|
|
3865
|
+
return flowBranch ?? null;
|
|
3866
|
+
};
|
|
3867
|
+
const getNext = (fromId, branch) => {
|
|
3868
|
+
let ce = edgeArray.find(
|
|
3869
|
+
(e) => e.type === "control" && e.from.blockId === fromId && (e.from.output ?? null) === branch
|
|
3870
|
+
);
|
|
3871
|
+
if ((ce === null || ce === void 0) && branch === null) {
|
|
3872
|
+
ce = edgeArray.find(
|
|
3873
|
+
(e) => e.type === "control" && e.from.blockId === fromId
|
|
3874
|
+
);
|
|
3875
|
+
}
|
|
3876
|
+
if (ce === null || ce === void 0) {
|
|
3877
|
+
return null;
|
|
3878
|
+
}
|
|
3879
|
+
return blocksById.get(ce.to.blockId) ?? null;
|
|
3880
|
+
};
|
|
3881
|
+
if (flow.startNode.type.startsWith("start.") === false) {
|
|
3882
|
+
throw new Error(
|
|
3883
|
+
`Flow ${flowId} has an invalid start block that is not of type 'start.'`
|
|
3884
|
+
);
|
|
3885
|
+
}
|
|
3886
|
+
let current = flow.startNode;
|
|
3887
|
+
await runBlock(current);
|
|
3888
|
+
const next = getNext(current.id, null);
|
|
3889
|
+
if (next === null) {
|
|
3890
|
+
return {
|
|
3891
|
+
output: {},
|
|
3892
|
+
logArray
|
|
3893
|
+
};
|
|
3894
|
+
}
|
|
3895
|
+
current = next;
|
|
3896
|
+
while (current.type.startsWith("end.") === false) {
|
|
3897
|
+
const branch = await runBlock(current);
|
|
3898
|
+
const next2 = getNext(current.id, branch);
|
|
3899
|
+
if (next2 === null) {
|
|
3900
|
+
return {
|
|
3901
|
+
output: {},
|
|
3902
|
+
logArray
|
|
3903
|
+
};
|
|
3904
|
+
}
|
|
3905
|
+
current = next2;
|
|
3906
|
+
}
|
|
3907
|
+
await runBlock(current);
|
|
3908
|
+
const endBlock = current;
|
|
3909
|
+
const result = {};
|
|
3910
|
+
const definitions = endBlock.data.outputParamDefinitionArray ?? [];
|
|
3911
|
+
for (const def of definitions) {
|
|
3912
|
+
result[def.name] = outputStore[current.id]?.[def.name] ?? null;
|
|
3913
|
+
}
|
|
3914
|
+
return {
|
|
3915
|
+
output: result,
|
|
3916
|
+
logArray
|
|
3917
|
+
};
|
|
3918
|
+
}
|
|
3614
3919
|
};
|
|
3615
3920
|
|
|
3616
3921
|
// src/flowTraces/flowTraces.service.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juhuu/sdk-ts",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.265",
|
|
4
4
|
"description": "Typescript wrapper for JUHUU services",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -26,11 +26,13 @@
|
|
|
26
26
|
],
|
|
27
27
|
"homepage": "https://github.com/JUHUU-Labs/sdk-ts#readme",
|
|
28
28
|
"devDependencies": {
|
|
29
|
+
"@types/json-logic-js": "^2.0.8",
|
|
29
30
|
"tsup": "^8.0.2",
|
|
30
31
|
"typescript": "^5.4.5"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"@types/node": "^24.1.0",
|
|
35
|
+
"json-logic-js": "^2.0.5",
|
|
34
36
|
"socket.io-client": "^4.7.5"
|
|
35
37
|
}
|
|
36
38
|
}
|