@juhuu/sdk-ts 1.2.264 → 1.2.267
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 +20 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.js +311 -0
- package/dist/index.mjs +311 -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(FlowExecuteLocallyParams: JUHUU.Flow.ExecuteLocally.Params, FlowExecuteLocallyOptions?: JUHUU.Flow.Execute.Options): Promise<{
|
|
1705
|
+
output: Record<string, any>;
|
|
1706
|
+
logArray: FlowLog[];
|
|
1707
|
+
}>;
|
|
1700
1708
|
}
|
|
1701
1709
|
|
|
1702
1710
|
declare class FlowTracesService extends Service {
|
|
@@ -4742,7 +4750,7 @@ declare namespace JUHUU {
|
|
|
4742
4750
|
nodeArray: FlowBlock[];
|
|
4743
4751
|
edgeArray: FlowEdge[];
|
|
4744
4752
|
propertyId: string;
|
|
4745
|
-
|
|
4753
|
+
executionEnvironmentArray: FlowExecutionEnvironment[];
|
|
4746
4754
|
status: FlowStatus;
|
|
4747
4755
|
errorMessage: string | null;
|
|
4748
4756
|
};
|
|
@@ -4816,6 +4824,17 @@ declare namespace JUHUU {
|
|
|
4816
4824
|
output: Record<string, any>;
|
|
4817
4825
|
};
|
|
4818
4826
|
}
|
|
4827
|
+
namespace ExecuteLocally {
|
|
4828
|
+
type Params = {
|
|
4829
|
+
flowId: string;
|
|
4830
|
+
input?: Record<string, any>;
|
|
4831
|
+
};
|
|
4832
|
+
type Options = JUHUU.RequestOptions;
|
|
4833
|
+
type Response = {
|
|
4834
|
+
output: Record<string, any>;
|
|
4835
|
+
logArray: FlowLog[];
|
|
4836
|
+
};
|
|
4837
|
+
}
|
|
4819
4838
|
}
|
|
4820
4839
|
namespace FlowTrace {
|
|
4821
4840
|
type Object = {
|
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(FlowExecuteLocallyParams: JUHUU.Flow.ExecuteLocally.Params, FlowExecuteLocallyOptions?: JUHUU.Flow.Execute.Options): Promise<{
|
|
1705
|
+
output: Record<string, any>;
|
|
1706
|
+
logArray: FlowLog[];
|
|
1707
|
+
}>;
|
|
1700
1708
|
}
|
|
1701
1709
|
|
|
1702
1710
|
declare class FlowTracesService extends Service {
|
|
@@ -4742,7 +4750,7 @@ declare namespace JUHUU {
|
|
|
4742
4750
|
nodeArray: FlowBlock[];
|
|
4743
4751
|
edgeArray: FlowEdge[];
|
|
4744
4752
|
propertyId: string;
|
|
4745
|
-
|
|
4753
|
+
executionEnvironmentArray: FlowExecutionEnvironment[];
|
|
4746
4754
|
status: FlowStatus;
|
|
4747
4755
|
errorMessage: string | null;
|
|
4748
4756
|
};
|
|
@@ -4816,6 +4824,17 @@ declare namespace JUHUU {
|
|
|
4816
4824
|
output: Record<string, any>;
|
|
4817
4825
|
};
|
|
4818
4826
|
}
|
|
4827
|
+
namespace ExecuteLocally {
|
|
4828
|
+
type Params = {
|
|
4829
|
+
flowId: string;
|
|
4830
|
+
input?: Record<string, any>;
|
|
4831
|
+
};
|
|
4832
|
+
type Options = JUHUU.RequestOptions;
|
|
4833
|
+
type Response = {
|
|
4834
|
+
output: Record<string, any>;
|
|
4835
|
+
logArray: FlowLog[];
|
|
4836
|
+
};
|
|
4837
|
+
}
|
|
4819
4838
|
}
|
|
4820
4839
|
namespace FlowTrace {
|
|
4821
4840
|
type Object = {
|
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,316 @@ 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(`Missing required input parameter '${param.name}'`);
|
|
3722
|
+
}
|
|
3723
|
+
outputs[param.name] = value;
|
|
3724
|
+
}
|
|
3725
|
+
return {
|
|
3726
|
+
output: outputs
|
|
3727
|
+
};
|
|
3728
|
+
},
|
|
3729
|
+
"control.if": async (inputs, block) => {
|
|
3730
|
+
const fb = block;
|
|
3731
|
+
const result = import_json_logic_js.default.apply(fb.data.condition, inputs);
|
|
3732
|
+
return {
|
|
3733
|
+
output: {},
|
|
3734
|
+
flowBranch: result === true ? "true" : "false"
|
|
3735
|
+
};
|
|
3736
|
+
},
|
|
3737
|
+
"flow.execute": async (inputs, block) => {
|
|
3738
|
+
const fb = block;
|
|
3739
|
+
const finalFlowId = this.isInputConnected(fb, "flowId") ? inputs.flowId : fb.data?.flowId;
|
|
3740
|
+
if (finalFlowId === void 0 || finalFlowId === null) {
|
|
3741
|
+
throw new Error(
|
|
3742
|
+
`Missing required input 'flowId' for block type '${block.type}'`
|
|
3743
|
+
);
|
|
3744
|
+
}
|
|
3745
|
+
const execInput = {};
|
|
3746
|
+
for (const [key, value] of Object.entries(
|
|
3747
|
+
inputs
|
|
3748
|
+
)) {
|
|
3749
|
+
if (key === "flowId") {
|
|
3750
|
+
continue;
|
|
3751
|
+
}
|
|
3752
|
+
execInput[key] = value;
|
|
3753
|
+
}
|
|
3754
|
+
const { output } = await this.executeLocally(finalFlowId, execInput);
|
|
3755
|
+
return { output };
|
|
3756
|
+
},
|
|
3757
|
+
"end.custom": async (inputs) => {
|
|
3758
|
+
return { output: { ...inputs } };
|
|
3759
|
+
},
|
|
3760
|
+
// Placeholder implementations for other block types (they will throw errors if used)
|
|
3761
|
+
"start.quickAction.location": async () => {
|
|
3762
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3763
|
+
},
|
|
3764
|
+
"start.session.update": async () => {
|
|
3765
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3766
|
+
},
|
|
3767
|
+
"start.location.update": async () => {
|
|
3768
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3769
|
+
},
|
|
3770
|
+
"start.parameter.update": async () => {
|
|
3771
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3772
|
+
},
|
|
3773
|
+
"const.number": async () => {
|
|
3774
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3775
|
+
},
|
|
3776
|
+
"const.text": async () => {
|
|
3777
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3778
|
+
},
|
|
3779
|
+
"const.boolean": async () => {
|
|
3780
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3781
|
+
},
|
|
3782
|
+
"math.add": async () => {
|
|
3783
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3784
|
+
},
|
|
3785
|
+
"math.subtract": async () => {
|
|
3786
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3787
|
+
},
|
|
3788
|
+
"math.multiply": async () => {
|
|
3789
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3790
|
+
},
|
|
3791
|
+
"math.divide": async () => {
|
|
3792
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3793
|
+
},
|
|
3794
|
+
"map.destructure": async () => {
|
|
3795
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3796
|
+
},
|
|
3797
|
+
"parameter.retrieve": async () => {
|
|
3798
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3799
|
+
},
|
|
3800
|
+
"property.retrieve": async () => {
|
|
3801
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3802
|
+
},
|
|
3803
|
+
"location.retrieve": async () => {
|
|
3804
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3805
|
+
},
|
|
3806
|
+
"session.retrieve": async () => {
|
|
3807
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3808
|
+
},
|
|
3809
|
+
"device.retrieve": async () => {
|
|
3810
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3811
|
+
},
|
|
3812
|
+
"user.retrieve": async () => {
|
|
3813
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3814
|
+
},
|
|
3815
|
+
"user.create": async () => {
|
|
3816
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3817
|
+
},
|
|
3818
|
+
"incident.retrieve": async () => {
|
|
3819
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3820
|
+
},
|
|
3821
|
+
"parameter.update": async () => {
|
|
3822
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3823
|
+
},
|
|
3824
|
+
"device.update": async () => {
|
|
3825
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3826
|
+
},
|
|
3827
|
+
"location.update": async () => {
|
|
3828
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3829
|
+
},
|
|
3830
|
+
"property.update": async () => {
|
|
3831
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3832
|
+
},
|
|
3833
|
+
"session.terminate": async () => {
|
|
3834
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3835
|
+
},
|
|
3836
|
+
"system.log": async () => {
|
|
3837
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3838
|
+
},
|
|
3839
|
+
"ui.navigate.screen": async () => {
|
|
3840
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3841
|
+
},
|
|
3842
|
+
"incident.create": async () => {
|
|
3843
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3844
|
+
},
|
|
3845
|
+
"control.switch": async () => {
|
|
3846
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3847
|
+
},
|
|
3848
|
+
"http.patch": async () => {
|
|
3849
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3850
|
+
},
|
|
3851
|
+
"http.get": async () => {
|
|
3852
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3853
|
+
},
|
|
3854
|
+
"http.post": async () => {
|
|
3855
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3856
|
+
},
|
|
3857
|
+
"http.delete": async () => {
|
|
3858
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3859
|
+
},
|
|
3860
|
+
"http.put": async () => {
|
|
3861
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3862
|
+
},
|
|
3863
|
+
"mqtt.send": async () => {
|
|
3864
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3865
|
+
}
|
|
3866
|
+
};
|
|
3867
|
+
async executeLocally(FlowExecuteLocallyParams, FlowExecuteLocallyOptions) {
|
|
3868
|
+
const logArray = [];
|
|
3869
|
+
logArray.push({
|
|
3870
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3871
|
+
message: `Starting local execution of flow '${FlowExecuteLocallyParams.flowId}'`,
|
|
3872
|
+
severity: "info"
|
|
3873
|
+
});
|
|
3874
|
+
const flowResponse = await this.retrieve({
|
|
3875
|
+
flowId: FlowExecuteLocallyParams.flowId
|
|
3876
|
+
});
|
|
3877
|
+
if (!flowResponse.ok) {
|
|
3878
|
+
throw new Error(
|
|
3879
|
+
`Failed to retrieve flow: ${flowResponse.data?.message || "Unknown error"}`
|
|
3880
|
+
);
|
|
3881
|
+
}
|
|
3882
|
+
const flow = flowResponse.data.flow;
|
|
3883
|
+
const blocksById = new Map(
|
|
3884
|
+
flow.nodeArray.map((b) => [b.id, b])
|
|
3885
|
+
);
|
|
3886
|
+
blocksById.set(flow.startNode.id, flow.startNode);
|
|
3887
|
+
const edgeArray = flow.edgeArray;
|
|
3888
|
+
const outputStore = {};
|
|
3889
|
+
const runBlock = async (block) => {
|
|
3890
|
+
logArray.push({
|
|
3891
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3892
|
+
message: `Running block ${block.type} (${block.id})`,
|
|
3893
|
+
severity: "info"
|
|
3894
|
+
});
|
|
3895
|
+
const inputs = this.resolveInputs(block, outputStore, edgeArray);
|
|
3896
|
+
const executor = this.blockExecutors[block.type];
|
|
3897
|
+
if (executor === void 0 || executor === null) {
|
|
3898
|
+
throw new Error(`No executor for ${block.type}`);
|
|
3899
|
+
}
|
|
3900
|
+
const raw = await executor(
|
|
3901
|
+
inputs,
|
|
3902
|
+
block,
|
|
3903
|
+
FlowExecuteLocallyParams.input ?? {}
|
|
3904
|
+
);
|
|
3905
|
+
const { flowBranch, output } = raw;
|
|
3906
|
+
outputStore[block.id] = output;
|
|
3907
|
+
if (raw.logArray !== void 0) {
|
|
3908
|
+
logArray.push(...raw.logArray);
|
|
3909
|
+
}
|
|
3910
|
+
logArray.push({
|
|
3911
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3912
|
+
message: `Block ${block.type} (${block.id}) executed successfully`,
|
|
3913
|
+
severity: "info"
|
|
3914
|
+
});
|
|
3915
|
+
return flowBranch ?? null;
|
|
3916
|
+
};
|
|
3917
|
+
const getNext = (fromId, branch) => {
|
|
3918
|
+
let ce = edgeArray.find(
|
|
3919
|
+
(e) => e.type === "control" && e.from.blockId === fromId && (e.from.output ?? null) === branch
|
|
3920
|
+
);
|
|
3921
|
+
if ((ce === null || ce === void 0) && branch === null) {
|
|
3922
|
+
ce = edgeArray.find(
|
|
3923
|
+
(e) => e.type === "control" && e.from.blockId === fromId
|
|
3924
|
+
);
|
|
3925
|
+
}
|
|
3926
|
+
if (ce === null || ce === void 0) {
|
|
3927
|
+
return null;
|
|
3928
|
+
}
|
|
3929
|
+
return blocksById.get(ce.to.blockId) ?? null;
|
|
3930
|
+
};
|
|
3931
|
+
if (flow.startNode.type.startsWith("start.") === false) {
|
|
3932
|
+
throw new Error(
|
|
3933
|
+
`Flow ${FlowExecuteLocallyParams.flowId} has an invalid start block that is not of type 'start.'`
|
|
3934
|
+
);
|
|
3935
|
+
}
|
|
3936
|
+
let current = flow.startNode;
|
|
3937
|
+
await runBlock(current);
|
|
3938
|
+
const next = getNext(current.id, null);
|
|
3939
|
+
if (next === null) {
|
|
3940
|
+
return {
|
|
3941
|
+
output: {},
|
|
3942
|
+
logArray
|
|
3943
|
+
};
|
|
3944
|
+
}
|
|
3945
|
+
current = next;
|
|
3946
|
+
while (current.type.startsWith("end.") === false) {
|
|
3947
|
+
const branch = await runBlock(current);
|
|
3948
|
+
const next2 = getNext(current.id, branch);
|
|
3949
|
+
if (next2 === null) {
|
|
3950
|
+
return {
|
|
3951
|
+
output: {},
|
|
3952
|
+
logArray
|
|
3953
|
+
};
|
|
3954
|
+
}
|
|
3955
|
+
current = next2;
|
|
3956
|
+
}
|
|
3957
|
+
await runBlock(current);
|
|
3958
|
+
const endBlock = current;
|
|
3959
|
+
const result = {};
|
|
3960
|
+
const definitions = endBlock.data.outputParamDefinitionArray ?? [];
|
|
3961
|
+
for (const def of definitions) {
|
|
3962
|
+
result[def.name] = outputStore[current.id]?.[def.name] ?? null;
|
|
3963
|
+
}
|
|
3964
|
+
return {
|
|
3965
|
+
output: result,
|
|
3966
|
+
logArray
|
|
3967
|
+
};
|
|
3968
|
+
}
|
|
3658
3969
|
};
|
|
3659
3970
|
|
|
3660
3971
|
// 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,316 @@ 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(`Missing required input parameter '${param.name}'`);
|
|
3678
|
+
}
|
|
3679
|
+
outputs[param.name] = value;
|
|
3680
|
+
}
|
|
3681
|
+
return {
|
|
3682
|
+
output: outputs
|
|
3683
|
+
};
|
|
3684
|
+
},
|
|
3685
|
+
"control.if": async (inputs, block) => {
|
|
3686
|
+
const fb = block;
|
|
3687
|
+
const result = jsonLogic.apply(fb.data.condition, inputs);
|
|
3688
|
+
return {
|
|
3689
|
+
output: {},
|
|
3690
|
+
flowBranch: result === true ? "true" : "false"
|
|
3691
|
+
};
|
|
3692
|
+
},
|
|
3693
|
+
"flow.execute": async (inputs, block) => {
|
|
3694
|
+
const fb = block;
|
|
3695
|
+
const finalFlowId = this.isInputConnected(fb, "flowId") ? inputs.flowId : fb.data?.flowId;
|
|
3696
|
+
if (finalFlowId === void 0 || finalFlowId === null) {
|
|
3697
|
+
throw new Error(
|
|
3698
|
+
`Missing required input 'flowId' for block type '${block.type}'`
|
|
3699
|
+
);
|
|
3700
|
+
}
|
|
3701
|
+
const execInput = {};
|
|
3702
|
+
for (const [key, value] of Object.entries(
|
|
3703
|
+
inputs
|
|
3704
|
+
)) {
|
|
3705
|
+
if (key === "flowId") {
|
|
3706
|
+
continue;
|
|
3707
|
+
}
|
|
3708
|
+
execInput[key] = value;
|
|
3709
|
+
}
|
|
3710
|
+
const { output } = await this.executeLocally(finalFlowId, execInput);
|
|
3711
|
+
return { output };
|
|
3712
|
+
},
|
|
3713
|
+
"end.custom": async (inputs) => {
|
|
3714
|
+
return { output: { ...inputs } };
|
|
3715
|
+
},
|
|
3716
|
+
// Placeholder implementations for other block types (they will throw errors if used)
|
|
3717
|
+
"start.quickAction.location": async () => {
|
|
3718
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3719
|
+
},
|
|
3720
|
+
"start.session.update": async () => {
|
|
3721
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3722
|
+
},
|
|
3723
|
+
"start.location.update": async () => {
|
|
3724
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3725
|
+
},
|
|
3726
|
+
"start.parameter.update": async () => {
|
|
3727
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3728
|
+
},
|
|
3729
|
+
"const.number": async () => {
|
|
3730
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3731
|
+
},
|
|
3732
|
+
"const.text": async () => {
|
|
3733
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3734
|
+
},
|
|
3735
|
+
"const.boolean": async () => {
|
|
3736
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3737
|
+
},
|
|
3738
|
+
"math.add": async () => {
|
|
3739
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3740
|
+
},
|
|
3741
|
+
"math.subtract": async () => {
|
|
3742
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3743
|
+
},
|
|
3744
|
+
"math.multiply": async () => {
|
|
3745
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3746
|
+
},
|
|
3747
|
+
"math.divide": async () => {
|
|
3748
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3749
|
+
},
|
|
3750
|
+
"map.destructure": async () => {
|
|
3751
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3752
|
+
},
|
|
3753
|
+
"parameter.retrieve": async () => {
|
|
3754
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3755
|
+
},
|
|
3756
|
+
"property.retrieve": async () => {
|
|
3757
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3758
|
+
},
|
|
3759
|
+
"location.retrieve": async () => {
|
|
3760
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3761
|
+
},
|
|
3762
|
+
"session.retrieve": async () => {
|
|
3763
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3764
|
+
},
|
|
3765
|
+
"device.retrieve": async () => {
|
|
3766
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3767
|
+
},
|
|
3768
|
+
"user.retrieve": async () => {
|
|
3769
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3770
|
+
},
|
|
3771
|
+
"user.create": async () => {
|
|
3772
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3773
|
+
},
|
|
3774
|
+
"incident.retrieve": async () => {
|
|
3775
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3776
|
+
},
|
|
3777
|
+
"parameter.update": async () => {
|
|
3778
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3779
|
+
},
|
|
3780
|
+
"device.update": async () => {
|
|
3781
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3782
|
+
},
|
|
3783
|
+
"location.update": async () => {
|
|
3784
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3785
|
+
},
|
|
3786
|
+
"property.update": async () => {
|
|
3787
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3788
|
+
},
|
|
3789
|
+
"session.terminate": async () => {
|
|
3790
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3791
|
+
},
|
|
3792
|
+
"system.log": async () => {
|
|
3793
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3794
|
+
},
|
|
3795
|
+
"ui.navigate.screen": async () => {
|
|
3796
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3797
|
+
},
|
|
3798
|
+
"incident.create": async () => {
|
|
3799
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3800
|
+
},
|
|
3801
|
+
"control.switch": async () => {
|
|
3802
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3803
|
+
},
|
|
3804
|
+
"http.patch": async () => {
|
|
3805
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3806
|
+
},
|
|
3807
|
+
"http.get": async () => {
|
|
3808
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3809
|
+
},
|
|
3810
|
+
"http.post": async () => {
|
|
3811
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3812
|
+
},
|
|
3813
|
+
"http.delete": async () => {
|
|
3814
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3815
|
+
},
|
|
3816
|
+
"http.put": async () => {
|
|
3817
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3818
|
+
},
|
|
3819
|
+
"mqtt.send": async () => {
|
|
3820
|
+
throw new Error("Block type not implemented in executeLocally");
|
|
3821
|
+
}
|
|
3822
|
+
};
|
|
3823
|
+
async executeLocally(FlowExecuteLocallyParams, FlowExecuteLocallyOptions) {
|
|
3824
|
+
const logArray = [];
|
|
3825
|
+
logArray.push({
|
|
3826
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3827
|
+
message: `Starting local execution of flow '${FlowExecuteLocallyParams.flowId}'`,
|
|
3828
|
+
severity: "info"
|
|
3829
|
+
});
|
|
3830
|
+
const flowResponse = await this.retrieve({
|
|
3831
|
+
flowId: FlowExecuteLocallyParams.flowId
|
|
3832
|
+
});
|
|
3833
|
+
if (!flowResponse.ok) {
|
|
3834
|
+
throw new Error(
|
|
3835
|
+
`Failed to retrieve flow: ${flowResponse.data?.message || "Unknown error"}`
|
|
3836
|
+
);
|
|
3837
|
+
}
|
|
3838
|
+
const flow = flowResponse.data.flow;
|
|
3839
|
+
const blocksById = new Map(
|
|
3840
|
+
flow.nodeArray.map((b) => [b.id, b])
|
|
3841
|
+
);
|
|
3842
|
+
blocksById.set(flow.startNode.id, flow.startNode);
|
|
3843
|
+
const edgeArray = flow.edgeArray;
|
|
3844
|
+
const outputStore = {};
|
|
3845
|
+
const runBlock = async (block) => {
|
|
3846
|
+
logArray.push({
|
|
3847
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3848
|
+
message: `Running block ${block.type} (${block.id})`,
|
|
3849
|
+
severity: "info"
|
|
3850
|
+
});
|
|
3851
|
+
const inputs = this.resolveInputs(block, outputStore, edgeArray);
|
|
3852
|
+
const executor = this.blockExecutors[block.type];
|
|
3853
|
+
if (executor === void 0 || executor === null) {
|
|
3854
|
+
throw new Error(`No executor for ${block.type}`);
|
|
3855
|
+
}
|
|
3856
|
+
const raw = await executor(
|
|
3857
|
+
inputs,
|
|
3858
|
+
block,
|
|
3859
|
+
FlowExecuteLocallyParams.input ?? {}
|
|
3860
|
+
);
|
|
3861
|
+
const { flowBranch, output } = raw;
|
|
3862
|
+
outputStore[block.id] = output;
|
|
3863
|
+
if (raw.logArray !== void 0) {
|
|
3864
|
+
logArray.push(...raw.logArray);
|
|
3865
|
+
}
|
|
3866
|
+
logArray.push({
|
|
3867
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
3868
|
+
message: `Block ${block.type} (${block.id}) executed successfully`,
|
|
3869
|
+
severity: "info"
|
|
3870
|
+
});
|
|
3871
|
+
return flowBranch ?? null;
|
|
3872
|
+
};
|
|
3873
|
+
const getNext = (fromId, branch) => {
|
|
3874
|
+
let ce = edgeArray.find(
|
|
3875
|
+
(e) => e.type === "control" && e.from.blockId === fromId && (e.from.output ?? null) === branch
|
|
3876
|
+
);
|
|
3877
|
+
if ((ce === null || ce === void 0) && branch === null) {
|
|
3878
|
+
ce = edgeArray.find(
|
|
3879
|
+
(e) => e.type === "control" && e.from.blockId === fromId
|
|
3880
|
+
);
|
|
3881
|
+
}
|
|
3882
|
+
if (ce === null || ce === void 0) {
|
|
3883
|
+
return null;
|
|
3884
|
+
}
|
|
3885
|
+
return blocksById.get(ce.to.blockId) ?? null;
|
|
3886
|
+
};
|
|
3887
|
+
if (flow.startNode.type.startsWith("start.") === false) {
|
|
3888
|
+
throw new Error(
|
|
3889
|
+
`Flow ${FlowExecuteLocallyParams.flowId} has an invalid start block that is not of type 'start.'`
|
|
3890
|
+
);
|
|
3891
|
+
}
|
|
3892
|
+
let current = flow.startNode;
|
|
3893
|
+
await runBlock(current);
|
|
3894
|
+
const next = getNext(current.id, null);
|
|
3895
|
+
if (next === null) {
|
|
3896
|
+
return {
|
|
3897
|
+
output: {},
|
|
3898
|
+
logArray
|
|
3899
|
+
};
|
|
3900
|
+
}
|
|
3901
|
+
current = next;
|
|
3902
|
+
while (current.type.startsWith("end.") === false) {
|
|
3903
|
+
const branch = await runBlock(current);
|
|
3904
|
+
const next2 = getNext(current.id, branch);
|
|
3905
|
+
if (next2 === null) {
|
|
3906
|
+
return {
|
|
3907
|
+
output: {},
|
|
3908
|
+
logArray
|
|
3909
|
+
};
|
|
3910
|
+
}
|
|
3911
|
+
current = next2;
|
|
3912
|
+
}
|
|
3913
|
+
await runBlock(current);
|
|
3914
|
+
const endBlock = current;
|
|
3915
|
+
const result = {};
|
|
3916
|
+
const definitions = endBlock.data.outputParamDefinitionArray ?? [];
|
|
3917
|
+
for (const def of definitions) {
|
|
3918
|
+
result[def.name] = outputStore[current.id]?.[def.name] ?? null;
|
|
3919
|
+
}
|
|
3920
|
+
return {
|
|
3921
|
+
output: result,
|
|
3922
|
+
logArray
|
|
3923
|
+
};
|
|
3924
|
+
}
|
|
3614
3925
|
};
|
|
3615
3926
|
|
|
3616
3927
|
// 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.267",
|
|
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
|
}
|