@flusys/nestjs-entity-builder 9.0.1 → 9.1.0
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/README.md +22 -28
- package/config/message-keys.d.ts +9 -62
- package/controllers/flow-api-key.controller.d.ts +14 -0
- package/controllers/flow-definition.controller.d.ts +1 -7
- package/controllers/index.d.ts +1 -0
- package/dtos/flow.dto.d.ts +20 -10
- package/entities/flow-api-key.entity.d.ts +10 -0
- package/entities/flow-definition.entity.d.ts +9 -3
- package/entities/flow-execution.entity.d.ts +0 -1
- package/entities/index.d.ts +3 -3
- package/fesm/21.js +11 -64
- package/fesm/{582.js → 489.js} +11 -20
- package/fesm/{913.js → 606.js} +295 -209
- package/fesm/719.js +186 -162
- package/fesm/794.js +187 -116
- package/fesm/{677.js → 996.js} +616 -1490
- package/fesm/controllers/index.js +6 -5
- package/fesm/docs/index.js +2 -2
- package/fesm/entities/index.js +2 -2
- package/fesm/guards/index.js +19 -12
- package/fesm/index.js +638 -50
- package/fesm/modules/index.js +625 -7
- package/fesm/rule-engine/index.js +2 -2
- package/fesm/services/index.js +25 -54
- package/flow-engine/flow-api-key.d.ts +7 -3
- package/flow-engine/flow-graph.validator.d.ts +2 -4
- package/flow-engine/flow-run.types.d.ts +4 -14
- package/flow-engine/flow.types.d.ts +9 -91
- package/interfaces/flow-definition.interface.d.ts +9 -13
- package/package.json +5 -5
- package/rule-engine/rule-engine.service.d.ts +0 -1
- package/services/entity-flow-scaffold.d.ts +1 -1
- package/services/flow-api-key.service.d.ts +31 -0
- package/services/flow-definition.service.d.ts +12 -24
- package/services/flow-execution.service.d.ts +0 -1
- package/services/flow-executor.service.d.ts +7 -7
- package/services/generic-entity.service.d.ts +1 -1
- package/services/index.d.ts +1 -0
- package/entities/flow-version.entity.d.ts +0 -10
- package/fesm/458.js +0 -649
package/fesm/{677.js → 996.js}
RENAMED
|
@@ -8,8 +8,8 @@ import * as __rspack_external_node_path_806ed179 from "node:path";
|
|
|
8
8
|
import * as __rspack_external_node_url_3991086a from "node:url";
|
|
9
9
|
import * as __rspack_external_node_worker_threads_28ca7740 from "node:worker_threads";
|
|
10
10
|
import * as __rspack_external_node_dns_c6249ebb from "node:dns";
|
|
11
|
-
export const __rspack_esm_id =
|
|
12
|
-
export const __rspack_esm_ids = [
|
|
11
|
+
export const __rspack_esm_id = 996;
|
|
12
|
+
export const __rspack_esm_ids = [996];
|
|
13
13
|
export const __webpack_modules__ = {
|
|
14
14
|
6576(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
15
15
|
const ENTITY_BUILDER_MODULE_OPTIONS = 'ENTITY_BUILDER_MODULE_OPTIONS';
|
|
@@ -59,60 +59,6 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
},
|
|
63
|
-
4816(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
64
|
-
/* import */ var node_crypto__rspack_import_0 = __webpack_require__(2561);
|
|
65
|
-
/* import */ var _flow_types_js__rspack_import_1 = __webpack_require__(6256);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const API_KEY_PREFIX_LENGTH = 11; // "fk_" + 8 hex
|
|
69
|
-
const hashApiKey = (key)=>(0,node_crypto__rspack_import_0.createHash)('sha256').update(key).digest('hex');
|
|
70
|
-
const apiKeyPrefix = (key)=>key.slice(0, API_KEY_PREFIX_LENGTH);
|
|
71
|
-
/** A key as the designer makes it: `fk_<8 hex>_<32 hex>`. */ function looksLikeApiKey(key) {
|
|
72
|
-
return typeof key === 'string' && /^fk_[0-9a-f]{8}_[0-9a-f]{32}$/.test(key);
|
|
73
|
-
}
|
|
74
|
-
/** Constant-time comparison of a presented key against a stored hash. */ function apiKeyMatches(presented, storedHash) {
|
|
75
|
-
const a = Buffer.from(hashApiKey(presented), 'hex');
|
|
76
|
-
const b = Buffer.from(storedHash, 'hex');
|
|
77
|
-
return a.length === b.length && (0,node_crypto__rspack_import_0.timingSafeEqual)(a, b);
|
|
78
|
-
}
|
|
79
|
-
/** Whether `presented` is the key a Request step stores. */ const apiKeyOpens = (stored, presented)=>!!stored && looksLikeApiKey(presented) && apiKeyMatches(presented, stored.hash);
|
|
80
|
-
/**
|
|
81
|
-
* What is saved of the Request steps' API keys: a plain key the designer made becomes its prefix and
|
|
82
|
-
* hash, so the key itself is never stored; a step without `api_key` access keeps no key at all.
|
|
83
|
-
*/ function sealApiKeys(nodes) {
|
|
84
|
-
return nodes.map((node)=>{
|
|
85
|
-
if (node.type !== 'trigger' || node.config?.['apiKey'] === undefined) return node;
|
|
86
|
-
const { apiKey, ...config } = node.config;
|
|
87
|
-
if (config['authMode'] !== 'api_key') return {
|
|
88
|
-
...node,
|
|
89
|
-
config
|
|
90
|
-
};
|
|
91
|
-
if (looksLikeApiKey(apiKey)) return {
|
|
92
|
-
...node,
|
|
93
|
-
config: {
|
|
94
|
-
...config,
|
|
95
|
-
apiKey: {
|
|
96
|
-
prefix: apiKeyPrefix(apiKey),
|
|
97
|
-
hash: hashApiKey(apiKey)
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
return (0,_flow_types_js__rspack_import_1/* .isStoredApiKey */.xA)(apiKey) ? node : {
|
|
102
|
-
...node,
|
|
103
|
-
config
|
|
104
|
-
};
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
__webpack_require__.d(__webpack_exports__, {
|
|
109
|
-
Jb: () => (looksLikeApiKey),
|
|
110
|
-
ue: () => (sealApiKeys)
|
|
111
|
-
}, {
|
|
112
|
-
NT: apiKeyOpens
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
|
|
116
62
|
},
|
|
117
63
|
8333(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
118
64
|
|
|
@@ -610,7 +556,7 @@ async function runValidate(cfg, env, state) {
|
|
|
610
556
|
passed: true
|
|
611
557
|
}
|
|
612
558
|
};
|
|
613
|
-
const status = cfg.statusCode ?? (failed.every((check)=>(0,flow_graph_validator/* .usesPermissionFunction */.
|
|
559
|
+
const status = cfg.statusCode ?? (failed.every((check)=>(0,flow_graph_validator/* .usesPermissionFunction */.u)(check.rule)) ? 403 : 400);
|
|
614
560
|
const errors = failed.map((check)=>({
|
|
615
561
|
field: check.field || check.id,
|
|
616
562
|
message: check.message
|
|
@@ -625,16 +571,19 @@ async function runValidate(cfg, env, state) {
|
|
|
625
571
|
}
|
|
626
572
|
/** `{ allowed, missing }` - `missing` lists the codes the caller does not hold. */ async function runPermissionCheck(cfg, env, state) {
|
|
627
573
|
const codes = (0,rule_permission/* .parsePermissionCodes */.PS)(cfg.codes);
|
|
574
|
+
let branch;
|
|
575
|
+
if (cfg.branch === null) branch = null;
|
|
576
|
+
else if (cfg.branch !== undefined) branch = (0,rule_permission/* .toBranchArgument */.lH)([
|
|
577
|
+
await env.ruleEngine.resolveExpression(cfg.branch, evaluationContext(state, env))
|
|
578
|
+
], 0);
|
|
628
579
|
const permissions = state.permissions ?? env.ruleEngine.createPermissionResolver(state.user);
|
|
629
|
-
const granted = state.user ? await permissions.granted(
|
|
580
|
+
const granted = state.user ? await permissions.granted(branch) : [];
|
|
630
581
|
const missing = codes.filter((code)=>!(0,utils_.matchesPermission)(granted, code));
|
|
631
582
|
const allowed = codes.length > 0 && (cfg.match === 'all' ? missing.length === 0 : missing.length < codes.length);
|
|
632
|
-
|
|
583
|
+
const output = {
|
|
633
584
|
allowed,
|
|
634
585
|
missing
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
/** A denied check: `onDenied: branch` follows the `denied` port, otherwise the run is answered `statusCode` (403). */ function deniedResult(cfg, output, allowed) {
|
|
586
|
+
};
|
|
638
587
|
if (cfg.onDenied === 'branch') return {
|
|
639
588
|
output,
|
|
640
589
|
port: allowed ? 'allowed' : 'denied'
|
|
@@ -650,47 +599,6 @@ async function runValidate(cfg, env, state) {
|
|
|
650
599
|
output
|
|
651
600
|
};
|
|
652
601
|
}
|
|
653
|
-
/** One id, a list of ids, or nothing (undefined / null / empty text), each id once. */ function idList(value) {
|
|
654
|
-
const items = Array.isArray(value) ? value : [
|
|
655
|
-
value
|
|
656
|
-
];
|
|
657
|
-
return [
|
|
658
|
-
...new Set(items.filter((item)=>item !== undefined && item !== null && item !== '').map(String))
|
|
659
|
-
];
|
|
660
|
-
}
|
|
661
|
-
/**
|
|
662
|
-
* `{ userId, companies, branches }` - what the signed-in user may work in (none without a user or
|
|
663
|
-
* the company feature). With `companyIds` / `branchIds` it also answers `allowed` and `missing`:
|
|
664
|
-
* every id asked for must be within reach, and a target that resolves to nothing is a denial, never a pass.
|
|
665
|
-
*/ async function runCompanyBranchCheck(cfg, env, state) {
|
|
666
|
-
const { companies, branches } = state.user ? await env.companyAccess(state.user.id) : {
|
|
667
|
-
companies: [],
|
|
668
|
-
branches: []
|
|
669
|
-
};
|
|
670
|
-
const output = {
|
|
671
|
-
userId: state.user?.id ?? null,
|
|
672
|
-
companies,
|
|
673
|
-
branches
|
|
674
|
-
};
|
|
675
|
-
if (cfg.companyIds === undefined && cfg.branchIds === undefined) return {
|
|
676
|
-
output
|
|
677
|
-
};
|
|
678
|
-
const ctx = evaluationContext(state, env);
|
|
679
|
-
const wanted = async (expression)=>expression === undefined ? null : idList(await env.ruleEngine.resolveExpression(expression, ctx));
|
|
680
|
-
const wantedCompanies = await wanted(cfg.companyIds);
|
|
681
|
-
const wantedBranches = await wanted(cfg.branchIds);
|
|
682
|
-
const missing = {
|
|
683
|
-
companyIds: (wantedCompanies ?? []).filter((id)=>!companies.some((company)=>company.id === id)),
|
|
684
|
-
branchIds: (wantedBranches ?? []).filter((id)=>!branches.some((branch)=>branch.id === id))
|
|
685
|
-
};
|
|
686
|
-
const nothingToCheck = wantedCompanies?.length === 0 || wantedBranches?.length === 0;
|
|
687
|
-
const allowed = !nothingToCheck && !missing.companyIds.length && !missing.branchIds.length;
|
|
688
|
-
return deniedResult(cfg, {
|
|
689
|
-
...output,
|
|
690
|
-
allowed,
|
|
691
|
-
missing
|
|
692
|
-
}, allowed);
|
|
693
|
-
}
|
|
694
602
|
const USES_PERMISSIONS = /\b(permissions|hasPermission|hasAnyPermission|hasAllPermissions)\b/;
|
|
695
603
|
/** The caller as a code step sees it; permission codes (current branch) are fetched only for code that reads them. */ async function codeUser(code, state) {
|
|
696
604
|
const user = state.user;
|
|
@@ -819,16 +727,15 @@ async function updateRecord(entityCode, service, values, state) {
|
|
|
819
727
|
}
|
|
820
728
|
/** @returns false when the record does not exist and `skip` allows that. */ async function deleteRecord(entityCode, service, id, skipMissing, state) {
|
|
821
729
|
countWrite(state);
|
|
822
|
-
let action;
|
|
823
730
|
try {
|
|
824
|
-
|
|
731
|
+
await service.delete(id, state.user, writeOptions(state));
|
|
825
732
|
} catch (error) {
|
|
826
733
|
if (skipMissing && error instanceof common_.NotFoundException) return false;
|
|
827
734
|
throw error;
|
|
828
735
|
}
|
|
829
736
|
if (state.qr) state.pendingEvents.push({
|
|
830
737
|
entityCode,
|
|
831
|
-
action,
|
|
738
|
+
action: 'deleted',
|
|
832
739
|
row: {
|
|
833
740
|
id
|
|
834
741
|
}
|
|
@@ -990,395 +897,6 @@ async function insertChildren(node, child, parentId, env, state) {
|
|
|
990
897
|
})
|
|
991
898
|
};
|
|
992
899
|
}
|
|
993
|
-
/** As strict as the email module's own check, and without the characters that would break an address header. */ const EMAIL_PATTERN = /^[^\s@,;<>"]+@[^\s@,;<>"]+\.[^\s@,;<>"]+$/;
|
|
994
|
-
const MAX_EMAIL_LENGTH = 254;
|
|
995
|
-
const shown = (value)=>String(typeof value === 'object' && value !== null ? JSON.stringify(value) : value).slice(0, 100);
|
|
996
|
-
/** A value as message text: nothing for null / undefined, JSON for an object. */ function asText(value) {
|
|
997
|
-
if (value === null || value === undefined) return '';
|
|
998
|
-
return typeof value === 'object' ? JSON.stringify(value) : String(value);
|
|
999
|
-
}
|
|
1000
|
-
/** Reserves `count` sends of the run's budget before any goes out, so a step never sends only some of its messages because of the limit. */ function countMessages(state, count) {
|
|
1001
|
-
if (state.messages + count > flow_types/* .FLOW_LIMITS.MAX_MESSAGES_PER_RUN */.Or.MAX_MESSAGES_PER_RUN) throw new flow_errors/* .FlowLimitError */.IM(message_keys/* .FLOW_ERROR_MESSAGES.TOO_MANY_MESSAGES */.zr.TOO_MANY_MESSAGES, {
|
|
1002
|
-
max: flow_types/* .FLOW_LIMITS.MAX_MESSAGES_PER_RUN */.Or.MAX_MESSAGES_PER_RUN
|
|
1003
|
-
});
|
|
1004
|
-
state.messages += count;
|
|
1005
|
-
}
|
|
1006
|
-
function assertRecipientCount(node, count, max) {
|
|
1007
|
-
if (count > max) throw new flow_errors/* .FlowLimitError */.IM(message_keys/* .FLOW_ERROR_MESSAGES.TOO_MANY_RECIPIENTS */.zr.TOO_MANY_RECIPIENTS, {
|
|
1008
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node),
|
|
1009
|
-
count,
|
|
1010
|
-
max
|
|
1011
|
-
});
|
|
1012
|
-
}
|
|
1013
|
-
/** Whatever the module threw, or its `success: false`, fails the step with the reason (a limit stays a limit). */ function sendFailure(key, node, error) {
|
|
1014
|
-
if (error instanceof flow_errors/* .FlowKeyedError */.Hp || error instanceof flow_errors/* .FlowHttpError */.hk) return error;
|
|
1015
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
1016
|
-
return new flow_errors/* .FlowKeyedError */.Hp(key, {
|
|
1017
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node),
|
|
1018
|
-
detail
|
|
1019
|
-
}, `"${(0,flow_types/* .nodeLabel */.dA)(node)}" could not send: ${detail}`);
|
|
1020
|
-
}
|
|
1021
|
-
/** Inside a transaction the message waits for the commit, so a run that rolls back sends nothing. */ async function deliver(node, state, send) {
|
|
1022
|
-
if (state.qr) {
|
|
1023
|
-
state.pendingEvents.push({
|
|
1024
|
-
delivery: (0,flow_types/* .nodeLabel */.dA)(node),
|
|
1025
|
-
send
|
|
1026
|
-
});
|
|
1027
|
-
return 'queued';
|
|
1028
|
-
}
|
|
1029
|
-
await send();
|
|
1030
|
-
return 'sent';
|
|
1031
|
-
}
|
|
1032
|
-
/** One id or a list of them, each once; null / undefined / empty text is none. Anything but an id rejects with `key`. */ function idsOf(node, value, key, text) {
|
|
1033
|
-
const items = (Array.isArray(value) ? value : [
|
|
1034
|
-
value
|
|
1035
|
-
]).filter((item)=>item !== undefined && item !== null && item !== '');
|
|
1036
|
-
for (const item of items){
|
|
1037
|
-
if (typeof item !== 'string' || !flow_types/* .FLOW_ID_PATTERN.test */.E2.test(item)) {
|
|
1038
|
-
throw new flow_errors/* .FlowHttpError */.hk(400, text(shown(item)), undefined, {
|
|
1039
|
-
messageKey: key,
|
|
1040
|
-
messageVariables: {
|
|
1041
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node),
|
|
1042
|
-
value: shown(item)
|
|
1043
|
-
}
|
|
1044
|
-
});
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
return [
|
|
1048
|
-
...new Set(items)
|
|
1049
|
-
];
|
|
1050
|
-
}
|
|
1051
|
-
const notificationRecipients = (node, value)=>idsOf(node, value, message_keys/* .FLOW_ERROR_MESSAGES.NOTIFICATION_RECIPIENT_INVALID */.zr.NOTIFICATION_RECIPIENT_INVALID, (shownValue)=>`"${(0,flow_types/* .nodeLabel */.dA)(node)}" cannot notify "${shownValue}": it is not a user id.`);
|
|
1052
|
-
/** Addresses: one, a list, or comma / semicolon separated text; each once (case aside), in the order given. */ function emailAddresses(node, value) {
|
|
1053
|
-
const items = (Array.isArray(value) ? value : [
|
|
1054
|
-
value
|
|
1055
|
-
]).filter((item)=>item !== undefined && item !== null);
|
|
1056
|
-
const seen = new Map();
|
|
1057
|
-
for (const item of items){
|
|
1058
|
-
const parts = typeof item === 'string' ? item.split(/[,;]/) : [
|
|
1059
|
-
item
|
|
1060
|
-
];
|
|
1061
|
-
for (const part of parts){
|
|
1062
|
-
const address = typeof part === 'string' ? part.trim() : part;
|
|
1063
|
-
if (address === '') continue;
|
|
1064
|
-
if (typeof address !== 'string' || address.length > MAX_EMAIL_LENGTH || !EMAIL_PATTERN.test(address)) {
|
|
1065
|
-
throw new flow_errors/* .FlowHttpError */.hk(400, `"${shown(address)}" is not a valid email address.`, undefined, {
|
|
1066
|
-
messageKey: message_keys/* .FLOW_ERROR_MESSAGES.EMAIL_ADDRESS_INVALID */.zr.EMAIL_ADDRESS_INVALID,
|
|
1067
|
-
messageVariables: {
|
|
1068
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node),
|
|
1069
|
-
address: shown(address)
|
|
1070
|
-
}
|
|
1071
|
-
});
|
|
1072
|
-
}
|
|
1073
|
-
if (!seen.has(address.toLowerCase())) seen.set(address.toLowerCase(), address);
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
return [
|
|
1077
|
-
...seen.values()
|
|
1078
|
-
];
|
|
1079
|
-
}
|
|
1080
|
-
/** The company a notification shows under: the one given, else the caller's current one. */ function notificationCompany(node, value, given, state) {
|
|
1081
|
-
if (!given) return state.user?.companyId ?? null;
|
|
1082
|
-
if (value === undefined || value === null || value === '') return null;
|
|
1083
|
-
if (typeof value === 'string' && flow_types/* .FLOW_ID_PATTERN.test */.E2.test(value)) return value;
|
|
1084
|
-
throw new flow_errors/* .FlowHttpError */.hk(400, `"${(0,flow_types/* .nodeLabel */.dA)(node)}": "${shown(value)}" is not a company id.`, undefined, {
|
|
1085
|
-
messageKey: message_keys/* .FLOW_ERROR_MESSAGES.NOTIFICATION_COMPANY_INVALID */.zr.NOTIFICATION_COMPANY_INVALID,
|
|
1086
|
-
messageVariables: {
|
|
1087
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node),
|
|
1088
|
-
value: shown(value)
|
|
1089
|
-
}
|
|
1090
|
-
});
|
|
1091
|
-
}
|
|
1092
|
-
/** Sends `batches` (each already checked) as one step: the run's budget is taken for all of them first; a test run sends nothing. */ async function sendAll(node, state, batches, skipKey, recipients, send) {
|
|
1093
|
-
countMessages(state, batches.length);
|
|
1094
|
-
if (state.mode === 'dry_run') return {
|
|
1095
|
-
output: {
|
|
1096
|
-
skipped: true,
|
|
1097
|
-
reasonKey: skipKey,
|
|
1098
|
-
count: batches.length,
|
|
1099
|
-
recipients
|
|
1100
|
-
},
|
|
1101
|
-
skipped: true
|
|
1102
|
-
};
|
|
1103
|
-
let status = 'sent';
|
|
1104
|
-
for (const batch of batches)status = await deliver(node, state, ()=>send(batch));
|
|
1105
|
-
return status;
|
|
1106
|
-
}
|
|
1107
|
-
const nobody = (extra = {})=>({
|
|
1108
|
-
output: {
|
|
1109
|
-
skipped: true,
|
|
1110
|
-
reasonKey: message_keys/* .FLOW_SKIP_MESSAGES.NO_RECIPIENTS */.CB.NO_RECIPIENTS,
|
|
1111
|
-
recipients: 0,
|
|
1112
|
-
...extra
|
|
1113
|
-
},
|
|
1114
|
-
skipped: true
|
|
1115
|
-
});
|
|
1116
|
-
/** Title, message, type, data and push of a notification, read in the current scope (the item's, in many mode). */ async function notificationContent(node, cfg, env, state) {
|
|
1117
|
-
const ctx = evaluationContext(state, env);
|
|
1118
|
-
const title = asText(await env.ruleEngine.resolveExpression(cfg.title, ctx)).trim().slice(0, flow_types/* .FLOW_LIMITS.MAX_NOTIFICATION_TITLE_LENGTH */.Or.MAX_NOTIFICATION_TITLE_LENGTH);
|
|
1119
|
-
if (!title) throw new flow_errors/* .FlowHttpError */.hk(400, `The title of "${(0,flow_types/* .nodeLabel */.dA)(node)}" is empty.`, undefined, {
|
|
1120
|
-
messageKey: message_keys/* .FLOW_ERROR_MESSAGES.NOTIFICATION_TITLE_EMPTY */.zr.NOTIFICATION_TITLE_EMPTY,
|
|
1121
|
-
messageVariables: {
|
|
1122
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node)
|
|
1123
|
-
}
|
|
1124
|
-
});
|
|
1125
|
-
const message = cfg.message === undefined ? '' : asText(await env.ruleEngine.resolveExpression(cfg.message, ctx));
|
|
1126
|
-
const data = cfg.data && Object.keys(cfg.data).length ? await mapValues(cfg.data, env, state) : null;
|
|
1127
|
-
return {
|
|
1128
|
-
title,
|
|
1129
|
-
message: message || null,
|
|
1130
|
-
type: cfg.type ?? 'info',
|
|
1131
|
-
data,
|
|
1132
|
-
realtime: cfg.realtime !== false
|
|
1133
|
-
};
|
|
1134
|
-
}
|
|
1135
|
-
/** One notification to the users `userIds` names, or null when that is nobody. */ async function userNotification(node, cfg, env, state) {
|
|
1136
|
-
const ctx = evaluationContext(state, env);
|
|
1137
|
-
const userIds = notificationRecipients(node, cfg.userIds === undefined ? undefined : await env.ruleEngine.resolveExpression(cfg.userIds, ctx));
|
|
1138
|
-
if (!userIds.length) return null;
|
|
1139
|
-
assertRecipientCount(node, userIds.length, flow_types/* .FLOW_LIMITS.MAX_NOTIFICATION_RECIPIENTS */.Or.MAX_NOTIFICATION_RECIPIENTS);
|
|
1140
|
-
const content = await notificationContent(node, cfg, env, state);
|
|
1141
|
-
const companyId = notificationCompany(node, cfg.companyId === undefined ? undefined : await env.ruleEngine.resolveExpression(cfg.companyId, ctx), cfg.companyId !== undefined, state);
|
|
1142
|
-
return {
|
|
1143
|
-
...content,
|
|
1144
|
-
userIds,
|
|
1145
|
-
companyId
|
|
1146
|
-
};
|
|
1147
|
-
}
|
|
1148
|
-
/**
|
|
1149
|
-
* A company-wide notification may reach only companies the run may speak for: any, for a run granted
|
|
1150
|
-
* the system; otherwise only those the signed-in caller works in.
|
|
1151
|
-
*/ async function assertMayNotifyCompanies(node, companyIds, env, state) {
|
|
1152
|
-
if (state.runAs === 'system' && state.systemAuthorized === true) return;
|
|
1153
|
-
const reachable = state.user ? new Set((await env.companyAccess(state.user.id)).companies.map((company)=>company.id)) : new Set();
|
|
1154
|
-
const denied = companyIds.find((id)=>!reachable.has(id));
|
|
1155
|
-
if (denied) {
|
|
1156
|
-
throw new flow_errors/* .FlowHttpError */.hk(403, `"${(0,flow_types/* .nodeLabel */.dA)(node)}" may not notify the company "${denied}".`, undefined, {
|
|
1157
|
-
messageKey: message_keys/* .FLOW_ERROR_MESSAGES.NOTIFICATION_COMPANY_DENIED */.zr.NOTIFICATION_COMPANY_DENIED,
|
|
1158
|
-
messageVariables: {
|
|
1159
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node),
|
|
1160
|
-
company: denied
|
|
1161
|
-
}
|
|
1162
|
-
});
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
/** One notification per company that has members, each shown under its own company. */ async function companyNotifications(node, cfg, env, state) {
|
|
1166
|
-
const companyMembers = env.companyMembers;
|
|
1167
|
-
if (!companyMembers) {
|
|
1168
|
-
throw new flow_errors/* .FlowKeyedError */.Hp(message_keys/* .FLOW_ERROR_MESSAGES.NOTIFICATION_COMPANY_UNAVAILABLE */.zr.NOTIFICATION_COMPANY_UNAVAILABLE, {
|
|
1169
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node)
|
|
1170
|
-
}, `"${(0,flow_types/* .nodeLabel */.dA)(node)}" notifies companies, which needs the company feature.`);
|
|
1171
|
-
}
|
|
1172
|
-
const ctx = evaluationContext(state, env);
|
|
1173
|
-
const resolve = async (expression)=>expression === undefined ? undefined : env.ruleEngine.resolveExpression(expression, ctx);
|
|
1174
|
-
const companyIds = idsOf(node, await resolve(cfg.companyIds), message_keys/* .FLOW_ERROR_MESSAGES.NOTIFICATION_COMPANY_INVALID */.zr.NOTIFICATION_COMPANY_INVALID, (value)=>`"${(0,flow_types/* .nodeLabel */.dA)(node)}": "${value}" is not a company id.`);
|
|
1175
|
-
const branchIds = idsOf(node, await resolve(cfg.branchIds), message_keys/* .FLOW_ERROR_MESSAGES.NOTIFICATION_BRANCH_INVALID */.zr.NOTIFICATION_BRANCH_INVALID, (value)=>`"${(0,flow_types/* .nodeLabel */.dA)(node)}": "${value}" is not a branch id.`);
|
|
1176
|
-
if (!companyIds.length) return [];
|
|
1177
|
-
await assertMayNotifyCompanies(node, companyIds, env, state);
|
|
1178
|
-
const content = await notificationContent(node, cfg, env, state);
|
|
1179
|
-
const batches = [];
|
|
1180
|
-
let total = 0;
|
|
1181
|
-
for (const companyId of companyIds){
|
|
1182
|
-
const userIds = await companyMembers(companyId, branchIds.length ? branchIds : undefined);
|
|
1183
|
-
total += userIds.length;
|
|
1184
|
-
assertRecipientCount(node, total, flow_types/* .FLOW_LIMITS.MAX_COMPANY_NOTIFICATION_RECIPIENTS */.Or.MAX_COMPANY_NOTIFICATION_RECIPIENTS);
|
|
1185
|
-
if (userIds.length) batches.push({
|
|
1186
|
-
...content,
|
|
1187
|
-
userIds,
|
|
1188
|
-
companyId
|
|
1189
|
-
});
|
|
1190
|
-
}
|
|
1191
|
-
return batches;
|
|
1192
|
-
}
|
|
1193
|
-
/**
|
|
1194
|
-
* one: `{ status, recipients }`. many / company: `{ status, count, recipients }` (+ `skipped` items
|
|
1195
|
-
* with nobody to notify, in many mode). `status` is `sent`, or `queued` inside a transaction (sent once
|
|
1196
|
-
* it commits). Every message is checked before the first goes out; nobody at all skips the step, and
|
|
1197
|
-
* a test run checks everything but sends nothing.
|
|
1198
|
-
*/ async function runSendNotification(node, cfg, env, state) {
|
|
1199
|
-
const notifications = env.notifications;
|
|
1200
|
-
if (!notifications) throw new flow_errors/* .FlowKeyedError */.Hp(message_keys/* .FLOW_ERROR_MESSAGES.NOTIFICATION_UNAVAILABLE */.zr.NOTIFICATION_UNAVAILABLE, {
|
|
1201
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node)
|
|
1202
|
-
}, `"${(0,flow_types/* .nodeLabel */.dA)(node)}" needs the notification module, which this app does not run.`);
|
|
1203
|
-
const target = cfg.target ?? 'one';
|
|
1204
|
-
let batches;
|
|
1205
|
-
let skippedItems = 0;
|
|
1206
|
-
if (target === 'company') {
|
|
1207
|
-
batches = await companyNotifications(node, cfg, env, state);
|
|
1208
|
-
} else if (target === 'many') {
|
|
1209
|
-
const items = await resolveList(node, cfg.items, flow_types/* .FLOW_LIMITS.MAX_MESSAGES_PER_RUN */.Or.MAX_MESSAGES_PER_RUN, env, state);
|
|
1210
|
-
const prepared = await eachItem(state, items, ()=>userNotification(node, cfg, env, state));
|
|
1211
|
-
batches = prepared.filter((batch)=>batch !== null);
|
|
1212
|
-
skippedItems = prepared.length - batches.length;
|
|
1213
|
-
} else {
|
|
1214
|
-
batches = [
|
|
1215
|
-
await userNotification(node, cfg, env, state)
|
|
1216
|
-
].filter((batch)=>batch !== null);
|
|
1217
|
-
}
|
|
1218
|
-
const counts = target === 'one' ? {} : {
|
|
1219
|
-
count: batches.length,
|
|
1220
|
-
...target === 'many' ? {
|
|
1221
|
-
skipped: skippedItems
|
|
1222
|
-
} : {}
|
|
1223
|
-
};
|
|
1224
|
-
if (!batches.length) return nobody(counts);
|
|
1225
|
-
const recipients = batches.reduce((sum, batch)=>sum + batch.userIds.length, 0);
|
|
1226
|
-
const sent = await sendAll(node, state, batches, message_keys/* .FLOW_SKIP_MESSAGES.NOTIFICATION */.CB.NOTIFICATION, recipients, async (batch)=>{
|
|
1227
|
-
try {
|
|
1228
|
-
await notifications.sendToMany(batch);
|
|
1229
|
-
} catch (error) {
|
|
1230
|
-
throw sendFailure(message_keys/* .FLOW_ERROR_MESSAGES.NOTIFICATION_FAILED */.zr.NOTIFICATION_FAILED, node, error);
|
|
1231
|
-
}
|
|
1232
|
-
});
|
|
1233
|
-
if (typeof sent !== 'string') return sent;
|
|
1234
|
-
return {
|
|
1235
|
-
output: {
|
|
1236
|
-
status: sent,
|
|
1237
|
-
recipients,
|
|
1238
|
-
...counts
|
|
1239
|
-
}
|
|
1240
|
-
};
|
|
1241
|
-
}
|
|
1242
|
-
/** One email, read in the current scope (the item's, in many mode), or null when `to` has no address. */ async function prepareEmail(node, cfg, email, env, state) {
|
|
1243
|
-
const ctx = evaluationContext(state, env);
|
|
1244
|
-
const addresses = async (expression)=>expression === undefined ? [] : emailAddresses(node, await env.ruleEngine.resolveExpression(expression, ctx));
|
|
1245
|
-
const to = await addresses(cfg.to);
|
|
1246
|
-
if (!to.length) return null;
|
|
1247
|
-
// Someone already on `to` gets the email once.
|
|
1248
|
-
const listed = new Set(to.map((address)=>address.toLowerCase()));
|
|
1249
|
-
const notListed = (list)=>{
|
|
1250
|
-
const kept = list.filter((address)=>!listed.has(address.toLowerCase()));
|
|
1251
|
-
kept.forEach((address)=>listed.add(address.toLowerCase()));
|
|
1252
|
-
return kept;
|
|
1253
|
-
};
|
|
1254
|
-
const cc = notListed(await addresses(cfg.cc));
|
|
1255
|
-
const bcc = notListed(await addresses(cfg.bcc));
|
|
1256
|
-
const recipients = to.length + cc.length + bcc.length;
|
|
1257
|
-
assertRecipientCount(node, recipients, flow_types/* .FLOW_LIMITS.MAX_EMAIL_RECIPIENTS */.Or.MAX_EMAIL_RECIPIENTS);
|
|
1258
|
-
const replyTo = await addresses(cfg.replyTo);
|
|
1259
|
-
if (replyTo.length > 1) {
|
|
1260
|
-
throw new flow_errors/* .FlowHttpError */.hk(400, `"${replyTo.join(', ')}" is not a single email address.`, undefined, {
|
|
1261
|
-
messageKey: message_keys/* .FLOW_ERROR_MESSAGES.EMAIL_ADDRESS_INVALID */.zr.EMAIL_ADDRESS_INVALID,
|
|
1262
|
-
messageVariables: {
|
|
1263
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node),
|
|
1264
|
-
address: shown(replyTo.join(', '))
|
|
1265
|
-
}
|
|
1266
|
-
});
|
|
1267
|
-
}
|
|
1268
|
-
const base = {
|
|
1269
|
-
to,
|
|
1270
|
-
...cc.length ? {
|
|
1271
|
-
cc
|
|
1272
|
-
} : {},
|
|
1273
|
-
...bcc.length ? {
|
|
1274
|
-
bcc
|
|
1275
|
-
} : {},
|
|
1276
|
-
...replyTo.length ? {
|
|
1277
|
-
replyTo: replyTo[0]
|
|
1278
|
-
} : {},
|
|
1279
|
-
...cfg.emailConfigId ? {
|
|
1280
|
-
emailConfigId: cfg.emailConfigId
|
|
1281
|
-
} : {}
|
|
1282
|
-
};
|
|
1283
|
-
const user = state.user;
|
|
1284
|
-
if (cfg.mode === 'template') {
|
|
1285
|
-
const variables = await mapValues(cfg.variables, env, state);
|
|
1286
|
-
const templateSlug = (cfg.templateSlug ?? '').trim();
|
|
1287
|
-
return {
|
|
1288
|
-
recipients,
|
|
1289
|
-
send: ()=>email.sendTemplate({
|
|
1290
|
-
...base,
|
|
1291
|
-
templateSlug,
|
|
1292
|
-
variables
|
|
1293
|
-
}, user)
|
|
1294
|
-
};
|
|
1295
|
-
}
|
|
1296
|
-
// A line break in a subject would start a new mail header.
|
|
1297
|
-
const subject = asText(cfg.subject === undefined ? '' : await env.ruleEngine.resolveExpression(cfg.subject, ctx)).replace(/[\r\n]+/g, ' ').trim().slice(0, flow_types/* .FLOW_LIMITS.MAX_EMAIL_SUBJECT_LENGTH */.Or.MAX_EMAIL_SUBJECT_LENGTH);
|
|
1298
|
-
if (!subject) throw new flow_errors/* .FlowHttpError */.hk(400, `The subject of "${(0,flow_types/* .nodeLabel */.dA)(node)}" is empty.`, undefined, {
|
|
1299
|
-
messageKey: message_keys/* .FLOW_ERROR_MESSAGES.EMAIL_SUBJECT_EMPTY */.zr.EMAIL_SUBJECT_EMPTY,
|
|
1300
|
-
messageVariables: {
|
|
1301
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node)
|
|
1302
|
-
}
|
|
1303
|
-
});
|
|
1304
|
-
const html = cfg.format === 'html';
|
|
1305
|
-
const body = cfg.body === undefined ? '' : asText(html ? await env.ruleEngine.resolveHtml(cfg.body, ctx) : await env.ruleEngine.resolveExpression(cfg.body, ctx));
|
|
1306
|
-
if (!body.trim()) throw new flow_errors/* .FlowHttpError */.hk(400, `The message of "${(0,flow_types/* .nodeLabel */.dA)(node)}" is empty.`, undefined, {
|
|
1307
|
-
messageKey: message_keys/* .FLOW_ERROR_MESSAGES.EMAIL_BODY_EMPTY */.zr.EMAIL_BODY_EMPTY,
|
|
1308
|
-
messageVariables: {
|
|
1309
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node)
|
|
1310
|
-
}
|
|
1311
|
-
});
|
|
1312
|
-
return {
|
|
1313
|
-
recipients,
|
|
1314
|
-
send: ()=>email.send({
|
|
1315
|
-
...base,
|
|
1316
|
-
subject,
|
|
1317
|
-
...html ? {
|
|
1318
|
-
html: body
|
|
1319
|
-
} : {
|
|
1320
|
-
text: body
|
|
1321
|
-
}
|
|
1322
|
-
}, user)
|
|
1323
|
-
};
|
|
1324
|
-
}
|
|
1325
|
-
/**
|
|
1326
|
-
* one: `{ status, recipients, messageId }`. many: `{ status, count, recipients, skipped, messageIds }`
|
|
1327
|
-
* (one id per email sent, in order). `status` is `sent`, or `queued` inside a transaction (sent once it
|
|
1328
|
-
* commits, no ids yet). Every email is checked before the first goes out; no address at all skips the
|
|
1329
|
-
* step, and a test run checks everything but sends nothing.
|
|
1330
|
-
*/ async function runSendEmail(node, cfg, env, state) {
|
|
1331
|
-
const email = env.email;
|
|
1332
|
-
if (!email) throw new flow_errors/* .FlowKeyedError */.Hp(message_keys/* .FLOW_ERROR_MESSAGES.EMAIL_UNAVAILABLE */.zr.EMAIL_UNAVAILABLE, {
|
|
1333
|
-
node: (0,flow_types/* .nodeLabel */.dA)(node)
|
|
1334
|
-
}, `"${(0,flow_types/* .nodeLabel */.dA)(node)}" needs the email module, which this app does not run.`);
|
|
1335
|
-
const many = cfg.target === 'many';
|
|
1336
|
-
let emails;
|
|
1337
|
-
let skippedItems = 0;
|
|
1338
|
-
if (many) {
|
|
1339
|
-
const items = await resolveList(node, cfg.items, flow_types/* .FLOW_LIMITS.MAX_MESSAGES_PER_RUN */.Or.MAX_MESSAGES_PER_RUN, env, state);
|
|
1340
|
-
const prepared = await eachItem(state, items, ()=>prepareEmail(node, cfg, email, env, state));
|
|
1341
|
-
emails = prepared.filter((item)=>item !== null);
|
|
1342
|
-
skippedItems = prepared.length - emails.length;
|
|
1343
|
-
} else {
|
|
1344
|
-
emails = [
|
|
1345
|
-
await prepareEmail(node, cfg, email, env, state)
|
|
1346
|
-
].filter((prepared)=>prepared !== null);
|
|
1347
|
-
}
|
|
1348
|
-
if (!emails.length) return nobody(many ? {
|
|
1349
|
-
count: 0,
|
|
1350
|
-
skipped: skippedItems
|
|
1351
|
-
} : {});
|
|
1352
|
-
const recipients = emails.reduce((sum, prepared)=>sum + prepared.recipients, 0);
|
|
1353
|
-
const messageIds = [];
|
|
1354
|
-
const sent = await sendAll(node, state, emails, message_keys/* .FLOW_SKIP_MESSAGES.EMAIL */.CB.EMAIL, recipients, async (prepared)=>{
|
|
1355
|
-
let result;
|
|
1356
|
-
try {
|
|
1357
|
-
result = await prepared.send();
|
|
1358
|
-
} catch (error) {
|
|
1359
|
-
throw sendFailure(message_keys/* .FLOW_ERROR_MESSAGES.EMAIL_FAILED */.zr.EMAIL_FAILED, node, error);
|
|
1360
|
-
}
|
|
1361
|
-
if (!result?.success) throw sendFailure(message_keys/* .FLOW_ERROR_MESSAGES.EMAIL_FAILED */.zr.EMAIL_FAILED, node, result?.error || 'The email was not accepted.');
|
|
1362
|
-
messageIds.push(result.messageId ?? null);
|
|
1363
|
-
});
|
|
1364
|
-
if (typeof sent !== 'string') return sent;
|
|
1365
|
-
if (!many) return {
|
|
1366
|
-
output: {
|
|
1367
|
-
status: sent,
|
|
1368
|
-
recipients,
|
|
1369
|
-
messageId: messageIds[0] ?? null
|
|
1370
|
-
}
|
|
1371
|
-
};
|
|
1372
|
-
return {
|
|
1373
|
-
output: {
|
|
1374
|
-
status: sent,
|
|
1375
|
-
count: emails.length,
|
|
1376
|
-
recipients,
|
|
1377
|
-
skipped: skippedItems,
|
|
1378
|
-
messageIds
|
|
1379
|
-
}
|
|
1380
|
-
};
|
|
1381
|
-
}
|
|
1382
900
|
/** Runs one node. Ports/branching/looping are the executor's job; this only does the node's own work. */ async function runNode(node, env, state) {
|
|
1383
901
|
const ctx = evaluationContext(state, env);
|
|
1384
902
|
const c = node.config;
|
|
@@ -1393,8 +911,6 @@ const nobody = (extra = {})=>({
|
|
|
1393
911
|
return runCode(node, c, state);
|
|
1394
912
|
case 'permission_check':
|
|
1395
913
|
return runPermissionCheck(c, env, state);
|
|
1396
|
-
case 'company_branch_check':
|
|
1397
|
-
return runCompanyBranchCheck(c, env, state);
|
|
1398
914
|
case 'set':
|
|
1399
915
|
{
|
|
1400
916
|
const cfg = c;
|
|
@@ -1545,7 +1061,6 @@ const nobody = (extra = {})=>({
|
|
|
1545
1061
|
k,
|
|
1546
1062
|
String(v ?? '')
|
|
1547
1063
|
]));
|
|
1548
|
-
if (cfg.forwardAuth === true && state.authorization && !Object.keys(headers).some((name)=>name.toLowerCase() === 'authorization')) headers['authorization'] = state.authorization;
|
|
1549
1064
|
const body = cfg.body && Object.keys(cfg.body).length ? await mapValues(cfg.body, env, state) : undefined;
|
|
1550
1065
|
const remaining = state.deadline - Date.now();
|
|
1551
1066
|
if (remaining <= 0) throw new flow_errors/* .FlowLimitError */.IM(message_keys/* .FLOW_ERROR_MESSAGES.OUT_OF_TIME */.zr.OUT_OF_TIME);
|
|
@@ -1584,10 +1099,6 @@ const nobody = (extra = {})=>({
|
|
|
1584
1099
|
}
|
|
1585
1100
|
};
|
|
1586
1101
|
}
|
|
1587
|
-
case 'send_notification':
|
|
1588
|
-
return runSendNotification(node, c, env, state);
|
|
1589
|
-
case 'send_email':
|
|
1590
|
-
return runSendEmail(node, c, env, state);
|
|
1591
1102
|
case 'respond':
|
|
1592
1103
|
{
|
|
1593
1104
|
const cfg = c;
|
|
@@ -1868,16 +1379,14 @@ function successResult(state, startedAt) {
|
|
|
1868
1379
|
},
|
|
1869
1380
|
3186(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
1870
1381
|
/* import */ var _flusys_nestjs_shared_utils__rspack_import_0 = __webpack_require__(9216);
|
|
1871
|
-
/* import */ var
|
|
1872
|
-
/* import */ var
|
|
1382
|
+
/* import */ var _config_entity_builder_constants_js__rspack_import_8 = __webpack_require__(6576);
|
|
1383
|
+
/* import */ var _config_message_keys_js__rspack_import_7 = __webpack_require__(5732);
|
|
1873
1384
|
/* import */ var _interfaces_generic_record_interface_js__rspack_import_1 = __webpack_require__(3372);
|
|
1874
|
-
/* import */ var _rule_engine_index_js__rspack_import_2 = __webpack_require__(
|
|
1385
|
+
/* import */ var _rule_engine_index_js__rspack_import_2 = __webpack_require__(5920);
|
|
1875
1386
|
/* import */ var _rule_engine_rule_ip_js__rspack_import_3 = __webpack_require__(809);
|
|
1876
1387
|
/* import */ var _rule_engine_rule_permission_js__rspack_import_4 = __webpack_require__(5191);
|
|
1877
1388
|
/* import */ var _rule_engine_rule_regex_js__rspack_import_5 = __webpack_require__(6308);
|
|
1878
1389
|
/* import */ var _flow_types_js__rspack_import_6 = __webpack_require__(6256);
|
|
1879
|
-
/* import */ var _flow_api_key_js__rspack_import_7 = __webpack_require__(4816);
|
|
1880
|
-
|
|
1881
1390
|
|
|
1882
1391
|
|
|
1883
1392
|
|
|
@@ -2058,37 +1567,37 @@ function isExpression(value) {
|
|
|
2058
1567
|
return !!value && typeof value === 'object' && typeof value.type === 'string';
|
|
2059
1568
|
}
|
|
2060
1569
|
/** Expression shape check with the engine's limits (no evaluation). */ function expressionProblem(value, depth = 0, options = {}) {
|
|
2061
|
-
if (!isExpression(value)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2062
|
-
if (depth > _rule_engine_index_js__rspack_import_2/* .RULE_ENGINE_LIMITS.MAX_GROUP_DEPTH */.bw.MAX_GROUP_DEPTH) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1570
|
+
if (!isExpression(value)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.NOT_AN_EXPRESSION */.IP.NOT_AN_EXPRESSION);
|
|
1571
|
+
if (depth > _rule_engine_index_js__rspack_import_2/* .RULE_ENGINE_LIMITS.MAX_GROUP_DEPTH */.bw.MAX_GROUP_DEPTH) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.TOO_DEEP */.IP.TOO_DEEP);
|
|
2063
1572
|
switch(value.type){
|
|
2064
1573
|
case 'literal':
|
|
2065
1574
|
return null;
|
|
2066
1575
|
case 'field_ref':
|
|
2067
|
-
return typeof value.ref === 'string' && value.ref.length > 0 ? null : (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1576
|
+
return typeof value.ref === 'string' && value.ref.length > 0 ? null : (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.EMPTY_REFERENCE */.IP.EMPTY_REFERENCE);
|
|
2068
1577
|
case 'template':
|
|
2069
|
-
if (typeof value.template !== 'string') return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2070
|
-
return value.template.length <= _rule_engine_index_js__rspack_import_2/* .RULE_TEMPLATE_MAX_LENGTH */.ym ? null : (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1578
|
+
if (typeof value.template !== 'string') return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.NO_TEMPLATE_TEXT */.IP.NO_TEMPLATE_TEXT);
|
|
1579
|
+
return value.template.length <= _rule_engine_index_js__rspack_import_2/* .RULE_TEMPLATE_MAX_LENGTH */.ym ? null : (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.TEMPLATE_TOO_LONG */.IP.TEMPLATE_TOO_LONG);
|
|
2071
1580
|
case 'arithmetic':
|
|
2072
|
-
return Array.isArray(value.operands) ? firstProblem(value.operands, depth, options) : (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1581
|
+
return Array.isArray(value.operands) ? firstProblem(value.operands, depth, options) : (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.NO_OPERANDS */.IP.NO_OPERANDS);
|
|
2073
1582
|
case 'concat':
|
|
2074
|
-
return Array.isArray(value.parts) ? firstProblem(value.parts, depth, options) : (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1583
|
+
return Array.isArray(value.parts) ? firstProblem(value.parts, depth, options) : (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.NO_PARTS */.IP.NO_PARTS);
|
|
2075
1584
|
case 'function':
|
|
2076
1585
|
return functionProblem(value, depth, options);
|
|
2077
1586
|
case 'lookup':
|
|
2078
1587
|
return lookupProblem(value, depth, options);
|
|
2079
1588
|
default:
|
|
2080
|
-
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1589
|
+
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.UNKNOWN_EXPRESSION_TYPE */.IP.UNKNOWN_EXPRESSION_TYPE, {
|
|
2081
1590
|
type: value.type
|
|
2082
1591
|
});
|
|
2083
1592
|
}
|
|
2084
1593
|
}
|
|
2085
1594
|
function functionProblem(value, depth, options) {
|
|
2086
|
-
if (!Array.isArray(value.args)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1595
|
+
if (!Array.isArray(value.args)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.NO_ARGUMENTS */.IP.NO_ARGUMENTS);
|
|
2087
1596
|
const arity = FUNCTION_ARITY[value.name];
|
|
2088
|
-
if (!arity) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1597
|
+
if (!arity) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.UNKNOWN_FUNCTION */.IP.UNKNOWN_FUNCTION, {
|
|
2089
1598
|
name: String(value.name)
|
|
2090
1599
|
});
|
|
2091
|
-
if (value.args.length < arity[0] || value.args.length > arity[1]) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1600
|
+
if (value.args.length < arity[0] || value.args.length > arity[1]) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.WRONG_ARGUMENT_COUNT */.IP.WRONG_ARGUMENT_COUNT, {
|
|
2092
1601
|
name: value.name,
|
|
2093
1602
|
min: arity[0],
|
|
2094
1603
|
max: arity[1]
|
|
@@ -2096,7 +1605,7 @@ function functionProblem(value, depth, options) {
|
|
|
2096
1605
|
const unitAt = DURATION_ARG[value.name];
|
|
2097
1606
|
const unit = unitAt === undefined ? undefined : value.args[unitAt];
|
|
2098
1607
|
if (unit?.type === 'literal' && !_rule_engine_index_js__rspack_import_2/* .RULE_DURATION_UNITS.includes */.qO.includes(unit.value)) {
|
|
2099
|
-
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1608
|
+
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.DURATION_UNIT_INVALID */.IP.DURATION_UNIT_INVALID, {
|
|
2100
1609
|
units: _rule_engine_index_js__rspack_import_2/* .RULE_DURATION_UNITS.join */.qO.join(', ')
|
|
2101
1610
|
});
|
|
2102
1611
|
}
|
|
@@ -2119,18 +1628,18 @@ function functionProblem(value, depth, options) {
|
|
|
2119
1628
|
try {
|
|
2120
1629
|
parsed = (0,_rule_engine_rule_permission_js__rspack_import_4/* .parsePermissionCodes */.PS)(codes.value);
|
|
2121
1630
|
} catch {
|
|
2122
|
-
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1631
|
+
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .RULE_ENGINE_MESSAGES.TOO_MANY_PERMISSION_CODES */.x3.TOO_MANY_PERMISSION_CODES, {
|
|
2123
1632
|
max: _rule_engine_index_js__rspack_import_2/* .RULE_ENGINE_LIMITS.MAX_PERMISSION_CODES */.bw.MAX_PERMISSION_CODES
|
|
2124
1633
|
});
|
|
2125
1634
|
}
|
|
2126
|
-
return parsed.length ? null : (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1635
|
+
return parsed.length ? null : (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.PERMISSION_CODE_REQUIRED */.IP.PERMISSION_CODE_REQUIRED, {
|
|
2127
1636
|
name: value.name
|
|
2128
1637
|
});
|
|
2129
1638
|
}
|
|
2130
1639
|
if (value.name === 'IP_IN_RANGE') {
|
|
2131
1640
|
const ranges = literal(1);
|
|
2132
1641
|
const invalid = ranges.ok ? (0,_rule_engine_rule_ip_js__rspack_import_3/* .invalidIpRange */.I8)(ranges.value) : null;
|
|
2133
|
-
return invalid ? (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1642
|
+
return invalid ? (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.IP_RANGE_INVALID */.IP.IP_RANGE_INVALID, {
|
|
2134
1643
|
range: invalid
|
|
2135
1644
|
}) : null;
|
|
2136
1645
|
}
|
|
@@ -2144,13 +1653,13 @@ function functionProblem(value, depth, options) {
|
|
|
2144
1653
|
function patternProblem(pattern) {
|
|
2145
1654
|
switch((0,_rule_engine_rule_regex_js__rspack_import_5/* .rulePatternProblem */._V)(pattern)){
|
|
2146
1655
|
case 'too_long':
|
|
2147
|
-
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1656
|
+
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.REGEX_TOO_LONG */.IP.REGEX_TOO_LONG, {
|
|
2148
1657
|
max: _rule_engine_index_js__rspack_import_2/* .RULE_ENGINE_LIMITS.MAX_REGEX_PATTERN_LENGTH */.bw.MAX_REGEX_PATTERN_LENGTH
|
|
2149
1658
|
});
|
|
2150
1659
|
case 'invalid':
|
|
2151
|
-
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1660
|
+
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.REGEX_INVALID */.IP.REGEX_INVALID);
|
|
2152
1661
|
case 'too_complex':
|
|
2153
|
-
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1662
|
+
return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.REGEX_TOO_COMPLEX */.IP.REGEX_TOO_COMPLEX, {
|
|
2154
1663
|
max: _rule_engine_index_js__rspack_import_2/* .RULE_ENGINE_LIMITS.MAX_REGEX_REPEAT */.bw.MAX_REGEX_REPEAT
|
|
2155
1664
|
});
|
|
2156
1665
|
default:
|
|
@@ -2158,20 +1667,20 @@ function patternProblem(pattern) {
|
|
|
2158
1667
|
}
|
|
2159
1668
|
}
|
|
2160
1669
|
function lookupProblem(value, depth, options) {
|
|
2161
|
-
if (typeof value.entity !== 'string' || !
|
|
2162
|
-
if (options.knownEntityCodes && !options.knownEntityCodes.has(value.entity)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1670
|
+
if (typeof value.entity !== 'string' || !_config_entity_builder_constants_js__rspack_import_8/* .ENTITY_CODE_PATTERN.test */.vs.test(value.entity)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.LOOKUP_ENTITY_INVALID */.IP.LOOKUP_ENTITY_INVALID);
|
|
1671
|
+
if (options.knownEntityCodes && !options.knownEntityCodes.has(value.entity)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.LOOKUP_ENTITY_UNKNOWN */.IP.LOOKUP_ENTITY_UNKNOWN, {
|
|
2163
1672
|
entity: value.entity
|
|
2164
1673
|
});
|
|
2165
1674
|
if (![
|
|
2166
1675
|
'exists',
|
|
2167
1676
|
'count',
|
|
2168
1677
|
'first'
|
|
2169
|
-
].includes(value.mode)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2170
|
-
if (value.field !== undefined && (typeof value.field !== 'string' || !COLUMN_CODE.test(value.field))) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2171
|
-
if (value.sort !== undefined && (typeof value.sort?.field !== 'string' || !COLUMN_CODE.test(value.sort.field))) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2172
|
-
if (!value.filter || typeof value.filter !== 'object' || Array.isArray(value.filter)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1678
|
+
].includes(value.mode)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.LOOKUP_MODE_INVALID */.IP.LOOKUP_MODE_INVALID);
|
|
1679
|
+
if (value.field !== undefined && (typeof value.field !== 'string' || !COLUMN_CODE.test(value.field))) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.LOOKUP_FIELD_INVALID */.IP.LOOKUP_FIELD_INVALID);
|
|
1680
|
+
if (value.sort !== undefined && (typeof value.sort?.field !== 'string' || !COLUMN_CODE.test(value.sort.field))) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.LOOKUP_FIELD_INVALID */.IP.LOOKUP_FIELD_INVALID);
|
|
1681
|
+
if (!value.filter || typeof value.filter !== 'object' || Array.isArray(value.filter)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.LOOKUP_FILTER_INVALID */.IP.LOOKUP_FILTER_INVALID);
|
|
2173
1682
|
for (const [key, item] of Object.entries(value.filter)){
|
|
2174
|
-
if (!COLUMN_CODE.test(key)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1683
|
+
if (!COLUMN_CODE.test(key)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.LOOKUP_FILTER_INVALID */.IP.LOOKUP_FILTER_INVALID);
|
|
2175
1684
|
const problem = filterValueProblem(item, depth, options);
|
|
2176
1685
|
if (problem) return problem;
|
|
2177
1686
|
}
|
|
@@ -2180,13 +1689,13 @@ function lookupProblem(value, depth, options) {
|
|
|
2180
1689
|
/** A filter entry: an expression (eq) or `{ op, value? }` with an expression value. */ function filterValueProblem(item, depth, options) {
|
|
2181
1690
|
if (!(0,_interfaces_generic_record_interface_js__rspack_import_1/* .isRecordFilterCondition */.t1)(item)) {
|
|
2182
1691
|
const op = item && typeof item === 'object' && !Array.isArray(item) && !('type' in item) ? item.op : undefined;
|
|
2183
|
-
if (typeof op === 'string' && !_interfaces_generic_record_interface_js__rspack_import_1/* .RECORD_FILTER_OPS.includes */.ox.includes(op)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1692
|
+
if (typeof op === 'string' && !_interfaces_generic_record_interface_js__rspack_import_1/* .RECORD_FILTER_OPS.includes */.ox.includes(op)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.FILTER_OPERATOR_UNKNOWN */.IP.FILTER_OPERATOR_UNKNOWN, {
|
|
2184
1693
|
op
|
|
2185
1694
|
});
|
|
2186
1695
|
return expressionProblem(item, depth + 1, options);
|
|
2187
1696
|
}
|
|
2188
1697
|
if (item.op === 'is_null' || item.op === 'not_null') return null;
|
|
2189
|
-
if (item.value === undefined) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1698
|
+
if (item.value === undefined) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.FILTER_VALUE_REQUIRED */.IP.FILTER_VALUE_REQUIRED, {
|
|
2190
1699
|
op: item.op
|
|
2191
1700
|
});
|
|
2192
1701
|
return expressionProblem(item.value, depth + 1, options);
|
|
@@ -2200,8 +1709,8 @@ function firstProblem(items, depth, options) {
|
|
|
2200
1709
|
}
|
|
2201
1710
|
function conditionProblem(node, options) {
|
|
2202
1711
|
const hasLeft = node?.left !== undefined;
|
|
2203
|
-
if (!node || !hasLeft && (typeof node.field !== 'string' || !node.field) || typeof node.comparison !== 'string') return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2204
|
-
if (!_rule_engine_index_js__rspack_import_2/* .RULE_COMPARISON_OPERATORS.includes */.dJ.includes(node.comparison)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1712
|
+
if (!node || !hasLeft && (typeof node.field !== 'string' || !node.field) || typeof node.comparison !== 'string') return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.CONDITION_INCOMPLETE */.IP.CONDITION_INCOMPLETE);
|
|
1713
|
+
if (!_rule_engine_index_js__rspack_import_2/* .RULE_COMPARISON_OPERATORS.includes */.dJ.includes(node.comparison)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.UNKNOWN_COMPARISON */.IP.UNKNOWN_COMPARISON, {
|
|
2205
1714
|
comparison: node.comparison
|
|
2206
1715
|
});
|
|
2207
1716
|
if (hasLeft) {
|
|
@@ -2217,15 +1726,15 @@ function conditionProblem(node, options) {
|
|
|
2217
1726
|
return null;
|
|
2218
1727
|
}
|
|
2219
1728
|
/** Rule group shape check with the engine's limits (no evaluation). */ function groupProblem(group, depth = 0, options = {}) {
|
|
2220
|
-
if (!group || typeof group !== 'object' || !Array.isArray(group.conditions)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1729
|
+
if (!group || typeof group !== 'object' || !Array.isArray(group.conditions)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.NOT_A_RULE */.IP.NOT_A_RULE);
|
|
2221
1730
|
const g = group;
|
|
2222
|
-
if (depth > _rule_engine_index_js__rspack_import_2/* .RULE_ENGINE_LIMITS.MAX_GROUP_DEPTH */.bw.MAX_GROUP_DEPTH) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2223
|
-
if (g.conditions.length > _rule_engine_index_js__rspack_import_2/* .RULE_ENGINE_LIMITS.MAX_CONDITIONS_PER_GROUP */.bw.MAX_CONDITIONS_PER_GROUP) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1731
|
+
if (depth > _rule_engine_index_js__rspack_import_2/* .RULE_ENGINE_LIMITS.MAX_GROUP_DEPTH */.bw.MAX_GROUP_DEPTH) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.TOO_DEEP */.IP.TOO_DEEP);
|
|
1732
|
+
if (g.conditions.length > _rule_engine_index_js__rspack_import_2/* .RULE_ENGINE_LIMITS.MAX_CONDITIONS_PER_GROUP */.bw.MAX_CONDITIONS_PER_GROUP) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.TOO_MANY_CONDITIONS */.IP.TOO_MANY_CONDITIONS);
|
|
2224
1733
|
if (![
|
|
2225
1734
|
'AND',
|
|
2226
1735
|
'OR',
|
|
2227
1736
|
'NOT'
|
|
2228
|
-
].includes(g.operator)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1737
|
+
].includes(g.operator)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SHAPE_MESSAGES.UNKNOWN_OPERATOR */.IP.UNKNOWN_OPERATOR);
|
|
2229
1738
|
for (const node of g.conditions){
|
|
2230
1739
|
const problem = node && (0,_rule_engine_index_js__rspack_import_2/* .isRuleGroup */.GD)(node) ? groupProblem(node, depth + 1, options) : conditionProblem(node, options);
|
|
2231
1740
|
if (problem) return problem;
|
|
@@ -2241,14 +1750,24 @@ function conditionProblem(node, options) {
|
|
|
2241
1750
|
const errors = [];
|
|
2242
1751
|
const warnings = [];
|
|
2243
1752
|
const err = (message)=>errors.push(message);
|
|
2244
|
-
if (!_flow_types_js__rspack_import_6/* .FLOW_SLUG_PATTERN.test */.YD.test(flow.slug ?? '')) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1753
|
+
if (!_flow_types_js__rspack_import_6/* .FLOW_SLUG_PATTERN.test */.YD.test(flow.slug ?? '')) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.SLUG_INVALID */.qj.SLUG_INVALID));
|
|
1754
|
+
if (!_flow_types_js__rspack_import_6/* .FLOW_RUN_AS.includes */.gl.includes(flow.runAs)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.RUN_AS_INVALID */.qj.RUN_AS_INVALID, {
|
|
1755
|
+
runAs: String(flow.runAs)
|
|
1756
|
+
}));
|
|
1757
|
+
if (!_flow_types_js__rspack_import_6/* .FLOW_AUTH_MODES.includes */.fO.includes(flow.authMode)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.AUTH_MODE_INVALID */.qj.AUTH_MODE_INVALID, {
|
|
1758
|
+
authMode: String(flow.authMode)
|
|
1759
|
+
}));
|
|
1760
|
+
if (flow.runAs === 'caller' && flow.authMode !== 'jwt' && flow.authMode !== 'permission' && flow.authMode !== 'internal') {
|
|
1761
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.RUN_AS_CALLER_NEEDS_AUTH */.qj.RUN_AS_CALLER_NEEDS_AUTH));
|
|
1762
|
+
}
|
|
1763
|
+
validateInputSchema(flow, err);
|
|
2245
1764
|
const nodes = Array.isArray(flow.nodes) ? flow.nodes : [];
|
|
2246
1765
|
const edges = Array.isArray(flow.edges) ? flow.edges : [];
|
|
2247
|
-
if (!nodes.length) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2248
|
-
if (nodes.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_NODES */.Or.MAX_NODES) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1766
|
+
if (!nodes.length) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NO_NODES */.qj.NO_NODES));
|
|
1767
|
+
if (nodes.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_NODES */.Or.MAX_NODES) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.TOO_MANY_NODES */.qj.TOO_MANY_NODES, {
|
|
2249
1768
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_NODES */.Or.MAX_NODES
|
|
2250
1769
|
}));
|
|
2251
|
-
if (edges.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_EDGES */.Or.MAX_EDGES) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1770
|
+
if (edges.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_EDGES */.Or.MAX_EDGES) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.TOO_MANY_EDGES */.qj.TOO_MANY_EDGES, {
|
|
2252
1771
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_EDGES */.Or.MAX_EDGES
|
|
2253
1772
|
}));
|
|
2254
1773
|
if (errors.length && (!nodes.length || nodes.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_NODES */.Or.MAX_NODES || edges.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_EDGES */.Or.MAX_EDGES)) return {
|
|
@@ -2258,16 +1777,16 @@ function conditionProblem(node, options) {
|
|
|
2258
1777
|
const byId = new Map();
|
|
2259
1778
|
for (const node of nodes){
|
|
2260
1779
|
if (!_flow_types_js__rspack_import_6/* .FLOW_NODE_ID_PATTERN.test */.z6.test(node?.id ?? '')) {
|
|
2261
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1780
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_ID_INVALID */.qj.NODE_ID_INVALID, {
|
|
2262
1781
|
id: node?.id
|
|
2263
1782
|
}));
|
|
2264
1783
|
continue;
|
|
2265
1784
|
}
|
|
2266
|
-
if (byId.has(node.id)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1785
|
+
if (byId.has(node.id)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_ID_DUPLICATE */.qj.NODE_ID_DUPLICATE, {
|
|
2267
1786
|
id: node.id
|
|
2268
1787
|
}));
|
|
2269
1788
|
byId.set(node.id, node);
|
|
2270
|
-
if (!_flow_types_js__rspack_import_6/* .FLOW_NODE_TYPES.includes */.q2.includes(node.type)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1789
|
+
if (!_flow_types_js__rspack_import_6/* .FLOW_NODE_TYPES.includes */.q2.includes(node.type)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_TYPE_UNKNOWN */.qj.NODE_TYPE_UNKNOWN, {
|
|
2271
1790
|
id: node.id,
|
|
2272
1791
|
type: node.type
|
|
2273
1792
|
}));
|
|
@@ -2280,24 +1799,24 @@ function conditionProblem(node, options) {
|
|
|
2280
1799
|
const outgoing = new Map();
|
|
2281
1800
|
const edgeIds = new Set();
|
|
2282
1801
|
for (const edge of edges){
|
|
2283
|
-
if (edgeIds.has(edge.id)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1802
|
+
if (edgeIds.has(edge.id)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.EDGE_ID_DUPLICATE */.qj.EDGE_ID_DUPLICATE, {
|
|
2284
1803
|
id: edge.id
|
|
2285
1804
|
}));
|
|
2286
1805
|
edgeIds.add(edge.id);
|
|
2287
1806
|
const from = byId.get(edge.from);
|
|
2288
1807
|
const to = byId.get(edge.to);
|
|
2289
1808
|
if (!from || !to) {
|
|
2290
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1809
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.EDGE_DANGLING */.qj.EDGE_DANGLING, {
|
|
2291
1810
|
from: edge.from,
|
|
2292
1811
|
to: edge.to
|
|
2293
1812
|
}));
|
|
2294
1813
|
continue;
|
|
2295
1814
|
}
|
|
2296
|
-
if (edge.from === edge.to) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1815
|
+
if (edge.from === edge.to) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.EDGE_SELF */.qj.EDGE_SELF, {
|
|
2297
1816
|
id: edge.from
|
|
2298
1817
|
}));
|
|
2299
|
-
if (to.type === 'trigger') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2300
|
-
if (!(0,_flow_types_js__rspack_import_6/* .portsOf */.a5)(from).includes(edge.port)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1818
|
+
if (to.type === 'trigger') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.EDGE_INTO_TRIGGER */.qj.EDGE_INTO_TRIGGER));
|
|
1819
|
+
if (!(0,_flow_types_js__rspack_import_6/* .portsOf */.a5)(from).includes(edge.port)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.EDGE_NO_PORT */.qj.EDGE_NO_PORT, {
|
|
2301
1820
|
id: from.id,
|
|
2302
1821
|
port: edge.port
|
|
2303
1822
|
}));
|
|
@@ -2313,195 +1832,111 @@ function conditionProblem(node, options) {
|
|
|
2313
1832
|
const seenPairs = new Set();
|
|
2314
1833
|
for (const edge of edges){
|
|
2315
1834
|
const key = `${edge.from}|${edge.port}|${edge.to}`;
|
|
2316
|
-
if (seenPairs.has(key)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1835
|
+
if (seenPairs.has(key)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.EDGE_TWICE */.qj.EDGE_TWICE, {
|
|
2317
1836
|
from: edge.from,
|
|
2318
1837
|
to: edge.to
|
|
2319
1838
|
}));
|
|
2320
1839
|
seenPairs.add(key);
|
|
2321
1840
|
}
|
|
2322
1841
|
const cyclic = hasCycle(nodes, outgoing);
|
|
2323
|
-
if (cyclic) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1842
|
+
if (cyclic) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.CYCLE */.qj.CYCLE));
|
|
2324
1843
|
const reachable = triggers.length ? new Set(triggers.flatMap((trigger)=>[
|
|
2325
1844
|
...reach(trigger.id, outgoing)
|
|
2326
1845
|
])) : null;
|
|
2327
1846
|
for (const node of nodes){
|
|
2328
|
-
if (reachable && !reachable.has(node.id)) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1847
|
+
if (reachable && !reachable.has(node.id)) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_UNREACHABLE */.qj.NODE_UNREACHABLE, {
|
|
2329
1848
|
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(node)
|
|
2330
1849
|
}));
|
|
2331
1850
|
}
|
|
2332
1851
|
checkNodeReferences(nodes, byId, flow, err, warnings);
|
|
2333
1852
|
if (!cyclic && reachable) checkReferenceTiming(nodes, edges, byId, reachable, warnings);
|
|
2334
1853
|
if (!cyclic) checkLoopDepth(nodes, outgoing, err);
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
}));
|
|
2346
|
-
checkEndpointRuns(runs, warnings);
|
|
2347
|
-
checkTransactionUse(flow, runs, outgoing, context, warnings);
|
|
1854
|
+
if (flow.isTransactional && nodes.some((n)=>n.type === 'http_request')) {
|
|
1855
|
+
warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.TRANSACTIONAL_HTTP */.qj.TRANSACTIONAL_HTTP));
|
|
1856
|
+
}
|
|
1857
|
+
checkTransactionUse(flow, nodes, outgoing, reachable, context, warnings);
|
|
1858
|
+
if (flow.runAs === 'system' && flow.authMode === 'public' && nodes.some((n)=>n.type.startsWith('entity_') || collectLookupEntities(n.config).size > 0)) {
|
|
1859
|
+
warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.PUBLIC_SYSTEM_ENTITY */.qj.PUBLIC_SYSTEM_ENTITY));
|
|
1860
|
+
}
|
|
1861
|
+
if ((flow.authMode === 'public' || flow.authMode === 'api_key') && nodes.some((n)=>n.type === 'permission_check' || usesPermissionFunction(n.config))) {
|
|
1862
|
+
warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.PERMISSION_WITHOUT_USER */.qj.PERMISSION_WITHOUT_USER));
|
|
1863
|
+
}
|
|
2348
1864
|
return {
|
|
2349
1865
|
errors,
|
|
2350
1866
|
warnings
|
|
2351
1867
|
};
|
|
2352
1868
|
}
|
|
2353
|
-
const touchesEntities = (node)=>node.type.startsWith('entity_') || collectLookupEntities(node.config).size > 0;
|
|
2354
|
-
/** What depends on a Request step's access, run-as and transaction, for the steps its runs reach. A finding shared by several Request steps is reported once. */ function checkEndpointRuns(runs, warnings) {
|
|
2355
|
-
const reported = new Set();
|
|
2356
|
-
const warnOnce = (message)=>{
|
|
2357
|
-
const key = JSON.stringify(message);
|
|
2358
|
-
if (reported.has(key)) return;
|
|
2359
|
-
reported.add(key);
|
|
2360
|
-
warnings.push(message);
|
|
2361
|
-
};
|
|
2362
|
-
const keylessAsCaller = [];
|
|
2363
|
-
for (const { endpoint, label, steps } of runs){
|
|
2364
|
-
if (endpoint.isTransactional) {
|
|
2365
|
-
if (steps.some((n)=>n.type === 'http_request')) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRANSACTIONAL_HTTP */.qj.TRANSACTIONAL_HTTP, {
|
|
2366
|
-
node: label
|
|
2367
|
-
}));
|
|
2368
|
-
// Inside the run's transaction a message is only sent once it commits: a failed send is logged, it cannot take the error path.
|
|
2369
|
-
for (const n of steps)if ((0,_flow_types_js__rspack_import_6/* .isMessageNode */.SE)(n.type) && n.onError === 'continue') warnOnce((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.MESSAGE_AFTER_COMMIT */.qj.MESSAGE_AFTER_COMMIT, {
|
|
2370
|
-
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(n)
|
|
2371
|
-
}));
|
|
2372
|
-
}
|
|
2373
|
-
if (endpoint.authMode === 'public' && endpoint.runAs === 'system' && steps.some(touchesEntities)) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.PUBLIC_SYSTEM_ENTITY */.qj.PUBLIC_SYSTEM_ENTITY, {
|
|
2374
|
-
node: label
|
|
2375
|
-
}));
|
|
2376
|
-
if (endpoint.authMode === 'public' && steps.some((n)=>(0,_flow_types_js__rspack_import_6/* .isMessageNode */.SE)(n.type))) warnOnce((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.PUBLIC_MESSAGE */.qj.PUBLIC_MESSAGE));
|
|
2377
|
-
// A URL callers reach without signing in has no user: checks deny them, and a run as the caller can touch no entity and notify no company.
|
|
2378
|
-
if (!_flow_types_js__rspack_import_6/* .KEYLESS_AUTH_MODES.has */.d7.has(endpoint.authMode)) continue;
|
|
2379
|
-
if (steps.some((n)=>n.type === 'permission_check' || n.type === 'company_branch_check' || usesPermissionFunction(n.config))) warnOnce((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.PERMISSION_WITHOUT_USER */.qj.PERMISSION_WITHOUT_USER));
|
|
2380
|
-
if (endpoint.runAs !== 'caller') continue;
|
|
2381
|
-
for (const n of steps)if (n.type === 'send_notification' && n.config?.['target'] === 'company') warnOnce((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.COMPANY_NOTIFICATION_WITHOUT_USER */.qj.COMPANY_NOTIFICATION_WITHOUT_USER, {
|
|
2382
|
-
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(n)
|
|
2383
|
-
}));
|
|
2384
|
-
if (steps.some(touchesEntities)) keylessAsCaller.push(endpoint.path ? `/${endpoint.path}` : '/');
|
|
2385
|
-
}
|
|
2386
|
-
if (keylessAsCaller.length) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.KEYLESS_ENDPOINT_AS_CALLER */.qj.KEYLESS_ENDPOINT_AS_CALLER, {
|
|
2387
|
-
endpoints: keylessAsCaller.join(', ')
|
|
2388
|
-
}));
|
|
2389
|
-
}
|
|
2390
|
-
/** The Request steps whose runs reach `nodeId`. */ function endpointsReaching(flow, nodeId) {
|
|
2391
|
-
const outgoing = new Map();
|
|
2392
|
-
for (const edge of Array.isArray(flow.edges) ? flow.edges : [])outgoing.set(edge.from, [
|
|
2393
|
-
...outgoing.get(edge.from) ?? [],
|
|
2394
|
-
{
|
|
2395
|
-
to: edge.to
|
|
2396
|
-
}
|
|
2397
|
-
]);
|
|
2398
|
-
return (0,_flow_types_js__rspack_import_6/* .flowEndpoints */.Xr)(flow).filter((endpoint)=>reach(endpoint.nodeId, outgoing).has(nodeId));
|
|
2399
|
-
}
|
|
2400
1869
|
/** At least one Request step; at most one on the flow's own URL, the others on distinct paths. */ function checkTriggers(triggers, err) {
|
|
2401
|
-
if (!triggers.length) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1870
|
+
if (!triggers.length) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.TRIGGER_MISSING */.qj.TRIGGER_MISSING));
|
|
2402
1871
|
const main = triggers.filter((trigger)=>!(0,_flow_types_js__rspack_import_6/* .triggerPath */.um)(trigger));
|
|
2403
|
-
if (main.length > 1) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1872
|
+
if (main.length > 1) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.TRIGGER_MAIN_DUPLICATE */.qj.TRIGGER_MAIN_DUPLICATE, {
|
|
2404
1873
|
count: main.length
|
|
2405
1874
|
}));
|
|
2406
1875
|
const paths = new Set();
|
|
2407
1876
|
for (const trigger of triggers){
|
|
2408
1877
|
const path = (0,_flow_types_js__rspack_import_6/* .triggerPath */.um)(trigger);
|
|
2409
1878
|
if (!path) continue;
|
|
2410
|
-
if (paths.has(path)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1879
|
+
if (paths.has(path)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.TRIGGER_PATH_DUPLICATE */.qj.TRIGGER_PATH_DUPLICATE, {
|
|
2411
1880
|
path
|
|
2412
1881
|
}));
|
|
2413
1882
|
paths.add(path);
|
|
2414
1883
|
}
|
|
2415
1884
|
}
|
|
2416
1885
|
/**
|
|
2417
|
-
* What the runtime would always refuse, caught on save: an API-key
|
|
2418
|
-
* caller, a required input left out, a chain that comes back to this flow or nests deeper
|
|
1886
|
+
* What the runtime would always refuse, caught on save: an API-key flow called by a flow running
|
|
1887
|
+
* as the caller, a required input left out, a chain that comes back to this flow or nests deeper
|
|
2419
1888
|
* than the limit. An inactive flow and an input the called flow does not declare are warnings.
|
|
2420
|
-
*/ function checkCalledFlow(
|
|
2421
|
-
const { flowSlug: slug, endpoint, input, inputList } = node.config;
|
|
2422
|
-
const at = {
|
|
2423
|
-
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(node)
|
|
2424
|
-
};
|
|
1889
|
+
*/ function checkCalledFlow(slug, endpoint, input, inputList, flow, known, at, err, warn) {
|
|
2425
1890
|
const target = known.get(slug);
|
|
2426
1891
|
const vars = {
|
|
2427
1892
|
...at,
|
|
2428
1893
|
flow: slug
|
|
2429
1894
|
};
|
|
2430
|
-
if (!target.isActive) warn.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1895
|
+
if (!target.isActive) warn.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INACTIVE */.qj.NODE_FLOW_INACTIVE, vars));
|
|
1896
|
+
if (target.authMode === 'api_key') {
|
|
1897
|
+
// A function runs as whoever calls it, so it fails only when a flow running as the caller does.
|
|
1898
|
+
if (flow.authMode === 'internal') warn.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_API_KEY */.qj.NODE_FLOW_API_KEY, vars));
|
|
1899
|
+
else if (flow.runAs === 'caller') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_API_KEY */.qj.NODE_FLOW_API_KEY, vars));
|
|
1900
|
+
}
|
|
2431
1901
|
const path = typeof endpoint === 'string' && endpoint ? endpoint : null;
|
|
2432
1902
|
const entry = target.endpoints.find((e)=>e.path === path);
|
|
2433
|
-
if (entry?.authMode === 'api_key') {
|
|
2434
|
-
// A Request step for other flows runs as whoever calls it, so it fails only when a run as the caller reaches it.
|
|
2435
|
-
const starts = endpointsReaching(flow, node.id);
|
|
2436
|
-
if (starts.some((e)=>e.authMode !== 'internal' && e.runAs === 'caller')) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_API_KEY */.qj.NODE_FLOW_API_KEY, vars));
|
|
2437
|
-
else if (starts.some((e)=>e.authMode === 'internal')) warn.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_API_KEY */.qj.NODE_FLOW_API_KEY, vars));
|
|
2438
|
-
}
|
|
2439
1903
|
if (!entry) {
|
|
2440
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(path ?
|
|
1904
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(path ? _config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_ENDPOINT_UNKNOWN */.qj.NODE_FLOW_ENDPOINT_UNKNOWN : _config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_ENDPOINT_REQUIRED */.qj.NODE_FLOW_ENDPOINT_REQUIRED, {
|
|
2441
1905
|
...vars,
|
|
2442
1906
|
endpoint: path ?? ''
|
|
2443
1907
|
}));
|
|
2444
1908
|
} else if (entry.bodyType === 'list') {
|
|
2445
|
-
if (inputList === undefined) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1909
|
+
if (inputList === undefined) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INPUT_LIST_REQUIRED */.qj.NODE_FLOW_INPUT_LIST_REQUIRED, vars));
|
|
2446
1910
|
} else if (inputList !== undefined) {
|
|
2447
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1911
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INPUT_LIST_UNEXPECTED */.qj.NODE_FLOW_INPUT_LIST_UNEXPECTED, vars));
|
|
2448
1912
|
} else {
|
|
2449
1913
|
checkCalledInputs(input, entry.inputSchema, vars, err, warn);
|
|
2450
1914
|
}
|
|
2451
1915
|
const loop = callPathTo(slug, flow.slug, known, new Set());
|
|
2452
|
-
if (loop) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1916
|
+
if (loop) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_LOOP */.qj.NODE_FLOW_LOOP, {
|
|
2453
1917
|
...at,
|
|
2454
1918
|
chain: [
|
|
2455
1919
|
flow.slug,
|
|
2456
1920
|
...loop
|
|
2457
1921
|
].join(' > ')
|
|
2458
1922
|
}));
|
|
2459
|
-
if (1 + callDepth(slug, known, new Set()) > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CALL_DEPTH */.Or.MAX_CALL_DEPTH) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1923
|
+
if (1 + callDepth(slug, known, new Set()) > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CALL_DEPTH */.Or.MAX_CALL_DEPTH) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_TOO_DEEP */.qj.NODE_FLOW_TOO_DEEP, {
|
|
2460
1924
|
...at,
|
|
2461
1925
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CALL_DEPTH */.Or.MAX_CALL_DEPTH
|
|
2462
1926
|
}));
|
|
2463
1927
|
}
|
|
2464
|
-
/**
|
|
2465
|
-
* What the Call flow steps of `caller` whose call chain reaches `slug` (that flow itself, or one
|
|
2466
|
-
* that calls it, however deep) would hit against the flows in `known`: the save errors of those
|
|
2467
|
-
* steps, and the flow they run being off (a warning on save, a failure at run).
|
|
2468
|
-
*/ function callProblems(caller, slug, known) {
|
|
2469
|
-
const problems = [];
|
|
2470
|
-
for (const node of Array.isArray(caller.nodes) ? caller.nodes : []){
|
|
2471
|
-
const c = node?.config ?? {};
|
|
2472
|
-
if (node?.type !== 'call_flow' || typeof c.flowSlug !== 'string') continue;
|
|
2473
|
-
if (c.flowSlug !== slug && !callPathTo(c.flowSlug, slug, known, new Set())) continue;
|
|
2474
|
-
const at = {
|
|
2475
|
-
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(node)
|
|
2476
|
-
};
|
|
2477
|
-
const target = known.get(c.flowSlug);
|
|
2478
|
-
if (!target) {
|
|
2479
|
-
problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_UNKNOWN */.qj.NODE_FLOW_UNKNOWN, {
|
|
2480
|
-
...at,
|
|
2481
|
-
flow: c.flowSlug
|
|
2482
|
-
}));
|
|
2483
|
-
continue;
|
|
2484
|
-
}
|
|
2485
|
-
if (!target.isActive) problems.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INACTIVE */.qj.NODE_FLOW_INACTIVE, {
|
|
2486
|
-
...at,
|
|
2487
|
-
flow: c.flowSlug
|
|
2488
|
-
}));
|
|
2489
|
-
checkCalledFlow(node, caller, known, (m)=>problems.push(m), []);
|
|
2490
|
-
}
|
|
2491
|
-
return problems;
|
|
2492
|
-
}
|
|
2493
1928
|
/** The named inputs sent to a flow whose body is an object: every required one given, the rest declared. */ function checkCalledInputs(input, schema, vars, err, warn) {
|
|
2494
1929
|
const given = input && typeof input === 'object' && !Array.isArray(input) ? Object.keys(input) : [];
|
|
2495
1930
|
if (schema.length) {
|
|
2496
1931
|
const declared = new Set(schema.map((field)=>field.name));
|
|
2497
|
-
for (const name of given)if (!declared.has(name)) warn.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1932
|
+
for (const name of given)if (!declared.has(name)) warn.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INPUT_UNDECLARED */.qj.NODE_FLOW_INPUT_UNDECLARED, {
|
|
2498
1933
|
...vars,
|
|
2499
1934
|
input: name
|
|
2500
1935
|
}));
|
|
2501
1936
|
}
|
|
2502
1937
|
for (const field of schema){
|
|
2503
1938
|
if (field.required && (field.default === undefined || field.default === null) && !given.includes(field.name)) {
|
|
2504
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1939
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INPUT_MISSING */.qj.NODE_FLOW_INPUT_MISSING, {
|
|
2505
1940
|
...vars,
|
|
2506
1941
|
input: field.name
|
|
2507
1942
|
}));
|
|
@@ -2531,36 +1966,42 @@ const touchesEntities = (node)=>node.type.startsWith('entity_') || collectLookup
|
|
|
2531
1966
|
running.delete(slug);
|
|
2532
1967
|
return deepest;
|
|
2533
1968
|
}
|
|
1969
|
+
function validateInputSchema(flow, err) {
|
|
1970
|
+
if (flow.bodyType !== undefined && !_flow_types_js__rspack_import_6/* .FLOW_BODY_TYPES.includes */.Y3.includes(flow.bodyType)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.BODY_TYPE_UNKNOWN */.qj.BODY_TYPE_UNKNOWN, {
|
|
1971
|
+
type: String(flow.bodyType)
|
|
1972
|
+
}));
|
|
1973
|
+
validateInputFields(flow.inputSchema ?? [], '', 1, err);
|
|
1974
|
+
}
|
|
2534
1975
|
/** One level of the request body: the top-level fields, or the fields of an object / list item at `prefix`. */ function validateInputFields(fields, prefix, depth, err) {
|
|
2535
|
-
if (fields.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_INPUT_FIELDS */.Or.MAX_INPUT_FIELDS) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1976
|
+
if (fields.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_INPUT_FIELDS */.Or.MAX_INPUT_FIELDS) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.INPUT_TOO_MANY */.qj.INPUT_TOO_MANY, {
|
|
2536
1977
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_INPUT_FIELDS */.Or.MAX_INPUT_FIELDS
|
|
2537
1978
|
}));
|
|
2538
1979
|
const seen = new Set();
|
|
2539
1980
|
for (const field of fields){
|
|
2540
1981
|
const name = `${prefix}${field?.name ?? ''}`;
|
|
2541
|
-
if (!_flow_types_js__rspack_import_6/* .FLOW_INPUT_NAME_PATTERN.test */.fZ.test(field?.name ?? '')) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1982
|
+
if (!_flow_types_js__rspack_import_6/* .FLOW_INPUT_NAME_PATTERN.test */.fZ.test(field?.name ?? '')) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.INPUT_NAME_INVALID */.qj.INPUT_NAME_INVALID, {
|
|
2542
1983
|
name
|
|
2543
1984
|
}));
|
|
2544
|
-
else if (seen.has(field.name)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1985
|
+
else if (seen.has(field.name)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.INPUT_NAME_DUPLICATE */.qj.INPUT_NAME_DUPLICATE, {
|
|
2545
1986
|
name
|
|
2546
1987
|
}));
|
|
2547
1988
|
seen.add(field?.name);
|
|
2548
|
-
if (!_flow_types_js__rspack_import_6/* .FLOW_INPUT_TYPES.includes */.Q7.includes(field?.type)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1989
|
+
if (!_flow_types_js__rspack_import_6/* .FLOW_INPUT_TYPES.includes */.Q7.includes(field?.type)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.INPUT_TYPE_UNKNOWN */.qj.INPUT_TYPE_UNKNOWN, {
|
|
2549
1990
|
name,
|
|
2550
1991
|
type: field?.type
|
|
2551
1992
|
}));
|
|
2552
1993
|
const itemType = field?.type === 'array' ? field.itemType : undefined;
|
|
2553
|
-
if (itemType !== undefined && (itemType === 'array' || !_flow_types_js__rspack_import_6/* .FLOW_INPUT_TYPES.includes */.Q7.includes(itemType))) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1994
|
+
if (itemType !== undefined && (itemType === 'array' || !_flow_types_js__rspack_import_6/* .FLOW_INPUT_TYPES.includes */.Q7.includes(itemType))) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.INPUT_ITEM_TYPE_UNKNOWN */.qj.INPUT_ITEM_TYPE_UNKNOWN, {
|
|
2554
1995
|
name,
|
|
2555
1996
|
type: itemType
|
|
2556
1997
|
}));
|
|
2557
|
-
if ((field?.type === 'choice' || itemType === 'choice') && !field.options?.length) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
1998
|
+
if ((field?.type === 'choice' || itemType === 'choice') && !field.options?.length) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.INPUT_CHOICE_NO_OPTIONS */.qj.INPUT_CHOICE_NO_OPTIONS, {
|
|
2558
1999
|
name
|
|
2559
2000
|
}));
|
|
2560
2001
|
const holdsFields = field?.type === 'object' || itemType === 'object';
|
|
2561
2002
|
if (!holdsFields || !Array.isArray(field.fields) || !field.fields.length) continue;
|
|
2562
2003
|
if (depth >= _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_INPUT_DEPTH */.Or.MAX_INPUT_DEPTH) {
|
|
2563
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2004
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.INPUT_TOO_DEEP */.qj.INPUT_TOO_DEEP, {
|
|
2564
2005
|
name,
|
|
2565
2006
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_INPUT_DEPTH */.Or.MAX_INPUT_DEPTH
|
|
2566
2007
|
}));
|
|
@@ -2579,7 +2020,7 @@ function validateNodeConfig(node, flow, context, err, warn) {
|
|
|
2579
2020
|
};
|
|
2580
2021
|
const expr = (value, what)=>{
|
|
2581
2022
|
const problem = expressionProblem(value, 0, shape);
|
|
2582
|
-
if (problem) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2023
|
+
if (problem) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_EXPRESSION_PROBLEM */.qj.NODE_EXPRESSION_PROBLEM, {
|
|
2583
2024
|
...at,
|
|
2584
2025
|
what,
|
|
2585
2026
|
problem
|
|
@@ -2587,7 +2028,7 @@ function validateNodeConfig(node, flow, context, err, warn) {
|
|
|
2587
2028
|
};
|
|
2588
2029
|
const exprMap = (value, kind)=>{
|
|
2589
2030
|
if (value === undefined) return;
|
|
2590
|
-
if (!value || typeof value !== 'object' || Array.isArray(value)) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2031
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_PAIRS_INVALID */.qj.NODE_PAIRS_INVALID, {
|
|
2591
2032
|
...at,
|
|
2592
2033
|
what: (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(kind.list)
|
|
2593
2034
|
}));
|
|
@@ -2597,13 +2038,13 @@ function validateNodeConfig(node, flow, context, err, warn) {
|
|
|
2597
2038
|
};
|
|
2598
2039
|
const filterMap = (value, kind)=>{
|
|
2599
2040
|
if (value === undefined) return;
|
|
2600
|
-
if (!value || typeof value !== 'object' || Array.isArray(value)) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2041
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_PAIRS_INVALID */.qj.NODE_PAIRS_INVALID, {
|
|
2601
2042
|
...at,
|
|
2602
2043
|
what: (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(kind.list)
|
|
2603
2044
|
}));
|
|
2604
2045
|
for (const [key, item] of Object.entries(value)){
|
|
2605
2046
|
const problem = filterValueProblem(item, -1, shape);
|
|
2606
|
-
if (problem) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2047
|
+
if (problem) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_EXPRESSION_PROBLEM */.qj.NODE_EXPRESSION_PROBLEM, {
|
|
2607
2048
|
...at,
|
|
2608
2049
|
what: (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(kind.item, {
|
|
2609
2050
|
name: key
|
|
@@ -2614,164 +2055,115 @@ function validateNodeConfig(node, flow, context, err, warn) {
|
|
|
2614
2055
|
};
|
|
2615
2056
|
const rule = (value, what)=>{
|
|
2616
2057
|
const problem = groupProblem(value, 0, shape);
|
|
2617
|
-
if (problem) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2058
|
+
if (problem) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_RULE_PROBLEM */.qj.NODE_RULE_PROBLEM, {
|
|
2618
2059
|
...at,
|
|
2619
2060
|
what,
|
|
2620
2061
|
problem
|
|
2621
2062
|
}));
|
|
2622
2063
|
};
|
|
2623
2064
|
const entity = (value)=>{
|
|
2624
|
-
if (typeof value !== 'string' || !
|
|
2625
|
-
if (context.knownEntityCodes && !context.knownEntityCodes.has(value)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2065
|
+
if (typeof value !== 'string' || !_config_entity_builder_constants_js__rspack_import_8/* .ENTITY_CODE_PATTERN.test */.vs.test(value)) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHOOSE_ENTITY */.qj.NODE_CHOOSE_ENTITY, at));
|
|
2066
|
+
if (context.knownEntityCodes && !context.knownEntityCodes.has(value)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_ENTITY_UNKNOWN */.qj.NODE_ENTITY_UNKNOWN, {
|
|
2626
2067
|
...at,
|
|
2627
2068
|
entity: value
|
|
2628
2069
|
}));
|
|
2629
2070
|
};
|
|
2630
2071
|
const KIND = {
|
|
2631
2072
|
variable: {
|
|
2632
|
-
list:
|
|
2633
|
-
item:
|
|
2073
|
+
list: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.VARIABLES */.bc.VARIABLES,
|
|
2074
|
+
item: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.VARIABLE */.bc.VARIABLE
|
|
2634
2075
|
},
|
|
2635
2076
|
field: {
|
|
2636
|
-
list:
|
|
2637
|
-
item:
|
|
2077
|
+
list: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.FIELDS */.bc.FIELDS,
|
|
2078
|
+
item: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.FIELD */.bc.FIELD
|
|
2638
2079
|
},
|
|
2639
2080
|
filter: {
|
|
2640
|
-
list:
|
|
2641
|
-
item:
|
|
2081
|
+
list: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.FILTERS */.bc.FILTERS,
|
|
2082
|
+
item: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.FILTER */.bc.FILTER
|
|
2642
2083
|
},
|
|
2643
2084
|
input: {
|
|
2644
|
-
list:
|
|
2645
|
-
item:
|
|
2085
|
+
list: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.INPUTS */.bc.INPUTS,
|
|
2086
|
+
item: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.INPUT */.bc.INPUT
|
|
2646
2087
|
},
|
|
2647
2088
|
header: {
|
|
2648
|
-
list:
|
|
2649
|
-
item:
|
|
2089
|
+
list: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.HEADERS */.bc.HEADERS,
|
|
2090
|
+
item: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.HEADER */.bc.HEADER
|
|
2650
2091
|
},
|
|
2651
2092
|
body: {
|
|
2652
|
-
list:
|
|
2653
|
-
item:
|
|
2093
|
+
list: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.BODY_VALUES */.bc.BODY_VALUES,
|
|
2094
|
+
item: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.BODY_VALUE */.bc.BODY_VALUE
|
|
2654
2095
|
},
|
|
2655
2096
|
payload: {
|
|
2656
|
-
list:
|
|
2657
|
-
item:
|
|
2097
|
+
list: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.PAYLOAD_VALUES */.bc.PAYLOAD_VALUES,
|
|
2098
|
+
item: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.PAYLOAD_VALUE */.bc.PAYLOAD_VALUE
|
|
2658
2099
|
},
|
|
2659
2100
|
response: {
|
|
2660
|
-
list:
|
|
2661
|
-
item:
|
|
2662
|
-
},
|
|
2663
|
-
data: {
|
|
2664
|
-
list: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.DATA_VALUES */.bc.DATA_VALUES,
|
|
2665
|
-
item: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.DATA_VALUE */.bc.DATA_VALUE
|
|
2666
|
-
},
|
|
2667
|
-
template: {
|
|
2668
|
-
list: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.TEMPLATE_VALUES */.bc.TEMPLATE_VALUES,
|
|
2669
|
-
item: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.TEMPLATE_VALUE */.bc.TEMPLATE_VALUE
|
|
2101
|
+
list: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.RESPONSE_VALUES */.bc.RESPONSE_VALUES,
|
|
2102
|
+
item: _config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.RESPONSE_VALUE */.bc.RESPONSE_VALUE
|
|
2670
2103
|
}
|
|
2671
2104
|
};
|
|
2672
|
-
const optionalExpr = (value, what)=>{
|
|
2673
|
-
if (value !== undefined) expr(value, what);
|
|
2674
|
-
};
|
|
2675
|
-
const serviceRunning = (service, unavailable)=>{
|
|
2676
|
-
if (context.messageServices && !context.messageServices[service]) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(unavailable, at));
|
|
2677
|
-
};
|
|
2678
2105
|
switch(node.type){
|
|
2679
2106
|
case 'trigger':
|
|
2680
2107
|
{
|
|
2681
|
-
if (c.path !== undefined && c.path !== '' && (typeof c.path !== 'string' || !_flow_types_js__rspack_import_6/* .FLOW_ENDPOINT_PATH_PATTERN.test */.YO.test(c.path))) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2682
|
-
if (c.authMode !== undefined && !_flow_types_js__rspack_import_6/* .FLOW_AUTH_MODES.includes */.fO.includes(c.authMode)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_AUTH_INVALID */.qj.TRIGGER_AUTH_INVALID, at));
|
|
2683
|
-
if (c.permissionCode !== undefined && (typeof c.permissionCode !== 'string' || c.permissionCode.length > 255)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_AUTH_INVALID */.qj.TRIGGER_AUTH_INVALID, at));
|
|
2684
|
-
if (c.runAs !== undefined && !_flow_types_js__rspack_import_6/* .FLOW_RUN_AS.includes */.gl.includes(c.runAs)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.RUN_AS_INVALID */.qj.RUN_AS_INVALID, {
|
|
2685
|
-
...at,
|
|
2686
|
-
runAs: String(c.runAs)
|
|
2687
|
-
}));
|
|
2688
|
-
if (c.isTransactional !== undefined && typeof c.isTransactional !== 'boolean') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_TRANSACTION_INVALID */.qj.TRIGGER_TRANSACTION_INVALID, at));
|
|
2689
|
-
if (c.timeoutMs !== undefined && !(Number.isInteger(c.timeoutMs) && c.timeoutMs >= _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MIN_TIMEOUT_MS */.Or.MIN_TIMEOUT_MS && c.timeoutMs <= _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_TIMEOUT_MS */.Or.MAX_TIMEOUT_MS)) {
|
|
2690
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_TIMEOUT_RANGE */.qj.TRIGGER_TIMEOUT_RANGE, {
|
|
2691
|
-
...at,
|
|
2692
|
-
min: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MIN_TIMEOUT_MS */.Or.MIN_TIMEOUT_MS / 1000,
|
|
2693
|
-
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_TIMEOUT_MS */.Or.MAX_TIMEOUT_MS / 1000
|
|
2694
|
-
}));
|
|
2695
|
-
}
|
|
2696
|
-
if (c.rateLimitPerMinute !== undefined && !(Number.isInteger(c.rateLimitPerMinute) && c.rateLimitPerMinute >= 0 && c.rateLimitPerMinute <= _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_RATE_LIMIT_PER_MINUTE */.Or.MAX_RATE_LIMIT_PER_MINUTE)) {
|
|
2697
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_RATE_LIMIT_RANGE */.qj.TRIGGER_RATE_LIMIT_RANGE, {
|
|
2698
|
-
...at,
|
|
2699
|
-
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_RATE_LIMIT_PER_MINUTE */.Or.MAX_RATE_LIMIT_PER_MINUTE
|
|
2700
|
-
}));
|
|
2701
|
-
}
|
|
2702
|
-
// Without a key an API-key URL could never be called; any other access keeps none.
|
|
2703
|
-
if (c.authMode === 'api_key' && c.apiKey === undefined) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_API_KEY_REQUIRED */.qj.TRIGGER_API_KEY_REQUIRED, at));
|
|
2704
|
-
else if (c.apiKey !== undefined && !(0,_flow_api_key_js__rspack_import_7/* .looksLikeApiKey */.Jb)(c.apiKey) && !(0,_flow_types_js__rspack_import_6/* .isStoredApiKey */.xA)(c.apiKey)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_API_KEY_INVALID */.qj.TRIGGER_API_KEY_INVALID, at));
|
|
2705
|
-
// Field errors are named after the URL (`<path>: <field>`) once a flow has several.
|
|
2108
|
+
if (c.path !== undefined && c.path !== '' && (typeof c.path !== 'string' || !_flow_types_js__rspack_import_6/* .FLOW_ENDPOINT_PATH_PATTERN.test */.YO.test(c.path))) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.TRIGGER_PATH_INVALID */.qj.TRIGGER_PATH_INVALID, at));
|
|
2706
2109
|
const path = (0,_flow_types_js__rspack_import_6/* .triggerPath */.um)(node);
|
|
2707
|
-
if (
|
|
2110
|
+
if (!path) break;
|
|
2111
|
+
if (c.bodyType !== undefined && !_flow_types_js__rspack_import_6/* .FLOW_BODY_TYPES.includes */.Y3.includes(c.bodyType)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.BODY_TYPE_UNKNOWN */.qj.BODY_TYPE_UNKNOWN, {
|
|
2708
2112
|
type: String(c.bodyType)
|
|
2709
2113
|
}));
|
|
2710
|
-
validateInputFields(Array.isArray(c.inputSchema) ? c.inputSchema : [],
|
|
2114
|
+
validateInputFields(Array.isArray(c.inputSchema) ? c.inputSchema : [], `${path}: `, 1, err);
|
|
2711
2115
|
break;
|
|
2712
2116
|
}
|
|
2713
2117
|
case 'validate':
|
|
2714
2118
|
validateChecks(c, at, rule, err);
|
|
2715
|
-
if (c.mode !== undefined && c.mode !== 'all' && c.mode !== 'first') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2119
|
+
if (c.mode !== undefined && c.mode !== 'all' && c.mode !== 'first') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_MODE_INVALID */.qj.NODE_MODE_INVALID, at));
|
|
2716
2120
|
if (c.statusCode !== undefined && !(Number.isInteger(c.statusCode) && c.statusCode >= 400 && c.statusCode <= 499)) {
|
|
2717
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2121
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_STATUS_4XX */.qj.NODE_STATUS_4XX, at));
|
|
2718
2122
|
}
|
|
2719
2123
|
break;
|
|
2720
2124
|
case 'permission_check':
|
|
2721
2125
|
{
|
|
2722
2126
|
try {
|
|
2723
|
-
if (!(0,_rule_engine_rule_permission_js__rspack_import_4/* .parsePermissionCodes */.PS)(c.codes).length) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2127
|
+
if (!(0,_rule_engine_rule_permission_js__rspack_import_4/* .parsePermissionCodes */.PS)(c.codes).length) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_PERMISSION_REQUIRED */.qj.NODE_PERMISSION_REQUIRED, at));
|
|
2724
2128
|
} catch {
|
|
2725
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2129
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .RULE_ENGINE_MESSAGES.TOO_MANY_PERMISSION_CODES */.x3.TOO_MANY_PERMISSION_CODES, {
|
|
2726
2130
|
max: _rule_engine_index_js__rspack_import_2/* .RULE_ENGINE_LIMITS.MAX_PERMISSION_CODES */.bw.MAX_PERMISSION_CODES
|
|
2727
2131
|
}));
|
|
2728
2132
|
}
|
|
2729
|
-
if (c.match !== undefined && c.match !== 'any' && c.match !== 'all') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2730
|
-
if (c.onDenied !== undefined && c.onDenied !== 'reject' && c.onDenied !== 'branch') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2731
|
-
if (c.
|
|
2133
|
+
if (c.match !== undefined && c.match !== 'any' && c.match !== 'all') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_PERMISSION_OPTION_INVALID */.qj.NODE_PERMISSION_OPTION_INVALID, at));
|
|
2134
|
+
if (c.onDenied !== undefined && c.onDenied !== 'reject' && c.onDenied !== 'branch') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_PERMISSION_OPTION_INVALID */.qj.NODE_PERMISSION_OPTION_INVALID, at));
|
|
2135
|
+
if (c.branch !== undefined && c.branch !== null) expr(c.branch, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_VALUE */.bc.THE_VALUE));
|
|
2136
|
+
if (c.message !== undefined && typeof c.message !== 'string') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_PERMISSION_OPTION_INVALID */.qj.NODE_PERMISSION_OPTION_INVALID, at));
|
|
2732
2137
|
if (c.statusCode !== undefined && !(Number.isInteger(c.statusCode) && c.statusCode >= 400 && c.statusCode <= 499)) {
|
|
2733
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2734
|
-
}
|
|
2735
|
-
break;
|
|
2736
|
-
}
|
|
2737
|
-
case 'company_branch_check':
|
|
2738
|
-
{
|
|
2739
|
-
if (c.companyIds !== undefined) expr(c.companyIds, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_VALUE */.bc.THE_VALUE));
|
|
2740
|
-
if (c.branchIds !== undefined) expr(c.branchIds, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_VALUE */.bc.THE_VALUE));
|
|
2741
|
-
if (c.onDenied !== undefined && c.onDenied !== 'reject' && c.onDenied !== 'branch') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_PERMISSION_OPTION_INVALID */.qj.NODE_PERMISSION_OPTION_INVALID, at));
|
|
2742
|
-
// Without an id to check there is nothing to allow or deny.
|
|
2743
|
-
if (c.onDenied === 'branch' && c.companyIds === undefined && c.branchIds === undefined) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_ACCESS_TARGET_REQUIRED */.qj.NODE_ACCESS_TARGET_REQUIRED, at));
|
|
2744
|
-
if (c.message !== undefined && typeof c.message !== 'string') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_PERMISSION_OPTION_INVALID */.qj.NODE_PERMISSION_OPTION_INVALID, at));
|
|
2745
|
-
if (c.statusCode !== undefined && !(Number.isInteger(c.statusCode) && c.statusCode >= 400 && c.statusCode <= 499)) {
|
|
2746
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_STATUS_4XX */.qj.NODE_STATUS_4XX, at));
|
|
2138
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_STATUS_4XX */.qj.NODE_STATUS_4XX, at));
|
|
2747
2139
|
}
|
|
2748
2140
|
break;
|
|
2749
2141
|
}
|
|
2750
2142
|
case 'set':
|
|
2751
2143
|
exprMap(c.values, KIND.variable);
|
|
2752
|
-
if (!c.values || !Object.keys(c.values).length) warn.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2144
|
+
if (!c.values || !Object.keys(c.values).length) warn.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_SETS_NOTHING */.qj.NODE_SETS_NOTHING, at));
|
|
2753
2145
|
for (const key of Object.keys(c.values ?? {})){
|
|
2754
|
-
if (!_flow_types_js__rspack_import_6/* .FLOW_INPUT_NAME_PATTERN.test */.fZ.test(key)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2146
|
+
if (!_flow_types_js__rspack_import_6/* .FLOW_INPUT_NAME_PATTERN.test */.fZ.test(key)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_VARIABLE_INVALID */.qj.NODE_VARIABLE_INVALID, {
|
|
2755
2147
|
...at,
|
|
2756
2148
|
name: key
|
|
2757
2149
|
}));
|
|
2758
2150
|
}
|
|
2759
2151
|
break;
|
|
2760
2152
|
case 'condition':
|
|
2761
|
-
rule(c.rule, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2153
|
+
rule(c.rule, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_RULE */.bc.THE_RULE));
|
|
2762
2154
|
break;
|
|
2763
2155
|
case 'switch':
|
|
2764
2156
|
{
|
|
2765
|
-
expr(c.value, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2157
|
+
expr(c.value, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_VALUE */.bc.THE_VALUE));
|
|
2766
2158
|
const cases = Array.isArray(c.cases) ? c.cases : [];
|
|
2767
|
-
if (!cases.length) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2159
|
+
if (!cases.length) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CASE_REQUIRED */.qj.NODE_CASE_REQUIRED, at));
|
|
2768
2160
|
const ids = new Set();
|
|
2769
2161
|
for (const item of cases){
|
|
2770
|
-
if (typeof item.id !== 'string' || !/^[A-Za-z][A-Za-z0-9_]{0,29}$/.test(item.id) || item.id === 'default') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2162
|
+
if (typeof item.id !== 'string' || !/^[A-Za-z][A-Za-z0-9_]{0,29}$/.test(item.id) || item.id === 'default') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CASE_INVALID */.qj.NODE_CASE_INVALID, {
|
|
2771
2163
|
...at,
|
|
2772
2164
|
name: String(item.id)
|
|
2773
2165
|
}));
|
|
2774
|
-
else if (ids.has(item.id)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2166
|
+
else if (ids.has(item.id)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CASE_DUPLICATE */.qj.NODE_CASE_DUPLICATE, {
|
|
2775
2167
|
...at,
|
|
2776
2168
|
name: item.id
|
|
2777
2169
|
}));
|
|
@@ -2780,10 +2172,10 @@ function validateNodeConfig(node, flow, context, err, warn) {
|
|
|
2780
2172
|
break;
|
|
2781
2173
|
}
|
|
2782
2174
|
case 'foreach':
|
|
2783
|
-
expr(c.items, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2784
|
-
if (c.collect !== undefined) expr(c.collect, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2175
|
+
expr(c.items, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_LIST */.bc.THE_LIST));
|
|
2176
|
+
if (c.collect !== undefined) expr(c.collect, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_COLLECTED_VALUE */.bc.THE_COLLECTED_VALUE));
|
|
2785
2177
|
if (c.maxItems !== undefined && !(Number.isInteger(c.maxItems) && c.maxItems >= 1 && c.maxItems <= _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_FOREACH_ITEMS */.Or.MAX_FOREACH_ITEMS)) {
|
|
2786
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2178
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_MAX_ITEMS_RANGE */.qj.NODE_MAX_ITEMS_RANGE, {
|
|
2787
2179
|
...at,
|
|
2788
2180
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_FOREACH_ITEMS */.Or.MAX_FOREACH_ITEMS
|
|
2789
2181
|
}));
|
|
@@ -2836,34 +2228,30 @@ function validateNodeConfig(node, flow, context, err, warn) {
|
|
|
2836
2228
|
break;
|
|
2837
2229
|
case 'entity_get':
|
|
2838
2230
|
entity(c.entityCode);
|
|
2839
|
-
expr(c.id, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2231
|
+
expr(c.id, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_RECORD_ID */.bc.THE_RECORD_ID));
|
|
2840
2232
|
break;
|
|
2841
2233
|
case 'entity_query':
|
|
2842
2234
|
entity(c.entityCode);
|
|
2843
2235
|
filterMap(c.filter, KIND.filter);
|
|
2844
|
-
if (c.search !== undefined) expr(c.search, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2845
|
-
if (c.sort !== undefined) {
|
|
2846
|
-
const sort = c.sort;
|
|
2847
|
-
if (typeof sort?.field !== 'string' || !COLUMN_CODE.test(sort.field) || sort.direction !== undefined && sort.direction !== 'ASC' && sort.direction !== 'DESC') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_SORT_INVALID */.qj.NODE_SORT_INVALID, at));
|
|
2848
|
-
}
|
|
2236
|
+
if (c.search !== undefined) expr(c.search, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_SEARCH_TEXT */.bc.THE_SEARCH_TEXT));
|
|
2849
2237
|
if (c.limit !== undefined && !(Number.isInteger(c.limit) && c.limit >= 1 && c.limit <= _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_QUERY_LIMIT */.Or.MAX_QUERY_LIMIT)) {
|
|
2850
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2238
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_LIMIT_RANGE */.qj.NODE_LIMIT_RANGE, {
|
|
2851
2239
|
...at,
|
|
2852
2240
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_QUERY_LIMIT */.Or.MAX_QUERY_LIMIT
|
|
2853
2241
|
}));
|
|
2854
2242
|
}
|
|
2855
2243
|
break;
|
|
2856
2244
|
case 'call_flow':
|
|
2857
|
-
if (typeof c.flowSlug !== 'string' || !_flow_types_js__rspack_import_6/* .FLOW_SLUG_PATTERN.test */.YD.test(c.flowSlug)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2858
|
-
else if (c.flowSlug === flow.slug) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2859
|
-
else if (context.knownFlows && !context.knownFlows.has(c.flowSlug)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2245
|
+
if (typeof c.flowSlug !== 'string' || !_flow_types_js__rspack_import_6/* .FLOW_SLUG_PATTERN.test */.YD.test(c.flowSlug)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHOOSE_FLOW */.qj.NODE_CHOOSE_FLOW, at));
|
|
2246
|
+
else if (c.flowSlug === flow.slug) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CALLS_ITSELF */.qj.NODE_CALLS_ITSELF, at));
|
|
2247
|
+
else if (context.knownFlows && !context.knownFlows.has(c.flowSlug)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_UNKNOWN */.qj.NODE_FLOW_UNKNOWN, {
|
|
2860
2248
|
...at,
|
|
2861
2249
|
flow: c.flowSlug
|
|
2862
2250
|
}));
|
|
2863
|
-
else if (context.knownFlows) checkCalledFlow(
|
|
2864
|
-
if (c.endpoint !== undefined && c.endpoint !== '' && (typeof c.endpoint !== 'string' || !_flow_types_js__rspack_import_6/* .FLOW_ENDPOINT_PATH_PATTERN.test */.YO.test(c.endpoint))) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2251
|
+
else if (context.knownFlows) checkCalledFlow(c.flowSlug, c.endpoint, c.input, c.inputList, flow, context.knownFlows, at, err, warn);
|
|
2252
|
+
if (c.endpoint !== undefined && c.endpoint !== '' && (typeof c.endpoint !== 'string' || !_flow_types_js__rspack_import_6/* .FLOW_ENDPOINT_PATH_PATTERN.test */.YO.test(c.endpoint))) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.TRIGGER_PATH_INVALID */.qj.TRIGGER_PATH_INVALID, at));
|
|
2865
2253
|
exprMap(c.input, KIND.input);
|
|
2866
|
-
if (c.inputList !== undefined) expr(c.inputList, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2254
|
+
if (c.inputList !== undefined) expr(c.inputList, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_INPUT_LIST */.bc.THE_INPUT_LIST));
|
|
2867
2255
|
break;
|
|
2868
2256
|
case 'http_request':
|
|
2869
2257
|
{
|
|
@@ -2873,13 +2261,12 @@ function validateNodeConfig(node, flow, context, err, warn) {
|
|
|
2873
2261
|
'PUT',
|
|
2874
2262
|
'PATCH',
|
|
2875
2263
|
'DELETE'
|
|
2876
|
-
].includes(String(c.method))) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2877
|
-
expr(c.url, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2264
|
+
].includes(String(c.method))) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHOOSE_METHOD */.qj.NODE_CHOOSE_METHOD, at));
|
|
2265
|
+
expr(c.url, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_URL */.bc.THE_URL));
|
|
2878
2266
|
exprMap(c.headers, KIND.header);
|
|
2879
2267
|
exprMap(c.body, KIND.body);
|
|
2880
|
-
if (c.forwardAuth === true) warn.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FORWARDS_TOKEN */.qj.NODE_FORWARDS_TOKEN, at));
|
|
2881
2268
|
if (c.timeoutMs !== undefined && !(Number.isInteger(c.timeoutMs) && c.timeoutMs >= 100 && c.timeoutMs <= _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_HTTP_TIMEOUT_MS */.Or.MAX_HTTP_TIMEOUT_MS)) {
|
|
2882
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2269
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_TIMEOUT_RANGE */.qj.NODE_TIMEOUT_RANGE, {
|
|
2883
2270
|
...at,
|
|
2884
2271
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_HTTP_TIMEOUT_MS */.Or.MAX_HTTP_TIMEOUT_MS
|
|
2885
2272
|
}));
|
|
@@ -2887,71 +2274,28 @@ function validateNodeConfig(node, flow, context, err, warn) {
|
|
|
2887
2274
|
break;
|
|
2888
2275
|
}
|
|
2889
2276
|
case 'publish_event':
|
|
2890
|
-
if (typeof c.eventName !== 'string' || !/^[a-z][a-z0-9_.-]{1,59}$/.test(c.eventName)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2277
|
+
if (typeof c.eventName !== 'string' || !/^[a-z][a-z0-9_.-]{1,59}$/.test(c.eventName)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_EVENT_NAME_INVALID */.qj.NODE_EVENT_NAME_INVALID, at));
|
|
2891
2278
|
exprMap(c.payload, KIND.payload);
|
|
2892
2279
|
break;
|
|
2893
|
-
case 'send_notification':
|
|
2894
|
-
{
|
|
2895
|
-
serviceRunning('notification', _config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_NOTIFICATION_UNAVAILABLE */.qj.NODE_NOTIFICATION_UNAVAILABLE);
|
|
2896
|
-
const target = c.target ?? 'one';
|
|
2897
|
-
if (!_flow_types_js__rspack_import_6/* .FLOW_NOTIFICATION_TARGETS.includes */.as.includes(target)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_MESSAGE_TARGET_INVALID */.qj.NODE_MESSAGE_TARGET_INVALID, at));
|
|
2898
|
-
if (target === 'many') expr(c.items, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_LIST */.bc.THE_LIST));
|
|
2899
|
-
if (target === 'company') {
|
|
2900
|
-
if (context.companyMembers === false) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_NOTIFICATION_COMPANY_UNAVAILABLE */.qj.NODE_NOTIFICATION_COMPANY_UNAVAILABLE, at));
|
|
2901
|
-
expr(c.companyIds, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_COMPANIES */.bc.THE_COMPANIES));
|
|
2902
|
-
optionalExpr(c.branchIds, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_BRANCHES */.bc.THE_BRANCHES));
|
|
2903
|
-
} else {
|
|
2904
|
-
expr(c.userIds, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_RECIPIENTS */.bc.THE_RECIPIENTS));
|
|
2905
|
-
optionalExpr(c.companyId, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_COMPANY */.bc.THE_COMPANY));
|
|
2906
|
-
}
|
|
2907
|
-
expr(c.title, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_TITLE */.bc.THE_TITLE));
|
|
2908
|
-
optionalExpr(c.message, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_MESSAGE */.bc.THE_MESSAGE));
|
|
2909
|
-
exprMap(c.data, KIND.data);
|
|
2910
|
-
if (c.type !== undefined && !_flow_types_js__rspack_import_6/* .FLOW_NOTIFICATION_TYPES.includes */.LG.includes(c.type)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_NOTIFICATION_OPTION_INVALID */.qj.NODE_NOTIFICATION_OPTION_INVALID, at));
|
|
2911
|
-
if (c.realtime !== undefined && typeof c.realtime !== 'boolean') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_NOTIFICATION_OPTION_INVALID */.qj.NODE_NOTIFICATION_OPTION_INVALID, at));
|
|
2912
|
-
break;
|
|
2913
|
-
}
|
|
2914
|
-
case 'send_email':
|
|
2915
|
-
{
|
|
2916
|
-
serviceRunning('email', _config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_EMAIL_UNAVAILABLE */.qj.NODE_EMAIL_UNAVAILABLE);
|
|
2917
|
-
if (!_flow_types_js__rspack_import_6/* .FLOW_EMAIL_TARGETS.includes */.B9.includes(c.target ?? 'one')) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_MESSAGE_TARGET_INVALID */.qj.NODE_MESSAGE_TARGET_INVALID, at));
|
|
2918
|
-
if (c.target === 'many') expr(c.items, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_LIST */.bc.THE_LIST));
|
|
2919
|
-
expr(c.to, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_RECIPIENTS */.bc.THE_RECIPIENTS));
|
|
2920
|
-
optionalExpr(c.cc, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_CC */.bc.THE_CC));
|
|
2921
|
-
optionalExpr(c.bcc, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_BCC */.bc.THE_BCC));
|
|
2922
|
-
optionalExpr(c.replyTo, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_REPLY_TO */.bc.THE_REPLY_TO));
|
|
2923
|
-
if (c.mode !== undefined && !_flow_types_js__rspack_import_6/* .FLOW_EMAIL_MODES.includes */.v1.includes(c.mode)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_EMAIL_OPTION_INVALID */.qj.NODE_EMAIL_OPTION_INVALID, at));
|
|
2924
|
-
if (c.format !== undefined && !_flow_types_js__rspack_import_6/* .FLOW_EMAIL_FORMATS.includes */.FU.includes(c.format)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_EMAIL_OPTION_INVALID */.qj.NODE_EMAIL_OPTION_INVALID, at));
|
|
2925
|
-
if (c.emailConfigId !== undefined && c.emailConfigId !== '' && (typeof c.emailConfigId !== 'string' || !_flow_types_js__rspack_import_6/* .FLOW_ID_PATTERN.test */.E2.test(c.emailConfigId))) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_EMAIL_OPTION_INVALID */.qj.NODE_EMAIL_OPTION_INVALID, at));
|
|
2926
|
-
if (c.mode === 'template') {
|
|
2927
|
-
const slug = typeof c.templateSlug === 'string' ? c.templateSlug.trim() : '';
|
|
2928
|
-
if (!slug || slug.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_EMAIL_TEMPLATE_SLUG_LENGTH */.Or.MAX_EMAIL_TEMPLATE_SLUG_LENGTH) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_EMAIL_TEMPLATE_REQUIRED */.qj.NODE_EMAIL_TEMPLATE_REQUIRED, at));
|
|
2929
|
-
exprMap(c.variables, KIND.template);
|
|
2930
|
-
} else {
|
|
2931
|
-
expr(c.subject, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_SUBJECT */.bc.THE_SUBJECT));
|
|
2932
|
-
expr(c.body, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_BODY */.bc.THE_BODY));
|
|
2933
|
-
}
|
|
2934
|
-
break;
|
|
2935
|
-
}
|
|
2936
2280
|
case 'respond':
|
|
2937
2281
|
{
|
|
2938
2282
|
const status = c.statusCode;
|
|
2939
|
-
if (!(Number.isInteger(status) && status >= 200 && status <= 599)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2283
|
+
if (!(Number.isInteger(status) && status >= 200 && status <= 599)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_STATUS_2XX_5XX */.qj.NODE_STATUS_2XX_5XX, at));
|
|
2940
2284
|
exprMap(c.body, KIND.response);
|
|
2941
|
-
if (c.bodyExpression !== undefined) expr(c.bodyExpression, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2285
|
+
if (c.bodyExpression !== undefined) expr(c.bodyExpression, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_RESPONSE */.bc.THE_RESPONSE));
|
|
2942
2286
|
break;
|
|
2943
2287
|
}
|
|
2944
2288
|
case 'commit':
|
|
2945
|
-
if (node.onError === 'continue') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2289
|
+
if (node.onError === 'continue') err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_COMMIT_CONTINUE */.qj.NODE_COMMIT_CONTINUE, at));
|
|
2946
2290
|
break;
|
|
2947
2291
|
case 'code':
|
|
2948
|
-
if (typeof c.code !== 'string' || !c.code.trim()) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2949
|
-
else if (c.code.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CODE_LENGTH */.Or.MAX_CODE_LENGTH) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2292
|
+
if (typeof c.code !== 'string' || !c.code.trim()) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CODE_REQUIRED */.qj.NODE_CODE_REQUIRED, at));
|
|
2293
|
+
else if (c.code.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CODE_LENGTH */.Or.MAX_CODE_LENGTH) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CODE_TOO_LONG */.qj.NODE_CODE_TOO_LONG, {
|
|
2950
2294
|
...at,
|
|
2951
2295
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CODE_LENGTH */.Or.MAX_CODE_LENGTH
|
|
2952
2296
|
}));
|
|
2953
2297
|
if (c.timeoutMs !== undefined && !(Number.isInteger(c.timeoutMs) && c.timeoutMs >= _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MIN_CODE_TIMEOUT_MS */.Or.MIN_CODE_TIMEOUT_MS && c.timeoutMs <= _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CODE_TIMEOUT_MS */.Or.MAX_CODE_TIMEOUT_MS)) {
|
|
2954
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2298
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CODE_TIMEOUT_RANGE */.qj.NODE_CODE_TIMEOUT_RANGE, {
|
|
2955
2299
|
...at,
|
|
2956
2300
|
min: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MIN_CODE_TIMEOUT_MS */.Or.MIN_CODE_TIMEOUT_MS,
|
|
2957
2301
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CODE_TIMEOUT_MS */.Or.MAX_CODE_TIMEOUT_MS
|
|
@@ -2962,19 +2306,19 @@ function validateNodeConfig(node, flow, context, err, warn) {
|
|
|
2962
2306
|
}
|
|
2963
2307
|
/** `target` and what it needs: one - an id; many - a list (the id is optional, the item's own id by default); filter - a filter and a limit. */ function writeTargetConfig(c, targets, notFound, { at, expr, filterMap, err }) {
|
|
2964
2308
|
const target = c.target ?? 'one';
|
|
2965
|
-
if (typeof target !== 'string' || !targets.includes(target)) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2966
|
-
if (c.onNotFound !== undefined && !notFound.includes(c.onNotFound)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2309
|
+
if (typeof target !== 'string' || !targets.includes(target)) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_WRITE_TARGET_INVALID */.qj.NODE_WRITE_TARGET_INVALID, at));
|
|
2310
|
+
if (c.onNotFound !== undefined && !notFound.includes(c.onNotFound)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_NOT_FOUND_INVALID */.qj.NODE_NOT_FOUND_INVALID, at));
|
|
2967
2311
|
const needsId = notFound.length > 0;
|
|
2968
|
-
if (target === 'one' && needsId) expr(c.id, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2312
|
+
if (target === 'one' && needsId) expr(c.id, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_RECORD_ID */.bc.THE_RECORD_ID));
|
|
2969
2313
|
if (target === 'many') {
|
|
2970
|
-
expr(c.items, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2971
|
-
if (needsId && c.id !== undefined) expr(c.id, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2314
|
+
expr(c.items, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_LIST */.bc.THE_LIST));
|
|
2315
|
+
if (needsId && c.id !== undefined) expr(c.id, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_RECORD_ID */.bc.THE_RECORD_ID));
|
|
2972
2316
|
}
|
|
2973
2317
|
if (target === 'filter') {
|
|
2974
2318
|
filterMap(c.filter);
|
|
2975
|
-
if (!c.filter || typeof c.filter !== 'object' || !Object.keys(c.filter).length) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2319
|
+
if (!c.filter || typeof c.filter !== 'object' || !Object.keys(c.filter).length) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_FILTER_REQUIRED */.qj.NODE_FILTER_REQUIRED, at));
|
|
2976
2320
|
if (c.limit !== undefined && !(Number.isInteger(c.limit) && c.limit >= 1 && c.limit <= _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_WRITE_ITEMS */.Or.MAX_WRITE_ITEMS)) {
|
|
2977
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2321
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_LIMIT_RANGE */.qj.NODE_LIMIT_RANGE, {
|
|
2978
2322
|
...at,
|
|
2979
2323
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_WRITE_ITEMS */.Or.MAX_WRITE_ITEMS
|
|
2980
2324
|
}));
|
|
@@ -2983,45 +2327,45 @@ function validateNodeConfig(node, flow, context, err, warn) {
|
|
|
2983
2327
|
}
|
|
2984
2328
|
function childInserts(value, { at, entity, expr, err }) {
|
|
2985
2329
|
if (value === undefined) return;
|
|
2986
|
-
if (!Array.isArray(value)) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2987
|
-
if (value.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CHILD_INSERTS */.Or.MAX_CHILD_INSERTS) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2330
|
+
if (!Array.isArray(value)) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHILDREN_INVALID */.qj.NODE_CHILDREN_INVALID, at));
|
|
2331
|
+
if (value.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CHILD_INSERTS */.Or.MAX_CHILD_INSERTS) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHILDREN_TOO_MANY */.qj.NODE_CHILDREN_TOO_MANY, {
|
|
2988
2332
|
...at,
|
|
2989
2333
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_CHILD_INSERTS */.Or.MAX_CHILD_INSERTS
|
|
2990
2334
|
}));
|
|
2991
2335
|
const names = new Set();
|
|
2992
2336
|
for (const child of value){
|
|
2993
2337
|
if (!child || typeof child !== 'object') {
|
|
2994
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2338
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHILDREN_INVALID */.qj.NODE_CHILDREN_INVALID, at));
|
|
2995
2339
|
continue;
|
|
2996
2340
|
}
|
|
2997
2341
|
const name = String(child.as ?? '');
|
|
2998
|
-
if (!_flow_types_js__rspack_import_6/* .FLOW_INPUT_NAME_PATTERN.test */.fZ.test(name)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2342
|
+
if (!_flow_types_js__rspack_import_6/* .FLOW_INPUT_NAME_PATTERN.test */.fZ.test(name)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHILD_NAME_INVALID */.qj.NODE_CHILD_NAME_INVALID, {
|
|
2999
2343
|
...at,
|
|
3000
2344
|
name
|
|
3001
2345
|
}));
|
|
3002
|
-
else if (names.has(name)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2346
|
+
else if (names.has(name)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHILD_NAME_DUPLICATE */.qj.NODE_CHILD_NAME_DUPLICATE, {
|
|
3003
2347
|
...at,
|
|
3004
2348
|
name
|
|
3005
2349
|
}));
|
|
3006
2350
|
names.add(name);
|
|
3007
2351
|
entity(child.entityCode);
|
|
3008
|
-
if (typeof child.parentField !== 'string' || !COLUMN_CODE.test(child.parentField)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2352
|
+
if (typeof child.parentField !== 'string' || !COLUMN_CODE.test(child.parentField)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHILD_PARENT_FIELD_REQUIRED */.qj.NODE_CHILD_PARENT_FIELD_REQUIRED, {
|
|
3009
2353
|
...at,
|
|
3010
2354
|
name
|
|
3011
2355
|
}));
|
|
3012
|
-
expr(child.items, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2356
|
+
expr(child.items, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.CHILD_LIST */.bc.CHILD_LIST, {
|
|
3013
2357
|
name
|
|
3014
2358
|
}));
|
|
3015
2359
|
const fields = child.fields;
|
|
3016
2360
|
if (fields === undefined) continue;
|
|
3017
2361
|
if (!fields || typeof fields !== 'object' || Array.isArray(fields)) {
|
|
3018
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2362
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_PAIRS_INVALID */.qj.NODE_PAIRS_INVALID, {
|
|
3019
2363
|
...at,
|
|
3020
|
-
what: (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2364
|
+
what: (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.FIELDS */.bc.FIELDS)
|
|
3021
2365
|
}));
|
|
3022
2366
|
continue;
|
|
3023
2367
|
}
|
|
3024
|
-
for (const [key, item] of Object.entries(fields))expr(item, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2368
|
+
for (const [key, item] of Object.entries(fields))expr(item, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.CHILD_FIELD */.bc.CHILD_FIELD, {
|
|
3025
2369
|
name: `${name}.${key}`
|
|
3026
2370
|
}));
|
|
3027
2371
|
}
|
|
@@ -3029,8 +2373,7 @@ function childInserts(value, { at, entity, expr, err }) {
|
|
|
3029
2373
|
/**
|
|
3030
2374
|
* How many loop levels each part of a node's config runs inside, beyond the loops around the node:
|
|
3031
2375
|
* a foreach's `collect` runs in its own loop; a many / filter write's per-record expressions in one
|
|
3032
|
-
* of the node's own; child records one deeper than their parent record
|
|
3033
|
-
* (all but its list) one per item.
|
|
2376
|
+
* of the node's own; child records one deeper than their parent record.
|
|
3034
2377
|
*/ function configScopes(node) {
|
|
3035
2378
|
const config = node.config ?? {};
|
|
3036
2379
|
if (node.type === 'foreach') {
|
|
@@ -3048,21 +2391,6 @@ function childInserts(value, { at, entity, expr, err }) {
|
|
|
3048
2391
|
}
|
|
3049
2392
|
];
|
|
3050
2393
|
}
|
|
3051
|
-
if ((0,_flow_types_js__rspack_import_6/* .isMessageNode */.SE)(node.type) && config['target'] === 'many') {
|
|
3052
|
-
const { items, ...perItem } = config;
|
|
3053
|
-
return [
|
|
3054
|
-
{
|
|
3055
|
-
value: items,
|
|
3056
|
-
extra: 0,
|
|
3057
|
-
ownLoop: false
|
|
3058
|
-
},
|
|
3059
|
-
{
|
|
3060
|
-
value: perItem,
|
|
3061
|
-
extra: 1,
|
|
3062
|
-
ownLoop: false
|
|
3063
|
-
}
|
|
3064
|
-
];
|
|
3065
|
-
}
|
|
3066
2394
|
if (!WRITE_NODE_TYPES.has(node.type)) return [
|
|
3067
2395
|
{
|
|
3068
2396
|
value: config,
|
|
@@ -3101,32 +2429,32 @@ function childInserts(value, { at, entity, expr, err }) {
|
|
|
3101
2429
|
return scopes;
|
|
3102
2430
|
}
|
|
3103
2431
|
function validateChecks(c, at, rule, err) {
|
|
3104
|
-
if (!Array.isArray(c.checks) || !c.checks.length) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
3105
|
-
if (c.checks.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_VALIDATE_CHECKS */.Or.MAX_VALIDATE_CHECKS) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2432
|
+
if (!Array.isArray(c.checks) || !c.checks.length) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHECK_REQUIRED */.qj.NODE_CHECK_REQUIRED, at));
|
|
2433
|
+
if (c.checks.length > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_VALIDATE_CHECKS */.Or.MAX_VALIDATE_CHECKS) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_TOO_MANY_CHECKS */.qj.NODE_TOO_MANY_CHECKS, {
|
|
3106
2434
|
...at,
|
|
3107
2435
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_VALIDATE_CHECKS */.Or.MAX_VALIDATE_CHECKS
|
|
3108
2436
|
}));
|
|
3109
2437
|
const ids = new Set();
|
|
3110
2438
|
for (const check of c.checks){
|
|
3111
2439
|
const id = check?.id;
|
|
3112
|
-
if (typeof id !== 'string' || !CHECK_ID.test(id)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2440
|
+
if (typeof id !== 'string' || !CHECK_ID.test(id)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHECK_ID_INVALID */.qj.NODE_CHECK_ID_INVALID, {
|
|
3113
2441
|
...at,
|
|
3114
2442
|
name: String(id)
|
|
3115
2443
|
}));
|
|
3116
|
-
else if (ids.has(id)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2444
|
+
else if (ids.has(id)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHECK_ID_DUPLICATE */.qj.NODE_CHECK_ID_DUPLICATE, {
|
|
3117
2445
|
...at,
|
|
3118
2446
|
name: id
|
|
3119
2447
|
}));
|
|
3120
2448
|
else ids.add(id);
|
|
3121
2449
|
const name = String(id);
|
|
3122
|
-
rule(check?.rule, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2450
|
+
rule(check?.rule, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_SUBJECT_MESSAGES.THE_CHECK */.bc.THE_CHECK, {
|
|
3123
2451
|
name
|
|
3124
2452
|
}));
|
|
3125
|
-
if (typeof check?.message !== 'string' || !check.message.trim()) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2453
|
+
if (typeof check?.message !== 'string' || !check.message.trim()) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHECK_MESSAGE_REQUIRED */.qj.NODE_CHECK_MESSAGE_REQUIRED, {
|
|
3126
2454
|
...at,
|
|
3127
2455
|
name
|
|
3128
2456
|
}));
|
|
3129
|
-
if (check?.field !== undefined && (typeof check.field !== 'string' || !check.field.trim() || check.field.length > 100)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2457
|
+
if (check?.field !== undefined && (typeof check.field !== 'string' || !check.field.trim() || check.field.length > 100)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.NODE_CHECK_FIELD_INVALID */.qj.NODE_CHECK_FIELD_INVALID, {
|
|
3130
2458
|
...at,
|
|
3131
2459
|
name
|
|
3132
2460
|
}));
|
|
@@ -3147,21 +2475,21 @@ function validateChecks(c, at, rule, err) {
|
|
|
3147
2475
|
for (const ref of refs){
|
|
3148
2476
|
const [scope, second] = ref.split('.');
|
|
3149
2477
|
if (!REF_SCOPES.has(scope)) {
|
|
3150
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2478
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.REF_BAD_SCOPE */.qj.REF_BAD_SCOPE, {
|
|
3151
2479
|
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(node),
|
|
3152
2480
|
ref
|
|
3153
2481
|
}));
|
|
3154
2482
|
} else if (scope === 'context' && second && !byId.has(second)) {
|
|
3155
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2483
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.REF_NODE_MISSING */.qj.REF_NODE_MISSING, {
|
|
3156
2484
|
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(node),
|
|
3157
2485
|
target: second
|
|
3158
2486
|
}));
|
|
3159
2487
|
} else if (scope === 'context' && second === node.id) {
|
|
3160
|
-
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2488
|
+
err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.REF_SELF */.qj.REF_SELF, {
|
|
3161
2489
|
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(node)
|
|
3162
2490
|
}));
|
|
3163
2491
|
} else if (scope === 'input' && second && namesKnown && !declaredInputs.has(second)) {
|
|
3164
|
-
warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2492
|
+
warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.REF_INPUT_UNDECLARED */.qj.REF_INPUT_UNDECLARED, {
|
|
3165
2493
|
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(node),
|
|
3166
2494
|
input: second
|
|
3167
2495
|
}));
|
|
@@ -3177,28 +2505,15 @@ function refsOf(value, refs = [], depth = 0) {
|
|
|
3177
2505
|
return refs;
|
|
3178
2506
|
}
|
|
3179
2507
|
/**
|
|
3180
|
-
* Writes that do not share a transaction, and Save progress steps that would not commit:
|
|
3181
|
-
*
|
|
3182
|
-
*
|
|
3183
|
-
*/ function checkTransactionUse(flow,
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
node: label
|
|
3190
|
-
}));
|
|
3191
|
-
for (const commit of steps)if (commit.type === 'commit') warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.COMMIT_NOT_TRANSACTIONAL */.qj.COMMIT_NOT_TRANSACTIONAL, {
|
|
3192
|
-
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(commit),
|
|
3193
|
-
endpoint: label
|
|
3194
|
-
}));
|
|
3195
|
-
}
|
|
3196
|
-
const live = [
|
|
3197
|
-
...new Map(runs.flatMap((run)=>run.steps).map((n)=>[
|
|
3198
|
-
n.id,
|
|
3199
|
-
n
|
|
3200
|
-
])).values()
|
|
3201
|
-
];
|
|
2508
|
+
* Writes that do not share a transaction, and Save progress steps that would not commit: in a flow
|
|
2509
|
+
* without the transaction setting, inside a loop (once per item), or in a flow other flows call
|
|
2510
|
+
* (inside its caller's transaction it is skipped).
|
|
2511
|
+
*/ function checkTransactionUse(flow, nodes, outgoing, reachable, context, warnings) {
|
|
2512
|
+
const live = nodes.filter((n)=>!reachable || reachable.has(n.id));
|
|
2513
|
+
const writes = live.filter((n)=>WRITE_NODE_TYPES.has(n.type)).length;
|
|
2514
|
+
if (!flow.isTransactional && writes >= 2) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.WRITES_NOT_TRANSACTIONAL */.qj.WRITES_NOT_TRANSACTIONAL, {
|
|
2515
|
+
count: writes
|
|
2516
|
+
}));
|
|
3202
2517
|
const commits = live.filter((n)=>n.type === 'commit');
|
|
3203
2518
|
if (!commits.length) return;
|
|
3204
2519
|
const loops = live.filter((n)=>n.type === 'foreach').map((n)=>({
|
|
@@ -3212,12 +2527,13 @@ function refsOf(value, refs = [], depth = 0) {
|
|
|
3212
2527
|
const at = {
|
|
3213
2528
|
node: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(commit)
|
|
3214
2529
|
};
|
|
2530
|
+
if (!flow.isTransactional) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.COMMIT_NOT_TRANSACTIONAL */.qj.COMMIT_NOT_TRANSACTIONAL, at));
|
|
3215
2531
|
const loop = loops.find((l)=>l.body.has(commit.id));
|
|
3216
|
-
if (loop) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2532
|
+
if (loop) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.COMMIT_IN_LOOP */.qj.COMMIT_IN_LOOP, {
|
|
3217
2533
|
...at,
|
|
3218
2534
|
loop: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(loop.node)
|
|
3219
2535
|
}));
|
|
3220
|
-
if (called) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2536
|
+
if (called) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.COMMIT_IN_CALLED_FLOW */.qj.COMMIT_IN_CALLED_FLOW, at));
|
|
3221
2537
|
}
|
|
3222
2538
|
}
|
|
3223
2539
|
/** Every node a loop's `each` branch runs, nested loops included. */ function loopBody(loopId, outgoing) {
|
|
@@ -3320,14 +2636,14 @@ function refsOf(value, refs = [], depth = 0) {
|
|
|
3320
2636
|
const [scope, target, field] = segs;
|
|
3321
2637
|
if (scope === 'loop') {
|
|
3322
2638
|
const parents = segs.slice(1).findIndex((s)=>s !== 'parent');
|
|
3323
|
-
if (!depth) warn(
|
|
3324
|
-
else if ((parents < 0 ? segs.length - 1 : parents) >= depth) warn(
|
|
2639
|
+
if (!depth) warn(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.REF_LOOP_OUTSIDE */.qj.REF_LOOP_OUTSIDE, {});
|
|
2640
|
+
else if ((parents < 0 ? segs.length - 1 : parents) >= depth) warn(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.REF_LOOP_PARENT_MISSING */.qj.REF_LOOP_PARENT_MISSING, {});
|
|
3325
2641
|
}
|
|
3326
2642
|
if (scope !== 'context' || !target || target === node.id || !byId.has(target)) continue;
|
|
3327
|
-
if (!available.has(target)) warn(
|
|
2643
|
+
if (!available.has(target)) warn(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.REF_NODE_NOT_YET */.qj.REF_NODE_NOT_YET, {
|
|
3328
2644
|
target: nameOf(target)
|
|
3329
2645
|
});
|
|
3330
|
-
else if (field === 'results' && around.has(target)) warn(
|
|
2646
|
+
else if (field === 'results' && around.has(target)) warn(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.REF_LOOP_RESULTS_EARLY */.qj.REF_LOOP_RESULTS_EARLY, {
|
|
3331
2647
|
loop: nameOf(target)
|
|
3332
2648
|
});
|
|
3333
2649
|
}
|
|
@@ -3382,15 +2698,14 @@ function reach(start, outgoing) {
|
|
|
3382
2698
|
nesting.set(id, max);
|
|
3383
2699
|
return max;
|
|
3384
2700
|
};
|
|
3385
|
-
if (nodes.some((n)=>n.type === 'trigger' && nestingFrom(n.id) > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_LOOP_DEPTH */.Or.MAX_LOOP_DEPTH)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(
|
|
2701
|
+
if (nodes.some((n)=>n.type === 'trigger' && nestingFrom(n.id) > _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_LOOP_DEPTH */.Or.MAX_LOOP_DEPTH)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_7/* .FLOW_VALIDATION_MESSAGES.LOOP_TOO_DEEP */.qj.LOOP_TOO_DEEP, {
|
|
3386
2702
|
max: _flow_types_js__rspack_import_6/* .FLOW_LIMITS.MAX_LOOP_DEPTH */.Or.MAX_LOOP_DEPTH
|
|
3387
2703
|
}));
|
|
3388
2704
|
}
|
|
3389
2705
|
|
|
3390
2706
|
__webpack_require__.d(__webpack_exports__, {
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
u9: () => (usesPermissionFunction)
|
|
2707
|
+
n: () => (validateFlow),
|
|
2708
|
+
u: () => (usesPermissionFunction)
|
|
3394
2709
|
});
|
|
3395
2710
|
|
|
3396
2711
|
|
|
@@ -3680,7 +2995,6 @@ const FLOW_NODE_TYPES = [
|
|
|
3680
2995
|
'trigger',
|
|
3681
2996
|
'validate',
|
|
3682
2997
|
'permission_check',
|
|
3683
|
-
'company_branch_check',
|
|
3684
2998
|
'set',
|
|
3685
2999
|
'condition',
|
|
3686
3000
|
'switch',
|
|
@@ -3694,32 +3008,21 @@ const FLOW_NODE_TYPES = [
|
|
|
3694
3008
|
'call_flow',
|
|
3695
3009
|
'http_request',
|
|
3696
3010
|
'publish_event',
|
|
3697
|
-
'send_notification',
|
|
3698
|
-
'send_email',
|
|
3699
3011
|
'respond',
|
|
3700
3012
|
'code'
|
|
3701
3013
|
];
|
|
3702
3014
|
/** A failure of these always ends the run: checks can never be carried past, and Save progress cannot run in a savepoint. */ const NON_CONTINUABLE_NODE_TYPES = new Set([
|
|
3703
3015
|
'validate',
|
|
3704
3016
|
'permission_check',
|
|
3705
|
-
'company_branch_check',
|
|
3706
3017
|
'commit'
|
|
3707
3018
|
]);
|
|
3708
|
-
|
|
3709
|
-
* Who may start a run at a Request step. `internal` (other flows only): the step has no URL - only
|
|
3710
|
-
* other flows' `call_flow` steps start there, and the run takes its caller's run-as.
|
|
3711
|
-
*/ const FLOW_AUTH_MODES = [
|
|
3019
|
+
const FLOW_AUTH_MODES = [
|
|
3712
3020
|
'public',
|
|
3713
3021
|
'api_key',
|
|
3714
3022
|
'jwt',
|
|
3715
3023
|
'permission',
|
|
3716
3024
|
'internal'
|
|
3717
3025
|
];
|
|
3718
|
-
/** A Request step that sets no access: any signed-in user. */ const DEFAULT_AUTH_MODE = 'jwt';
|
|
3719
|
-
/** Modes a caller reaches without signing in: the run has no `user`. */ const KEYLESS_AUTH_MODES = new Set([
|
|
3720
|
-
'public',
|
|
3721
|
-
'api_key'
|
|
3722
|
-
]);
|
|
3723
3026
|
const FLOW_RUN_AS = [
|
|
3724
3027
|
'caller',
|
|
3725
3028
|
'system'
|
|
@@ -3752,42 +3055,6 @@ const FLOW_INPUT_TYPES = [
|
|
|
3752
3055
|
'many',
|
|
3753
3056
|
'filter'
|
|
3754
3057
|
];
|
|
3755
|
-
function isStoredApiKey(value) {
|
|
3756
|
-
const key = value;
|
|
3757
|
-
return typeof key?.prefix === 'string' && typeof key.hash === 'string' && /^[0-9a-f]{64}$/.test(key.hash);
|
|
3758
|
-
}
|
|
3759
|
-
/** The app modules a message step sends through; a step whose module is not installed cannot be saved or run. */ const FLOW_MESSAGE_SERVICES = {
|
|
3760
|
-
send_notification: 'notification',
|
|
3761
|
-
send_email: 'email'
|
|
3762
|
-
};
|
|
3763
|
-
const isMessageNode = (type)=>Object.hasOwn(FLOW_MESSAGE_SERVICES, type);
|
|
3764
|
-
const FLOW_NOTIFICATION_TYPES = [
|
|
3765
|
-
'info',
|
|
3766
|
-
'success',
|
|
3767
|
-
'warning',
|
|
3768
|
-
'error'
|
|
3769
|
-
];
|
|
3770
|
-
/**
|
|
3771
|
-
* Who a notification step sends to. one (default): one notification to the users `userIds` names.
|
|
3772
|
-
* many: one per item of `items`, each read with the item as `loop.item`. company: every active member
|
|
3773
|
-
* of `companyIds` (one or a list; with `branchIds`, only those also in one of those branches), shown under that company.
|
|
3774
|
-
*/ const FLOW_NOTIFICATION_TARGETS = [
|
|
3775
|
-
'one',
|
|
3776
|
-
'many',
|
|
3777
|
-
'company'
|
|
3778
|
-
];
|
|
3779
|
-
/** one (default): one email. many: one per item of `items`, each read with the item as `loop.item`. */ const FLOW_EMAIL_TARGETS = [
|
|
3780
|
-
'one',
|
|
3781
|
-
'many'
|
|
3782
|
-
];
|
|
3783
|
-
const FLOW_EMAIL_MODES = [
|
|
3784
|
-
'content',
|
|
3785
|
-
'template'
|
|
3786
|
-
];
|
|
3787
|
-
const FLOW_EMAIL_FORMATS = [
|
|
3788
|
-
'text',
|
|
3789
|
-
'html'
|
|
3790
|
-
];
|
|
3791
3058
|
const FLOW_LIMITS = {
|
|
3792
3059
|
MAX_NODES: 100,
|
|
3793
3060
|
MAX_EDGES: 300,
|
|
@@ -3796,13 +3063,6 @@ const FLOW_LIMITS = {
|
|
|
3796
3063
|
MAX_LOOP_DEPTH: 3,
|
|
3797
3064
|
MAX_CALL_DEPTH: 5,
|
|
3798
3065
|
MAX_HTTP_CALLS: 10,
|
|
3799
|
-
/** Notification and email steps sent per run (a loop counts every pass). */ MAX_MESSAGES_PER_RUN: 100,
|
|
3800
|
-
MAX_NOTIFICATION_RECIPIENTS: 500,
|
|
3801
|
-
/** All members of the companies a company-wide notification step reaches. */ MAX_COMPANY_NOTIFICATION_RECIPIENTS: 5000,
|
|
3802
|
-
/** to + cc + bcc of one email. */ MAX_EMAIL_RECIPIENTS: 50,
|
|
3803
|
-
MAX_NOTIFICATION_TITLE_LENGTH: 255,
|
|
3804
|
-
MAX_EMAIL_SUBJECT_LENGTH: 255,
|
|
3805
|
-
MAX_EMAIL_TEMPLATE_SLUG_LENGTH: 255,
|
|
3806
3066
|
MAX_HTTP_TIMEOUT_MS: 15_000,
|
|
3807
3067
|
MAX_HTTP_RESPONSE_BYTES: 1_000_000,
|
|
3808
3068
|
MAX_QUERY_LIMIT: 200,
|
|
@@ -3813,8 +3073,6 @@ const FLOW_LIMITS = {
|
|
|
3813
3073
|
DEFAULT_TIMEOUT_MS: 30_000,
|
|
3814
3074
|
MIN_TIMEOUT_MS: 1000,
|
|
3815
3075
|
MAX_TIMEOUT_MS: 120_000,
|
|
3816
|
-
DEFAULT_RATE_LIMIT_PER_MINUTE: 60,
|
|
3817
|
-
MAX_RATE_LIMIT_PER_MINUTE: 100_000,
|
|
3818
3076
|
TRACE_PREVIEW_CHARS: 2000,
|
|
3819
3077
|
MAX_INPUT_FIELDS: 50,
|
|
3820
3078
|
/** How deep object/list-of-object fields may nest inside the request body. */ MAX_INPUT_DEPTH: 4,
|
|
@@ -3833,38 +3091,25 @@ const FLOW_NODE_ID_PATTERN = /^[A-Za-z][A-Za-z0-9_]{0,39}$/;
|
|
|
3833
3091
|
const FLOW_SLUG_PATTERN = /^[a-z][a-z0-9-]{2,62}$/;
|
|
3834
3092
|
const FLOW_INPUT_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9_]{0,59}$/;
|
|
3835
3093
|
const FLOW_ENDPOINT_PATH_PATTERN = /^[a-z][a-z0-9-]{0,62}$/;
|
|
3836
|
-
/** A record, user or company id. */ const FLOW_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
3837
|
-
/** Who may start a run at a Request step; an unknown mode reads as the default, which the validator refuses on save. */ function endpointAuth(config) {
|
|
3838
|
-
const authMode = config.authMode && FLOW_AUTH_MODES.includes(config.authMode) ? config.authMode : DEFAULT_AUTH_MODE;
|
|
3839
|
-
const code = authMode === 'permission' && typeof config.permissionCode === 'string' ? config.permissionCode.trim() : '';
|
|
3840
|
-
return {
|
|
3841
|
-
authMode,
|
|
3842
|
-
permissionCode: code || null
|
|
3843
|
-
};
|
|
3844
|
-
}
|
|
3845
|
-
/** A flow whose every Request step is `internal`: a function, with no URL of its own. */ const isFunctionFlow = (flow)=>{
|
|
3846
|
-
const endpoints = flowEndpoints(flow);
|
|
3847
|
-
return endpoints.length > 0 && endpoints.every((endpoint)=>endpoint.authMode === 'internal');
|
|
3848
|
-
};
|
|
3849
3094
|
/** A Request step's path, or null when it answers on the flow's own URL. */ function triggerPath(node) {
|
|
3850
3095
|
const path = node.config?.path;
|
|
3851
3096
|
return typeof path === 'string' && path.trim() ? path.trim() : null;
|
|
3852
3097
|
}
|
|
3853
|
-
/** Every Request step of a flow as a URL
|
|
3098
|
+
/** Every Request step of a flow as a URL. */ function flowEndpoints(flow) {
|
|
3854
3099
|
return (flow.nodes ?? []).filter((node)=>node?.type === 'trigger').map((node)=>{
|
|
3855
3100
|
const path = triggerPath(node);
|
|
3856
|
-
|
|
3101
|
+
if (!path) return {
|
|
3102
|
+
nodeId: node.id,
|
|
3103
|
+
path,
|
|
3104
|
+
bodyType: flow.bodyType ?? 'object',
|
|
3105
|
+
inputSchema: flow.inputSchema ?? []
|
|
3106
|
+
};
|
|
3107
|
+
const config = node.config;
|
|
3857
3108
|
return {
|
|
3858
3109
|
nodeId: node.id,
|
|
3859
3110
|
path,
|
|
3860
3111
|
bodyType: config.bodyType ?? 'object',
|
|
3861
|
-
inputSchema: Array.isArray(config.inputSchema) ? config.inputSchema : []
|
|
3862
|
-
...endpointAuth(config),
|
|
3863
|
-
runAs: config.runAs ?? 'caller',
|
|
3864
|
-
isTransactional: config.isTransactional === true,
|
|
3865
|
-
timeoutMs: config.timeoutMs ?? FLOW_LIMITS.DEFAULT_TIMEOUT_MS,
|
|
3866
|
-
rateLimitPerMinute: config.rateLimitPerMinute ?? FLOW_LIMITS.DEFAULT_RATE_LIMIT_PER_MINUTE,
|
|
3867
|
-
apiKey: isStoredApiKey(config.apiKey) ? config.apiKey : null
|
|
3112
|
+
inputSchema: Array.isArray(config.inputSchema) ? config.inputSchema : []
|
|
3868
3113
|
};
|
|
3869
3114
|
});
|
|
3870
3115
|
}
|
|
@@ -3872,9 +3117,6 @@ const FLOW_ENDPOINT_PATH_PATTERN = /^[a-z][a-z0-9-]{0,62}$/;
|
|
|
3872
3117
|
const wanted = path?.trim() || null;
|
|
3873
3118
|
return flowEndpoints(flow).find((endpoint)=>endpoint.path === wanted);
|
|
3874
3119
|
}
|
|
3875
|
-
/** The Request step a run starts at: by its id, or the one on the flow's own URL when none is named. */ function startEndpoint(flow, nodeId) {
|
|
3876
|
-
return nodeId ? flowEndpoints(flow).find((endpoint)=>endpoint.nodeId === nodeId) : findEndpoint(flow);
|
|
3877
|
-
}
|
|
3878
3120
|
/** Output ports a node of this type can have (a `respond` node ends the flow: none). */ function portsOf(node) {
|
|
3879
3121
|
switch(node.type){
|
|
3880
3122
|
case 'condition':
|
|
@@ -3893,7 +3135,6 @@ const FLOW_ENDPOINT_PATH_PATTERN = /^[a-z][a-z0-9-]{0,62}$/;
|
|
|
3893
3135
|
'done'
|
|
3894
3136
|
];
|
|
3895
3137
|
case 'permission_check':
|
|
3896
|
-
case 'company_branch_check':
|
|
3897
3138
|
return node.config.onDenied === 'branch' ? [
|
|
3898
3139
|
'allowed',
|
|
3899
3140
|
'denied'
|
|
@@ -3918,35 +3159,23 @@ const FLOW_ENDPOINT_PATH_PATTERN = /^[a-z][a-z0-9-]{0,62}$/;
|
|
|
3918
3159
|
}
|
|
3919
3160
|
|
|
3920
3161
|
__webpack_require__.d(__webpack_exports__, {
|
|
3921
|
-
IE: () => (startEndpoint),
|
|
3922
3162
|
Xr: () => (flowEndpoints),
|
|
3923
3163
|
a5: () => (portsOf),
|
|
3924
3164
|
um: () => (triggerPath),
|
|
3925
|
-
vS: () => (findEndpoint)
|
|
3926
|
-
xA: () => (isStoredApiKey)
|
|
3165
|
+
vS: () => (findEndpoint)
|
|
3927
3166
|
}, {
|
|
3928
3167
|
At: NON_CONTINUABLE_NODE_TYPES,
|
|
3929
|
-
B9: FLOW_EMAIL_TARGETS,
|
|
3930
3168
|
Dn: RECORD_WRITE_TARGETS,
|
|
3931
|
-
E2: FLOW_ID_PATTERN,
|
|
3932
|
-
FU: FLOW_EMAIL_FORMATS,
|
|
3933
|
-
KF: FLOW_MESSAGE_SERVICES,
|
|
3934
|
-
LG: FLOW_NOTIFICATION_TYPES,
|
|
3935
3169
|
Or: FLOW_LIMITS,
|
|
3936
3170
|
Q7: FLOW_INPUT_TYPES,
|
|
3937
|
-
SE: isMessageNode,
|
|
3938
3171
|
Y3: FLOW_BODY_TYPES,
|
|
3939
3172
|
YD: FLOW_SLUG_PATTERN,
|
|
3940
3173
|
YO: FLOW_ENDPOINT_PATH_PATTERN,
|
|
3941
|
-
as: FLOW_NOTIFICATION_TARGETS,
|
|
3942
|
-
d7: KEYLESS_AUTH_MODES,
|
|
3943
3174
|
dA: nodeLabel,
|
|
3944
3175
|
fO: FLOW_AUTH_MODES,
|
|
3945
|
-
fP: isFunctionFlow,
|
|
3946
3176
|
fZ: FLOW_INPUT_NAME_PATTERN,
|
|
3947
3177
|
gl: FLOW_RUN_AS,
|
|
3948
3178
|
q2: FLOW_NODE_TYPES,
|
|
3949
|
-
v1: FLOW_EMAIL_MODES,
|
|
3950
3179
|
z6: FLOW_NODE_ID_PATTERN
|
|
3951
3180
|
});
|
|
3952
3181
|
|
|
@@ -3957,8 +3186,6 @@ const SENSITIVE_KEY = /pass(word)?|secret|token|authorization|api[-_]?key|cookie
|
|
|
3957
3186
|
/** Copy of `value` with the content of sensitive-looking keys replaced, safe to store in a log. */ function redactSensitive(value, depth = 0) {
|
|
3958
3187
|
if (depth > 8) return '[deep]';
|
|
3959
3188
|
if (Array.isArray(value)) return value.slice(0, 100).map((v)=>redactSensitive(v, depth + 1));
|
|
3960
|
-
// Dates (and anything else with its own JSON form) have no own keys: walked as objects they would log as `{}`.
|
|
3961
|
-
if (value && typeof value.toJSON === 'function') return redactSensitive(value.toJSON(), depth + 1);
|
|
3962
3189
|
if (value && typeof value === 'object') {
|
|
3963
3190
|
const out = {};
|
|
3964
3191
|
for (const [key, item] of Object.entries(value)){
|
|
@@ -4613,61 +3840,54 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
4613
3840
|
|
|
4614
3841
|
|
|
4615
3842
|
},
|
|
4616
|
-
|
|
3843
|
+
8888(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
4617
3844
|
|
|
4618
3845
|
// EXPORTS
|
|
4619
3846
|
__webpack_require__.d(__webpack_exports__, {
|
|
4620
|
-
|
|
4621
|
-
Er: () => (/* binding */ defaultFlowPermissionCode),
|
|
4622
|
-
YW: () => (/* binding */ flowNotFound),
|
|
4623
|
-
HF: () => (/* binding */ isPublished),
|
|
4624
|
-
eY: () => (/* binding */ snapshotOf),
|
|
4625
|
-
RK: () => (/* binding */ toFlowSettings),
|
|
4626
|
-
lw: () => (/* binding */ workingCopy)
|
|
3847
|
+
T: () => (/* binding */ FlowApiKeyService)
|
|
4627
3848
|
});
|
|
4628
3849
|
|
|
4629
|
-
// EXTERNAL MODULE: external "@flusys/nestjs-shared"
|
|
4630
|
-
var nestjs_shared_ = __webpack_require__(3422);
|
|
4631
|
-
// EXTERNAL MODULE: external "@flusys/nestjs-shared/classes"
|
|
4632
|
-
var classes_ = __webpack_require__(6937);
|
|
4633
|
-
// EXTERNAL MODULE: external "@flusys/nestjs-shared/interfaces"
|
|
4634
|
-
var interfaces_ = __webpack_require__(5103);
|
|
4635
|
-
// EXTERNAL MODULE: external "@flusys/nestjs-shared/modules"
|
|
4636
|
-
var modules_ = __webpack_require__(1236);
|
|
4637
3850
|
// EXTERNAL MODULE: external "@nestjs/common"
|
|
4638
3851
|
var common_ = __webpack_require__(6157);
|
|
4639
3852
|
// EXTERNAL MODULE: external "typeorm"
|
|
4640
3853
|
var external_typeorm_ = __webpack_require__(7158);
|
|
4641
|
-
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/config/event-actions.ts
|
|
4642
|
-
var event_actions = __webpack_require__(982);
|
|
4643
3854
|
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/config/message-keys.ts
|
|
4644
3855
|
var message_keys = __webpack_require__(5732);
|
|
4645
|
-
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/entities/
|
|
4646
|
-
var
|
|
3856
|
+
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/entities/flow-api-key.entity.ts
|
|
3857
|
+
var flow_api_key_entity = __webpack_require__(201);
|
|
3858
|
+
// EXTERNAL MODULE: external "node:crypto"
|
|
3859
|
+
var external_node_crypto_ = __webpack_require__(2561);
|
|
3860
|
+
;// CONCATENATED MODULE: ./projects/nestjs-entity-builder/src/flow-engine/flow-api-key.ts
|
|
3861
|
+
|
|
3862
|
+
const API_KEY_PREFIX_LENGTH = 11; // "fk_" + 8 hex
|
|
3863
|
+
/** A new key: `fk_<8 hex>_<32 hex>`. Shown once; only its hash is stored. */ function generateApiKey() {
|
|
3864
|
+
const key = `fk_${(0,external_node_crypto_.randomBytes)(4).toString('hex')}_${(0,external_node_crypto_.randomBytes)(16).toString('hex')}`;
|
|
3865
|
+
return {
|
|
3866
|
+
key,
|
|
3867
|
+
prefix: apiKeyPrefix(key),
|
|
3868
|
+
hash: hashApiKey(key)
|
|
3869
|
+
};
|
|
3870
|
+
}
|
|
3871
|
+
const hashApiKey = (key)=>(0,external_node_crypto_.createHash)('sha256').update(key).digest('hex');
|
|
3872
|
+
const apiKeyPrefix = (key)=>key.slice(0, API_KEY_PREFIX_LENGTH);
|
|
3873
|
+
function looksLikeApiKey(key) {
|
|
3874
|
+
return typeof key === 'string' && /^fk_[0-9a-f]{8}_[0-9a-f]{32}$/.test(key);
|
|
3875
|
+
}
|
|
3876
|
+
/** Constant-time comparison of a presented key against a stored hash. */ function apiKeyMatches(presented, storedHash) {
|
|
3877
|
+
const a = Buffer.from(hashApiKey(presented), 'hex');
|
|
3878
|
+
const b = Buffer.from(storedHash, 'hex');
|
|
3879
|
+
return a.length === b.length && (0,external_node_crypto_.timingSafeEqual)(a, b);
|
|
3880
|
+
}
|
|
3881
|
+
|
|
4647
3882
|
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/entities/flow-definition.entity.ts
|
|
4648
3883
|
var flow_definition_entity = __webpack_require__(3770);
|
|
4649
|
-
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/
|
|
4650
|
-
var
|
|
4651
|
-
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/flow-engine/flow-api-key.ts
|
|
4652
|
-
var flow_api_key = __webpack_require__(4816);
|
|
4653
|
-
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/flow-engine/flow-graph.validator.ts
|
|
4654
|
-
var flow_graph_validator = __webpack_require__(3186);
|
|
4655
|
-
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/flow-engine/flow.types.ts
|
|
4656
|
-
var flow_types = __webpack_require__(6256);
|
|
4657
|
-
;// CONCATENATED MODULE: ./projects/nestjs-entity-builder/src/interfaces/flow-definition.interface.ts
|
|
4658
|
-
/** What a version holds and a draft edits: everything about a flow but its identity. */ const FLOW_VERSIONED_FIELDS = [
|
|
4659
|
-
'name',
|
|
4660
|
-
'slug',
|
|
4661
|
-
'description',
|
|
4662
|
-
'isActive',
|
|
4663
|
-
'retainExecutions',
|
|
4664
|
-
'nodes',
|
|
4665
|
-
'edges'
|
|
4666
|
-
];
|
|
4667
|
-
|
|
3884
|
+
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/rule-engine/rule-values.ts
|
|
3885
|
+
var rule_values = __webpack_require__(6622);
|
|
4668
3886
|
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/services/entity-builder-datasource.provider.ts
|
|
4669
3887
|
var entity_builder_datasource_provider = __webpack_require__(424);
|
|
4670
|
-
|
|
3888
|
+
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/services/flow-definition.service.ts
|
|
3889
|
+
var flow_definition_service = __webpack_require__(5229);
|
|
3890
|
+
;// CONCATENATED MODULE: ./projects/nestjs-entity-builder/src/services/flow-api-key.service.ts
|
|
4671
3891
|
function _ts_decorate(decorators, target, key, desc) {
|
|
4672
3892
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4673
3893
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -4700,6 +3920,195 @@ function _ts_param(paramIndex, decorator) {
|
|
|
4700
3920
|
|
|
4701
3921
|
|
|
4702
3922
|
|
|
3923
|
+
const TOUCH_INTERVAL_MS = 60_000;
|
|
3924
|
+
class FlowApiKeyService {
|
|
3925
|
+
provider;
|
|
3926
|
+
constructor(provider){
|
|
3927
|
+
this.provider = provider;
|
|
3928
|
+
}
|
|
3929
|
+
async repo() {
|
|
3930
|
+
return this.provider.getRepository(flow_api_key_entity/* .FlowApiKey */.S);
|
|
3931
|
+
}
|
|
3932
|
+
async assertFlowExists(flowId) {
|
|
3933
|
+
const flow = await (await this.provider.getRepository(flow_definition_entity/* .FlowDefinition */.G)).findOne({
|
|
3934
|
+
where: {
|
|
3935
|
+
id: flowId
|
|
3936
|
+
},
|
|
3937
|
+
select: {
|
|
3938
|
+
id: true
|
|
3939
|
+
}
|
|
3940
|
+
});
|
|
3941
|
+
if (!flow) throw (0,flow_definition_service/* .flowNotFound */.YW)();
|
|
3942
|
+
}
|
|
3943
|
+
async findKey(id) {
|
|
3944
|
+
const key = await (await this.repo()).findOne({
|
|
3945
|
+
where: {
|
|
3946
|
+
id
|
|
3947
|
+
}
|
|
3948
|
+
});
|
|
3949
|
+
if (!key) throw new common_.NotFoundException({
|
|
3950
|
+
message: 'API key not found.',
|
|
3951
|
+
messageKey: message_keys/* .FLOW_MESSAGES.API_KEY_NOT_FOUND */.wu.API_KEY_NOT_FOUND
|
|
3952
|
+
});
|
|
3953
|
+
await this.assertFlowExists(key.flowId);
|
|
3954
|
+
return key;
|
|
3955
|
+
}
|
|
3956
|
+
/** The plain key is returned here and never again. */ async create(flowId, name, expiresAt, user) {
|
|
3957
|
+
const expiry = expiresAt ? (0,rule_values/* .parseDateText */.hz)(expiresAt) : null;
|
|
3958
|
+
if (expiry !== null && !(expiry > Date.now())) {
|
|
3959
|
+
throw new common_.BadRequestException({
|
|
3960
|
+
message: 'The expiry date of an API key must be in the future.',
|
|
3961
|
+
messageKey: message_keys/* .FLOW_MESSAGES.API_KEY_EXPIRY_IN_PAST */.wu.API_KEY_EXPIRY_IN_PAST
|
|
3962
|
+
});
|
|
3963
|
+
}
|
|
3964
|
+
await this.assertFlowExists(flowId);
|
|
3965
|
+
const { key, prefix, hash } = generateApiKey();
|
|
3966
|
+
const repo = await this.repo();
|
|
3967
|
+
const saved = await repo.save(repo.create({
|
|
3968
|
+
flowId,
|
|
3969
|
+
name,
|
|
3970
|
+
keyPrefix: prefix,
|
|
3971
|
+
keyHash: hash,
|
|
3972
|
+
isActive: true,
|
|
3973
|
+
expiresAt: expiry === null ? null : new Date(expiry),
|
|
3974
|
+
lastUsedAt: null,
|
|
3975
|
+
createdById: user?.id ?? null
|
|
3976
|
+
}));
|
|
3977
|
+
return {
|
|
3978
|
+
key,
|
|
3979
|
+
info: this.info(saved)
|
|
3980
|
+
};
|
|
3981
|
+
}
|
|
3982
|
+
async list(flowId) {
|
|
3983
|
+
await this.assertFlowExists(flowId);
|
|
3984
|
+
const rows = await (await this.repo()).find({
|
|
3985
|
+
where: {
|
|
3986
|
+
flowId
|
|
3987
|
+
},
|
|
3988
|
+
order: {
|
|
3989
|
+
createdAt: 'DESC'
|
|
3990
|
+
}
|
|
3991
|
+
});
|
|
3992
|
+
return rows.map((r)=>this.info(r));
|
|
3993
|
+
}
|
|
3994
|
+
async revoke(id) {
|
|
3995
|
+
const key = await this.findKey(id);
|
|
3996
|
+
await (await this.repo()).update({
|
|
3997
|
+
id: key.id
|
|
3998
|
+
}, {
|
|
3999
|
+
isActive: false
|
|
4000
|
+
});
|
|
4001
|
+
}
|
|
4002
|
+
async remove(id) {
|
|
4003
|
+
const key = await this.findKey(id);
|
|
4004
|
+
await (await this.repo()).softDelete({
|
|
4005
|
+
id: key.id
|
|
4006
|
+
});
|
|
4007
|
+
}
|
|
4008
|
+
/**
|
|
4009
|
+
* Checks `presented` against the unrevoked keys of this flow. Only the flow access guard calls
|
|
4010
|
+
* this, and only while the flow's authMode is `api_key`; revoking works in any authMode.
|
|
4011
|
+
*/ async verify(flowId, presented) {
|
|
4012
|
+
if (!looksLikeApiKey(presented)) return 'invalid';
|
|
4013
|
+
const repo = await this.repo();
|
|
4014
|
+
const candidates = await repo.find({
|
|
4015
|
+
where: {
|
|
4016
|
+
flowId,
|
|
4017
|
+
keyPrefix: apiKeyPrefix(presented),
|
|
4018
|
+
isActive: true,
|
|
4019
|
+
deletedAt: (0,external_typeorm_.IsNull)()
|
|
4020
|
+
},
|
|
4021
|
+
select: {
|
|
4022
|
+
id: true,
|
|
4023
|
+
keyHash: true,
|
|
4024
|
+
expiresAt: true,
|
|
4025
|
+
lastUsedAt: true
|
|
4026
|
+
}
|
|
4027
|
+
});
|
|
4028
|
+
const match = candidates.find((c)=>apiKeyMatches(presented, c.keyHash));
|
|
4029
|
+
if (!match) return 'invalid';
|
|
4030
|
+
if (isExpired(match.expiresAt)) return 'expired';
|
|
4031
|
+
if (!match.lastUsedAt || Date.now() - match.lastUsedAt.getTime() > TOUCH_INTERVAL_MS) {
|
|
4032
|
+
await repo.update({
|
|
4033
|
+
id: match.id
|
|
4034
|
+
}, {
|
|
4035
|
+
lastUsedAt: new Date()
|
|
4036
|
+
});
|
|
4037
|
+
}
|
|
4038
|
+
return 'valid';
|
|
4039
|
+
}
|
|
4040
|
+
info(row) {
|
|
4041
|
+
const status = !row.isActive ? 'revoked' : isExpired(row.expiresAt) ? 'expired' : 'active';
|
|
4042
|
+
return {
|
|
4043
|
+
id: row.id,
|
|
4044
|
+
flowId: row.flowId,
|
|
4045
|
+
name: row.name,
|
|
4046
|
+
keyPrefix: row.keyPrefix,
|
|
4047
|
+
isActive: row.isActive,
|
|
4048
|
+
status,
|
|
4049
|
+
expiresAt: row.expiresAt,
|
|
4050
|
+
lastUsedAt: row.lastUsedAt,
|
|
4051
|
+
createdAt: row.createdAt
|
|
4052
|
+
};
|
|
4053
|
+
}
|
|
4054
|
+
}
|
|
4055
|
+
FlowApiKeyService = _ts_decorate([
|
|
4056
|
+
(0,common_.Injectable)({
|
|
4057
|
+
scope: common_.Scope.REQUEST
|
|
4058
|
+
}),
|
|
4059
|
+
_ts_param(0, (0,common_.Inject)(entity_builder_datasource_provider/* .EntityBuilderDataSourceProvider */.D)),
|
|
4060
|
+
_ts_metadata("design:type", Function),
|
|
4061
|
+
_ts_metadata("design:paramtypes", [
|
|
4062
|
+
typeof entity_builder_datasource_provider/* .EntityBuilderDataSourceProvider */.D === "undefined" ? Object : entity_builder_datasource_provider/* .EntityBuilderDataSourceProvider */.D
|
|
4063
|
+
])
|
|
4064
|
+
], FlowApiKeyService);
|
|
4065
|
+
function isExpired(expiresAt) {
|
|
4066
|
+
return !!expiresAt && expiresAt.getTime() <= Date.now();
|
|
4067
|
+
}
|
|
4068
|
+
|
|
4069
|
+
|
|
4070
|
+
},
|
|
4071
|
+
5229(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
4072
|
+
/* import */ var _flusys_nestjs_shared__rspack_import_0 = __webpack_require__(3422);
|
|
4073
|
+
/* import */ var _flusys_nestjs_shared_classes__rspack_import_1 = __webpack_require__(6937);
|
|
4074
|
+
/* import */ var _flusys_nestjs_shared_modules__rspack_import_2 = __webpack_require__(1236);
|
|
4075
|
+
/* import */ var _nestjs_common__rspack_import_3 = __webpack_require__(6157);
|
|
4076
|
+
/* import */ var typeorm__rspack_import_4 = __webpack_require__(7158);
|
|
4077
|
+
/* import */ var _config_event_actions_js__rspack_import_11 = __webpack_require__(982);
|
|
4078
|
+
/* import */ var _config_message_keys_js__rspack_import_10 = __webpack_require__(5732);
|
|
4079
|
+
/* import */ var _entities_entity_definition_entity_js__rspack_import_5 = __webpack_require__(3189);
|
|
4080
|
+
/* import */ var _entities_flow_definition_entity_js__rspack_import_6 = __webpack_require__(3770);
|
|
4081
|
+
/* import */ var _flow_engine_flow_graph_validator_js__rspack_import_7 = __webpack_require__(3186);
|
|
4082
|
+
/* import */ var _flow_engine_flow_types_js__rspack_import_8 = __webpack_require__(6256);
|
|
4083
|
+
/* import */ var _entity_builder_datasource_provider_js__rspack_import_9 = __webpack_require__(424);
|
|
4084
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
4085
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4086
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
4087
|
+
r = Reflect.decorate(decorators, target, key, desc);
|
|
4088
|
+
} else {
|
|
4089
|
+
for(var i = decorators.length - 1; i >= 0; i--){
|
|
4090
|
+
if (d = decorators[i]) {
|
|
4091
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
4092
|
+
}
|
|
4093
|
+
}
|
|
4094
|
+
}
|
|
4095
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
4096
|
+
}
|
|
4097
|
+
function _ts_metadata(metadataKey, metadataValue) {
|
|
4098
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") {
|
|
4099
|
+
return Reflect.metadata(metadataKey, metadataValue);
|
|
4100
|
+
}
|
|
4101
|
+
}
|
|
4102
|
+
function _ts_param(paramIndex, decorator) {
|
|
4103
|
+
return function(target, key) {
|
|
4104
|
+
decorator(target, key, paramIndex);
|
|
4105
|
+
};
|
|
4106
|
+
}
|
|
4107
|
+
|
|
4108
|
+
|
|
4109
|
+
|
|
4110
|
+
|
|
4111
|
+
|
|
4703
4112
|
|
|
4704
4113
|
|
|
4705
4114
|
|
|
@@ -4708,44 +4117,34 @@ function _ts_param(paramIndex, decorator) {
|
|
|
4708
4117
|
|
|
4709
4118
|
|
|
4710
4119
|
const defaultFlowPermissionCode = (slug)=>`entity_builder.flow.${slug}.execute`;
|
|
4711
|
-
const flowNotFound = ()=>new
|
|
4120
|
+
const flowNotFound = ()=>new _nestjs_common__rspack_import_3.NotFoundException({
|
|
4712
4121
|
message: 'Flow not found.',
|
|
4713
|
-
messageKey:
|
|
4714
|
-
});
|
|
4715
|
-
/** A flow that has been published at least once: its columns are what callers run. */ const isPublished = (flow)=>flow.version > 0;
|
|
4716
|
-
/** The versioned part of a flow (or of a draft), in a fixed key order so two snapshots compare as text. */ function snapshotOf(source) {
|
|
4717
|
-
return Object.fromEntries(FLOW_VERSIONED_FIELDS.filter((key)=>source[key] !== undefined).map((key)=>[
|
|
4718
|
-
key,
|
|
4719
|
-
source[key]
|
|
4720
|
-
]));
|
|
4721
|
-
}
|
|
4722
|
-
const sameSnapshot = (a, b)=>JSON.stringify(a) === JSON.stringify(b);
|
|
4723
|
-
/** What the designer edits: the saved draft, or the published flow when there is none. */ const workingCopy = (flow)=>({
|
|
4724
|
-
...snapshotOf(flow),
|
|
4725
|
-
...flow.draft
|
|
4122
|
+
messageKey: _config_message_keys_js__rspack_import_10/* .FLOW_MESSAGES.NOT_FOUND */.wu.NOT_FOUND
|
|
4726
4123
|
});
|
|
4727
|
-
/**
|
|
4124
|
+
/** Fills the defaults a flow definition gets when a field is left out. */ function toFlowSettings(dto) {
|
|
4728
4125
|
return {
|
|
4729
4126
|
slug: dto.slug,
|
|
4127
|
+
authMode: dto.authMode ?? 'jwt',
|
|
4128
|
+
runAs: dto.runAs ?? 'caller',
|
|
4129
|
+
isTransactional: dto.isTransactional ?? false,
|
|
4130
|
+
bodyType: dto.bodyType ?? 'object',
|
|
4131
|
+
inputSchema: dto.inputSchema ?? [],
|
|
4730
4132
|
nodes: dto.nodes ?? [],
|
|
4731
|
-
edges: dto.edges ?? []
|
|
4133
|
+
edges: dto.edges ?? [],
|
|
4134
|
+
timeoutMs: dto.timeoutMs ?? _flow_engine_flow_types_js__rspack_import_8/* .FLOW_LIMITS.DEFAULT_TIMEOUT_MS */.Or.DEFAULT_TIMEOUT_MS
|
|
4732
4135
|
};
|
|
4733
4136
|
}
|
|
4734
|
-
|
|
4735
|
-
class FlowDefinitionService extends classes_.ApiService {
|
|
4137
|
+
class FlowDefinitionService extends _flusys_nestjs_shared_classes__rspack_import_1.ApiService {
|
|
4736
4138
|
cacheManager;
|
|
4737
4139
|
utilsService;
|
|
4738
4140
|
provider;
|
|
4739
4141
|
permissionCache;
|
|
4740
4142
|
actionRegistry;
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
companyAccess;
|
|
4744
|
-
constructor(cacheManager, utilsService, provider, permissionCache, actionRegistry, notifications, email, companyAccess){
|
|
4745
|
-
super(event_actions/* .ENTITY_BUILDER_EVENT_ENTITIES.FLOW_DEFINITION */.P.FLOW_DEFINITION, cacheManager, utilsService, FlowDefinitionService.name, true, event_actions/* .ENTITY_BUILDER_EVENT_MODULE */.S, provider, flow_definition_entity/* .FlowDefinition */.G), this.cacheManager = cacheManager, this.utilsService = utilsService, this.provider = provider, this.permissionCache = permissionCache, this.actionRegistry = actionRegistry, this.notifications = notifications, this.email = email, this.companyAccess = companyAccess;
|
|
4143
|
+
constructor(cacheManager, utilsService, provider, permissionCache, actionRegistry){
|
|
4144
|
+
super(_config_event_actions_js__rspack_import_11/* .ENTITY_BUILDER_EVENT_ENTITIES.FLOW_DEFINITION */.P.FLOW_DEFINITION, cacheManager, utilsService, FlowDefinitionService.name, true, _config_event_actions_js__rspack_import_11/* .ENTITY_BUILDER_EVENT_MODULE */.S, provider, _entities_flow_definition_entity_js__rspack_import_6/* .FlowDefinition */.G), this.cacheManager = cacheManager, this.utilsService = utilsService, this.provider = provider, this.permissionCache = permissionCache, this.actionRegistry = actionRegistry;
|
|
4746
4145
|
}
|
|
4747
4146
|
async findOrFail(id) {
|
|
4748
|
-
const flow = await (await this.provider.getRepository(
|
|
4147
|
+
const flow = await (await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_6/* .FlowDefinition */.G)).findOne({
|
|
4749
4148
|
where: {
|
|
4750
4149
|
id
|
|
4751
4150
|
}
|
|
@@ -4753,28 +4152,28 @@ class FlowDefinitionService extends classes_.ApiService {
|
|
|
4753
4152
|
if (!flow) throw flowNotFound();
|
|
4754
4153
|
return flow;
|
|
4755
4154
|
}
|
|
4756
|
-
/** Validation with the real entity and flow lists
|
|
4757
|
-
const entities = await (await this.provider.getRepository(
|
|
4155
|
+
/** Validation with the real entity and flow lists. Returns errors and warnings without throwing. */ async validate(settings) {
|
|
4156
|
+
const entities = await (await this.provider.getRepository(_entities_entity_definition_entity_js__rspack_import_5/* .EntityDefinition */.f)).find({
|
|
4758
4157
|
select: {
|
|
4759
4158
|
code: true
|
|
4760
4159
|
}
|
|
4761
4160
|
});
|
|
4762
|
-
const flows = await (await this.provider.getRepository(
|
|
4763
|
-
return (0,
|
|
4161
|
+
const flows = await (await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_6/* .FlowDefinition */.G)).find();
|
|
4162
|
+
return (0,_flow_engine_flow_graph_validator_js__rspack_import_7/* .validateFlow */.n)(settings, {
|
|
4764
4163
|
knownEntityCodes: new Set(entities.map((e)=>e.code)),
|
|
4765
4164
|
knownFlows: new Map(flows.map((flow)=>[
|
|
4766
4165
|
flow.slug,
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4166
|
+
{
|
|
4167
|
+
isActive: flow.isActive,
|
|
4168
|
+
authMode: flow.authMode,
|
|
4169
|
+
endpoints: (0,_flow_engine_flow_types_js__rspack_import_8/* .flowEndpoints */.Xr)(flow),
|
|
4170
|
+
calls: calledSlugs(flow.nodes)
|
|
4171
|
+
}
|
|
4172
|
+
]))
|
|
4774
4173
|
});
|
|
4775
4174
|
}
|
|
4776
4175
|
/** Names of the other flows whose `call_flow` nodes run `slug`. */ async callersOf(slug, excludeIds) {
|
|
4777
|
-
const flows = await (await this.provider.getRepository(
|
|
4176
|
+
const flows = await (await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_6/* .FlowDefinition */.G)).find({
|
|
4778
4177
|
select: {
|
|
4779
4178
|
id: true,
|
|
4780
4179
|
name: true,
|
|
@@ -4786,83 +4185,20 @@ class FlowDefinitionService extends classes_.ApiService {
|
|
|
4786
4185
|
async assertNotCalled(slug, excludeIds) {
|
|
4787
4186
|
const callers = await this.callersOf(slug, excludeIds);
|
|
4788
4187
|
if (!callers.length) return;
|
|
4789
|
-
throw new
|
|
4188
|
+
throw new _nestjs_common__rspack_import_3.ConflictException({
|
|
4790
4189
|
message: `The flow '${slug}' is called by: ${callers.join(', ')}. Change those flows first.`,
|
|
4791
|
-
messageKey:
|
|
4190
|
+
messageKey: _config_message_keys_js__rspack_import_10/* .FLOW_MESSAGES.CALLED_BY_OTHER_FLOWS */.wu.CALLED_BY_OTHER_FLOWS,
|
|
4792
4191
|
messageVariables: {
|
|
4793
4192
|
slug,
|
|
4794
4193
|
flows: callers.join(', ')
|
|
4795
4194
|
}
|
|
4796
4195
|
});
|
|
4797
4196
|
}
|
|
4798
|
-
/**
|
|
4799
|
-
* Other flows' Call flow steps keep working: the URL name they call is not renamed, the paths they
|
|
4800
|
-
* start at are not dropped, and nothing else they rely on changes under them - access, body,
|
|
4801
|
-
* required inputs, the flow staying on, the call chain staying loop-free and within depth.
|
|
4802
|
-
*/ async assertCallersKept(before, after, live) {
|
|
4803
|
-
if (after.slug !== before.slug) return this.assertNotCalled(before.slug, [
|
|
4804
|
-
before.id
|
|
4805
|
-
]);
|
|
4806
|
-
await this.assertEndpointsNotCalled(before, after);
|
|
4807
|
-
await this.assertCallsStillValid(before, {
|
|
4808
|
-
...after,
|
|
4809
|
-
...live
|
|
4810
|
-
});
|
|
4811
|
-
}
|
|
4812
|
-
/**
|
|
4813
|
-
* Checks each running flow that calls this one, directly or through other flows, against the flows
|
|
4814
|
-
* as they are and as this change leaves them, and refuses the change when it adds a problem. A
|
|
4815
|
-
* caller already broken for another reason does not block it; only what this change breaks does.
|
|
4816
|
-
*/ async assertCallsStillValid(before, after) {
|
|
4817
|
-
const flows = await (await this.provider.getRepository(flow_definition_entity/* .FlowDefinition */.G)).find();
|
|
4818
|
-
const running = flows.filter((flow)=>flow.id !== before.id && flow.isActive && isPublished(flow) && calledSlugs(flow.nodes).length);
|
|
4819
|
-
if (!running.length) return;
|
|
4820
|
-
const now = new Map(flows.map((flow)=>[
|
|
4821
|
-
flow.slug,
|
|
4822
|
-
callableOf(flow)
|
|
4823
|
-
]));
|
|
4824
|
-
const next = new Map(now).set(before.slug, callableOf(after));
|
|
4825
|
-
const broken = [];
|
|
4826
|
-
for (const caller of running){
|
|
4827
|
-
const settings = toFlowSettings(caller);
|
|
4828
|
-
// Counted, not a set: two steps with the same label can share a problem, and only the new one is added.
|
|
4829
|
-
const existing = new Map();
|
|
4830
|
-
for (const problem of (0,flow_graph_validator/* .callProblems */.r7)(settings, before.slug, now)){
|
|
4831
|
-
const key = JSON.stringify(problem);
|
|
4832
|
-
existing.set(key, (existing.get(key) ?? 0) + 1);
|
|
4833
|
-
}
|
|
4834
|
-
const added = (0,flow_graph_validator/* .callProblems */.r7)(settings, before.slug, next).filter((problem)=>{
|
|
4835
|
-
const key = JSON.stringify(problem);
|
|
4836
|
-
const left = existing.get(key) ?? 0;
|
|
4837
|
-
existing.set(key, left - 1);
|
|
4838
|
-
return left <= 0;
|
|
4839
|
-
});
|
|
4840
|
-
if (added.length) broken.push({
|
|
4841
|
-
flow: caller.name,
|
|
4842
|
-
problems: added
|
|
4843
|
-
});
|
|
4844
|
-
}
|
|
4845
|
-
if (!broken.length) return;
|
|
4846
|
-
const names = broken.map((b)=>b.flow).join(', ');
|
|
4847
|
-
throw new common_.ConflictException({
|
|
4848
|
-
message: `This change breaks flows that call '${before.slug}': ${names}. Change those flows first.`,
|
|
4849
|
-
messageKey: message_keys/* .FLOW_MESSAGES.CALLERS_BROKEN */.wu.CALLERS_BROKEN,
|
|
4850
|
-
messageVariables: {
|
|
4851
|
-
slug: before.slug,
|
|
4852
|
-
flows: names
|
|
4853
|
-
},
|
|
4854
|
-
errors: broken.flatMap((b)=>b.problems.map((problem)=>({
|
|
4855
|
-
field: 'flow',
|
|
4856
|
-
flow: b.flow,
|
|
4857
|
-
...problem
|
|
4858
|
-
})))
|
|
4859
|
-
});
|
|
4860
|
-
}
|
|
4861
4197
|
/** A URL other flows' Call flow steps start at cannot be removed or renamed from under them. */ async assertEndpointsNotCalled(before, after) {
|
|
4862
|
-
const kept = new Set((0,
|
|
4863
|
-
const removed = (0,
|
|
4198
|
+
const kept = new Set((0,_flow_engine_flow_types_js__rspack_import_8/* .flowEndpoints */.Xr)(after).map((e)=>e.path));
|
|
4199
|
+
const removed = (0,_flow_engine_flow_types_js__rspack_import_8/* .flowEndpoints */.Xr)(before).map((e)=>e.path).filter((path)=>!kept.has(path));
|
|
4864
4200
|
if (!removed.length) return;
|
|
4865
|
-
const flows = await (await this.provider.getRepository(
|
|
4201
|
+
const flows = await (await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_6/* .FlowDefinition */.G)).find({
|
|
4866
4202
|
select: {
|
|
4867
4203
|
id: true,
|
|
4868
4204
|
name: true,
|
|
@@ -4873,9 +4209,9 @@ class FlowDefinitionService extends classes_.ApiService {
|
|
|
4873
4209
|
const callers = flows.filter((flow)=>flow.id !== before.id && calledTargets(flow.nodes).some((t)=>t.slug === before.slug && t.endpoint === path)).map((flow)=>flow.name);
|
|
4874
4210
|
if (!callers.length) continue;
|
|
4875
4211
|
const url = `api-flows/${before.slug}${path ? `/${path}` : ''}`;
|
|
4876
|
-
throw new
|
|
4212
|
+
throw new _nestjs_common__rspack_import_3.ConflictException({
|
|
4877
4213
|
message: `The URL ${url} is called by: ${callers.join(', ')}. Change those flows first.`,
|
|
4878
|
-
messageKey:
|
|
4214
|
+
messageKey: _config_message_keys_js__rspack_import_10/* .FLOW_MESSAGES.ENDPOINT_CALLED_BY_OTHER_FLOWS */.wu.ENDPOINT_CALLED_BY_OTHER_FLOWS,
|
|
4879
4215
|
messageVariables: {
|
|
4880
4216
|
url,
|
|
4881
4217
|
flows: callers.join(', ')
|
|
@@ -4886,9 +4222,9 @@ class FlowDefinitionService extends classes_.ApiService {
|
|
|
4886
4222
|
async assertSaveable(settings, user, selfId) {
|
|
4887
4223
|
const { errors, warnings } = await this.validate(settings);
|
|
4888
4224
|
if (errors.length) {
|
|
4889
|
-
throw new
|
|
4225
|
+
throw new _nestjs_common__rspack_import_3.BadRequestException({
|
|
4890
4226
|
message: 'The flow has problems.',
|
|
4891
|
-
messageKey:
|
|
4227
|
+
messageKey: _config_message_keys_js__rspack_import_10/* .FLOW_MESSAGES.INVALID */.wu.INVALID,
|
|
4892
4228
|
errors: errors.map((error)=>({
|
|
4893
4229
|
field: 'flow',
|
|
4894
4230
|
...error
|
|
@@ -4896,16 +4232,16 @@ class FlowDefinitionService extends classes_.ApiService {
|
|
|
4896
4232
|
warnings
|
|
4897
4233
|
});
|
|
4898
4234
|
}
|
|
4899
|
-
const clash = await (await this.provider.getRepository(
|
|
4235
|
+
const clash = await (await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_6/* .FlowDefinition */.G)).findOne({
|
|
4900
4236
|
where: {
|
|
4901
4237
|
slug: settings.slug
|
|
4902
4238
|
},
|
|
4903
4239
|
withDeleted: true
|
|
4904
4240
|
});
|
|
4905
4241
|
if (clash && clash.id !== selfId) {
|
|
4906
|
-
throw new
|
|
4242
|
+
throw new _nestjs_common__rspack_import_3.ConflictException({
|
|
4907
4243
|
message: `The URL name '${settings.slug}' is already used by another flow.`,
|
|
4908
|
-
messageKey:
|
|
4244
|
+
messageKey: _config_message_keys_js__rspack_import_10/* .FLOW_MESSAGES.SLUG_TAKEN */.wu.SLUG_TAKEN,
|
|
4909
4245
|
messageVariables: {
|
|
4910
4246
|
slug: settings.slug
|
|
4911
4247
|
}
|
|
@@ -4914,21 +4250,21 @@ class FlowDefinitionService extends classes_.ApiService {
|
|
|
4914
4250
|
await this.assertMayAuthor(settings, user);
|
|
4915
4251
|
}
|
|
4916
4252
|
/** The extra permissions a flow needs from whoever writes it: saving it, or test-running it as an unsaved draft. */ async assertMayAuthor(settings, user) {
|
|
4917
|
-
if (
|
|
4918
|
-
if (settings.nodes.some((node)=>node?.type === 'code')) await this.assertHasPermission(user,
|
|
4253
|
+
if (settings.runAs === 'system') await this.assertHasPermission(user, _flusys_nestjs_shared__rspack_import_0.FLOW_DEFINITION_PERMISSIONS.SYSTEM);
|
|
4254
|
+
if (settings.nodes.some((node)=>node?.type === 'code')) await this.assertHasPermission(user, _flusys_nestjs_shared__rspack_import_0.FLOW_DEFINITION_PERMISSIONS.CODE);
|
|
4919
4255
|
}
|
|
4920
4256
|
async assertMayCreate(user) {
|
|
4921
|
-
await this.assertHasPermission(user,
|
|
4257
|
+
await this.assertHasPermission(user, _flusys_nestjs_shared__rspack_import_0.FLOW_DEFINITION_PERMISSIONS.CREATE);
|
|
4922
4258
|
}
|
|
4923
4259
|
/**
|
|
4924
4260
|
* A test run needs what running the flow for real would: the author permissions for its
|
|
4925
4261
|
* run-as and code nodes (a saved flow as much as a draft). A live run also needs what makes it
|
|
4926
|
-
* real - a draft the permission to save it, a permission
|
|
4927
|
-
*/ async assertMayTest(settings,
|
|
4262
|
+
* real - a draft the permission to save it, a permission flow its own execute permission.
|
|
4263
|
+
*/ async assertMayTest(settings, user, run) {
|
|
4928
4264
|
await this.assertMayAuthor(settings, user);
|
|
4929
4265
|
if (run.mode !== 'live') return;
|
|
4930
|
-
if (run.draft) await this.assertHasPermission(user, run.saved ?
|
|
4931
|
-
if (
|
|
4266
|
+
if (run.draft) await this.assertHasPermission(user, run.saved ? _flusys_nestjs_shared__rspack_import_0.FLOW_DEFINITION_PERMISSIONS.UPDATE : _flusys_nestjs_shared__rspack_import_0.FLOW_DEFINITION_PERMISSIONS.CREATE);
|
|
4267
|
+
if (settings.authMode === 'permission') await this.assertHasPermission(user, settings.permissionCode || defaultFlowPermissionCode(settings.slug));
|
|
4932
4268
|
}
|
|
4933
4269
|
assertHasPermission(user, permission) {
|
|
4934
4270
|
return this.permissionCache.assertPermission(user, permission);
|
|
@@ -4938,187 +4274,37 @@ class FlowDefinitionService extends classes_.ApiService {
|
|
|
4938
4274
|
dto
|
|
4939
4275
|
]){
|
|
4940
4276
|
await this.assertSaveable(toFlowSettings(d), user);
|
|
4941
|
-
|
|
4942
|
-
d.
|
|
4277
|
+
// JSON columns have no database default, so leaving the optional settings out must not mean NULL.
|
|
4278
|
+
d.inputSchema ??= [];
|
|
4279
|
+
d.bodyType ??= 'object';
|
|
4280
|
+
d.authMode ??= 'jwt';
|
|
4281
|
+
d.runAs ??= 'caller';
|
|
4943
4282
|
}
|
|
4944
4283
|
}
|
|
4945
|
-
|
|
4946
|
-
* Checked against what the save produces: the draft of a published flow, the flow itself before its
|
|
4947
|
-
* first publish. An unpublished flow changes in place, so its callers are protected now, not at publish.
|
|
4948
|
-
*/ async beforeUpdateOperation(dto, user, _qr) {
|
|
4284
|
+
async beforeUpdateOperation(dto, user, _qr) {
|
|
4949
4285
|
for (const d of Array.isArray(dto) ? dto : [
|
|
4950
4286
|
dto
|
|
4951
4287
|
]){
|
|
4952
4288
|
const existing = await this.findOrFail(d.id);
|
|
4953
|
-
const
|
|
4954
|
-
...
|
|
4289
|
+
const merged = toFlowSettings({
|
|
4290
|
+
...existing,
|
|
4955
4291
|
...stripUndefined(d)
|
|
4956
4292
|
});
|
|
4957
|
-
await this.assertSaveable(
|
|
4958
|
-
if (
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
}
|
|
4964
|
-
}
|
|
4965
|
-
/** A published flow keeps running as published: the edits go to its draft (none when they match what is live). */ async convertSingleDtoToEntity(dto, user) {
|
|
4966
|
-
const id = dto.id;
|
|
4967
|
-
if (!id) return super.convertSingleDtoToEntity(dto, user);
|
|
4968
|
-
const existing = await this.findOrFail(id);
|
|
4969
|
-
if (!isPublished(existing)) return super.convertSingleDtoToEntity(dto, user);
|
|
4970
|
-
const draft = snapshotOf({
|
|
4971
|
-
...workingCopy(existing),
|
|
4972
|
-
...stripUndefined(dto)
|
|
4973
|
-
});
|
|
4974
|
-
existing.draft = sameSnapshot(draft, snapshotOf(existing)) ? null : draft;
|
|
4975
|
-
return existing;
|
|
4976
|
-
}
|
|
4977
|
-
/**
|
|
4978
|
-
* Makes the draft (or, before the first publish, the flow as saved) what callers run, as the next
|
|
4979
|
-
* version. It is checked like a save, plus what only going live can break: other flows calling
|
|
4980
|
-
* this one by a URL name or path it no longer has.
|
|
4981
|
-
*/ async publish(id, note, user) {
|
|
4982
|
-
const existing = await this.findOrFail(id);
|
|
4983
|
-
const published = isPublished(existing);
|
|
4984
|
-
if (published && !existing.draft) throw new common_.BadRequestException({
|
|
4985
|
-
message: 'There are no changes to publish.',
|
|
4986
|
-
messageKey: message_keys/* .FLOW_MESSAGES.NOTHING_TO_PUBLISH */.wu.NOTHING_TO_PUBLISH
|
|
4987
|
-
});
|
|
4988
|
-
const next = workingCopy(existing);
|
|
4989
|
-
const settings = toFlowSettings(next);
|
|
4990
|
-
await this.assertSaveable(settings, user, existing.id);
|
|
4991
|
-
await this.assertCallersKept(existing, settings, {
|
|
4992
|
-
isActive: next.isActive ?? existing.isActive,
|
|
4993
|
-
version: existing.version + 1
|
|
4994
|
-
});
|
|
4995
|
-
const qr = await this.provider.getQueryRunner();
|
|
4996
|
-
try {
|
|
4997
|
-
await qr.connect();
|
|
4998
|
-
await qr.startTransaction();
|
|
4999
|
-
const versions = qr.manager.getRepository(flow_version_entity/* .FlowVersion */.p);
|
|
5000
|
-
// A version that went live before versions were kept is recorded now, so it can still be restored.
|
|
5001
|
-
if (published && !await versions.exists({
|
|
5002
|
-
where: {
|
|
5003
|
-
flowId: existing.id,
|
|
5004
|
-
version: existing.version
|
|
5005
|
-
}
|
|
5006
|
-
})) {
|
|
5007
|
-
await versions.save(versions.create({
|
|
5008
|
-
flowId: existing.id,
|
|
5009
|
-
version: existing.version,
|
|
5010
|
-
definition: snapshotOf(existing),
|
|
5011
|
-
note: null,
|
|
5012
|
-
publishedAt: null,
|
|
5013
|
-
publishedById: null
|
|
5014
|
-
}));
|
|
5015
|
-
}
|
|
5016
|
-
Object.assign(existing, next, {
|
|
5017
|
-
draft: null,
|
|
5018
|
-
version: existing.version + 1,
|
|
5019
|
-
updatedById: user?.id ?? null
|
|
5020
|
-
});
|
|
5021
|
-
await qr.manager.getRepository(flow_definition_entity/* .FlowDefinition */.G).save(existing);
|
|
5022
|
-
await versions.save(versions.create({
|
|
5023
|
-
flowId: existing.id,
|
|
5024
|
-
version: existing.version,
|
|
5025
|
-
definition: next,
|
|
5026
|
-
note: note?.trim() || null,
|
|
5027
|
-
publishedAt: new Date(),
|
|
5028
|
-
publishedById: user?.id ?? null
|
|
5029
|
-
}));
|
|
5030
|
-
await qr.commitTransaction();
|
|
5031
|
-
} catch (error) {
|
|
5032
|
-
await qr.rollbackTransaction().catch(()=>undefined);
|
|
5033
|
-
throw error;
|
|
5034
|
-
} finally{
|
|
5035
|
-
await qr.release().catch(()=>undefined);
|
|
4293
|
+
await this.assertSaveable(merged, user, existing.id);
|
|
4294
|
+
if (merged.slug !== existing.slug) await this.assertNotCalled(existing.slug, [
|
|
4295
|
+
existing.id
|
|
4296
|
+
]);
|
|
4297
|
+
else await this.assertEndpointsNotCalled(existing, merged);
|
|
4298
|
+
d.version = existing.version + 1;
|
|
5036
4299
|
}
|
|
5037
|
-
await this.clearCaches(existing);
|
|
5038
|
-
await this.provisionPermissions([
|
|
5039
|
-
existing
|
|
5040
|
-
]);
|
|
5041
|
-
return existing;
|
|
5042
|
-
}
|
|
5043
|
-
/** Newest first, without the definitions (`getVersion` returns one in full). */ async listVersions(flowId) {
|
|
5044
|
-
await this.findOrFail(flowId);
|
|
5045
|
-
return (await this.provider.getRepository(flow_version_entity/* .FlowVersion */.p)).find({
|
|
5046
|
-
where: {
|
|
5047
|
-
flowId
|
|
5048
|
-
},
|
|
5049
|
-
order: {
|
|
5050
|
-
version: 'DESC'
|
|
5051
|
-
},
|
|
5052
|
-
select: {
|
|
5053
|
-
id: true,
|
|
5054
|
-
flowId: true,
|
|
5055
|
-
version: true,
|
|
5056
|
-
note: true,
|
|
5057
|
-
publishedAt: true,
|
|
5058
|
-
publishedById: true
|
|
5059
|
-
}
|
|
5060
|
-
});
|
|
5061
|
-
}
|
|
5062
|
-
async getVersion(flowId, version) {
|
|
5063
|
-
const row = await (await this.provider.getRepository(flow_version_entity/* .FlowVersion */.p)).findOne({
|
|
5064
|
-
where: {
|
|
5065
|
-
flowId,
|
|
5066
|
-
version
|
|
5067
|
-
}
|
|
5068
|
-
});
|
|
5069
|
-
if (!row) throw new common_.NotFoundException({
|
|
5070
|
-
message: `Version ${version} of this flow was not found.`,
|
|
5071
|
-
messageKey: message_keys/* .FLOW_MESSAGES.VERSION_NOT_FOUND */.wu.VERSION_NOT_FOUND,
|
|
5072
|
-
messageVariables: {
|
|
5073
|
-
version
|
|
5074
|
-
}
|
|
5075
|
-
});
|
|
5076
|
-
return row;
|
|
5077
|
-
}
|
|
5078
|
-
/**
|
|
5079
|
-
* Puts an old version back into the draft; callers keep the published flow until it is published
|
|
5080
|
-
* again. Not checked like a save (the entities it names may have changed since), but the author
|
|
5081
|
-
* still needs the permissions its run-as and code steps call for.
|
|
5082
|
-
*/ async restoreVersion(flowId, version, user) {
|
|
5083
|
-
const flow = await this.findOrFail(flowId);
|
|
5084
|
-
const snapshot = snapshotOf((await this.getVersion(flowId, version)).definition);
|
|
5085
|
-
await this.assertMayAuthor(toFlowSettings(snapshot), user);
|
|
5086
|
-
flow.draft = sameSnapshot(snapshot, snapshotOf(flow)) ? null : snapshot;
|
|
5087
|
-
return this.saveDraft(flow, user);
|
|
5088
|
-
}
|
|
5089
|
-
async discardDraft(flowId, user) {
|
|
5090
|
-
const flow = await this.findOrFail(flowId);
|
|
5091
|
-
if (!flow.draft) throw new common_.BadRequestException({
|
|
5092
|
-
message: 'This flow has no unpublished changes.',
|
|
5093
|
-
messageKey: message_keys/* .FLOW_MESSAGES.NO_DRAFT */.wu.NO_DRAFT
|
|
5094
|
-
});
|
|
5095
|
-
flow.draft = null;
|
|
5096
|
-
return this.saveDraft(flow, user);
|
|
5097
|
-
}
|
|
5098
|
-
async saveDraft(flow, user) {
|
|
5099
|
-
await (await this.provider.getRepository(flow_definition_entity/* .FlowDefinition */.G)).update(flow.id, {
|
|
5100
|
-
draft: flow.draft,
|
|
5101
|
-
updatedById: user?.id ?? null
|
|
5102
|
-
});
|
|
5103
|
-
await this.clearCaches(flow);
|
|
5104
|
-
return flow;
|
|
5105
|
-
}
|
|
5106
|
-
async clearCaches(flow) {
|
|
5107
|
-
if (!this.isCacheable) return;
|
|
5108
|
-
await Promise.all([
|
|
5109
|
-
this.clearCacheForAll(),
|
|
5110
|
-
this.clearCacheForId([
|
|
5111
|
-
flow
|
|
5112
|
-
])
|
|
5113
|
-
]);
|
|
5114
4300
|
}
|
|
5115
4301
|
async beforeDeleteOperation(dto, user, _qr) {
|
|
5116
4302
|
const ids = Array.isArray(dto.id) ? dto.id : [
|
|
5117
4303
|
dto.id
|
|
5118
4304
|
];
|
|
5119
|
-
const flows = await (await this.provider.getRepository(
|
|
4305
|
+
const flows = await (await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_6/* .FlowDefinition */.G)).find({
|
|
5120
4306
|
where: {
|
|
5121
|
-
id: (0,
|
|
4307
|
+
id: (0,typeorm__rspack_import_4.In)(ids)
|
|
5122
4308
|
},
|
|
5123
4309
|
withDeleted: true
|
|
5124
4310
|
});
|
|
@@ -5126,50 +4312,39 @@ class FlowDefinitionService extends classes_.ApiService {
|
|
|
5126
4312
|
if (dto.type === 'restore') return;
|
|
5127
4313
|
for (const flow of flows)await this.assertNotCalled(flow.slug, ids);
|
|
5128
4314
|
}
|
|
5129
|
-
|
|
4315
|
+
async afterInsertOperation(entities) {
|
|
4316
|
+
await this.provisionPermissions(entities);
|
|
4317
|
+
}
|
|
4318
|
+
async afterUpdateOperation(entities) {
|
|
4319
|
+
await this.provisionPermissions(entities);
|
|
4320
|
+
}
|
|
4321
|
+
async provisionPermissions(flows) {
|
|
4322
|
+
const needing = flows.filter((f)=>f.authMode === 'permission');
|
|
4323
|
+
if (!needing.length) return;
|
|
5130
4324
|
if (!this.actionRegistry) return;
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
if (endpoint.authMode !== 'permission') continue;
|
|
5135
|
-
const code = endpoint.permissionCode || defaultFlowPermissionCode(flow.slug);
|
|
5136
|
-
if (!actions.has(code)) actions.set(code, endpoint.path ? `Run ${flow.name} (${endpoint.path})` : `Run ${flow.name}`);
|
|
5137
|
-
}
|
|
5138
|
-
}
|
|
5139
|
-
if (actions.size) await this.actionRegistry.registerActions([
|
|
5140
|
-
...actions
|
|
5141
|
-
].map(([code, name])=>({
|
|
5142
|
-
code,
|
|
5143
|
-
name
|
|
4325
|
+
await this.actionRegistry.registerActions(needing.map((f)=>({
|
|
4326
|
+
code: f.permissionCode || defaultFlowPermissionCode(f.slug),
|
|
4327
|
+
name: `Run ${f.name}`
|
|
5144
4328
|
})));
|
|
5145
4329
|
}
|
|
5146
4330
|
}
|
|
5147
4331
|
FlowDefinitionService = _ts_decorate([
|
|
5148
|
-
(0,
|
|
5149
|
-
scope:
|
|
4332
|
+
(0,_nestjs_common__rspack_import_3.Injectable)({
|
|
4333
|
+
scope: _nestjs_common__rspack_import_3.Scope.REQUEST
|
|
5150
4334
|
}),
|
|
5151
|
-
_ts_param(0, (0,
|
|
5152
|
-
_ts_param(1, (0,
|
|
5153
|
-
_ts_param(2, (0,
|
|
5154
|
-
_ts_param(3, (0,
|
|
5155
|
-
_ts_param(4, (0,
|
|
5156
|
-
_ts_param(4, (0,
|
|
5157
|
-
_ts_param(5, (0,common_.Optional)()),
|
|
5158
|
-
_ts_param(5, (0,common_.Inject)(interfaces_.NOTIFICATION_ADAPTER)),
|
|
5159
|
-
_ts_param(6, (0,common_.Optional)()),
|
|
5160
|
-
_ts_param(6, (0,common_.Inject)(interfaces_.EMAIL_ADAPTER)),
|
|
5161
|
-
_ts_param(7, (0,common_.Optional)()),
|
|
5162
|
-
_ts_param(7, (0,common_.Inject)(interfaces_.COMPANY_ACCESS_RESOLVER)),
|
|
4335
|
+
_ts_param(0, (0,_nestjs_common__rspack_import_3.Inject)('CACHE_INSTANCE')),
|
|
4336
|
+
_ts_param(1, (0,_nestjs_common__rspack_import_3.Inject)(_flusys_nestjs_shared_modules__rspack_import_2.UtilsService)),
|
|
4337
|
+
_ts_param(2, (0,_nestjs_common__rspack_import_3.Inject)(_entity_builder_datasource_provider_js__rspack_import_9/* .EntityBuilderDataSourceProvider */.D)),
|
|
4338
|
+
_ts_param(3, (0,_nestjs_common__rspack_import_3.Inject)(_flusys_nestjs_shared_modules__rspack_import_2.SharedPermissionCacheService)),
|
|
4339
|
+
_ts_param(4, (0,_nestjs_common__rspack_import_3.Optional)()),
|
|
4340
|
+
_ts_param(4, (0,_nestjs_common__rspack_import_3.Inject)(_flusys_nestjs_shared__rspack_import_0.PERMISSION_ACTION_REGISTRY)),
|
|
5163
4341
|
_ts_metadata("design:type", Function),
|
|
5164
4342
|
_ts_metadata("design:paramtypes", [
|
|
5165
|
-
typeof
|
|
5166
|
-
typeof
|
|
5167
|
-
typeof
|
|
5168
|
-
typeof
|
|
5169
|
-
typeof IPermissionActionRegistry === "undefined" ? Object : IPermissionActionRegistry
|
|
5170
|
-
typeof INotificationAdapter === "undefined" ? Object : INotificationAdapter,
|
|
5171
|
-
typeof IEmailAdapter === "undefined" ? Object : IEmailAdapter,
|
|
5172
|
-
typeof ICompanyAccessResolver === "undefined" ? Object : ICompanyAccessResolver
|
|
4343
|
+
typeof _flusys_nestjs_shared_classes__rspack_import_1.HybridCache === "undefined" ? Object : _flusys_nestjs_shared_classes__rspack_import_1.HybridCache,
|
|
4344
|
+
typeof _flusys_nestjs_shared_modules__rspack_import_2.UtilsService === "undefined" ? Object : _flusys_nestjs_shared_modules__rspack_import_2.UtilsService,
|
|
4345
|
+
typeof _entity_builder_datasource_provider_js__rspack_import_9/* .EntityBuilderDataSourceProvider */.D === "undefined" ? Object : _entity_builder_datasource_provider_js__rspack_import_9/* .EntityBuilderDataSourceProvider */.D,
|
|
4346
|
+
typeof _flusys_nestjs_shared_modules__rspack_import_2.SharedPermissionCacheService === "undefined" ? Object : _flusys_nestjs_shared_modules__rspack_import_2.SharedPermissionCacheService,
|
|
4347
|
+
typeof IPermissionActionRegistry === "undefined" ? Object : IPermissionActionRegistry
|
|
5173
4348
|
])
|
|
5174
4349
|
], FlowDefinitionService);
|
|
5175
4350
|
/** What the `call_flow` nodes of a flow run: a slug, and the path of the Request step they start at (null: the flow's own URL). */ function calledTargets(nodes) {
|
|
@@ -5181,13 +4356,6 @@ FlowDefinitionService = _ts_decorate([
|
|
|
5181
4356
|
};
|
|
5182
4357
|
});
|
|
5183
4358
|
}
|
|
5184
|
-
/** What a Call flow step checks about a flow: it runs only once published and switched on. */ function callableOf(flow) {
|
|
5185
|
-
return {
|
|
5186
|
-
isActive: flow.isActive && isPublished(flow),
|
|
5187
|
-
endpoints: (0,flow_types/* .flowEndpoints */.Xr)(flow),
|
|
5188
|
-
calls: calledSlugs(flow.nodes)
|
|
5189
|
-
};
|
|
5190
|
-
}
|
|
5191
4359
|
/** Slugs the `call_flow` nodes of a flow run. */ function calledSlugs(nodes) {
|
|
5192
4360
|
return calledTargets(nodes).map((target)=>target.slug);
|
|
5193
4361
|
}
|
|
@@ -5195,6 +4363,14 @@ function stripUndefined(value) {
|
|
|
5195
4363
|
return Object.fromEntries(Object.entries(value).filter(([, v])=>v !== undefined));
|
|
5196
4364
|
}
|
|
5197
4365
|
|
|
4366
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
4367
|
+
RK: () => (toFlowSettings),
|
|
4368
|
+
Tk: () => (FlowDefinitionService)
|
|
4369
|
+
}, {
|
|
4370
|
+
Er: defaultFlowPermissionCode,
|
|
4371
|
+
YW: flowNotFound
|
|
4372
|
+
});
|
|
4373
|
+
|
|
5198
4374
|
|
|
5199
4375
|
},
|
|
5200
4376
|
7810(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
@@ -5252,7 +4428,6 @@ class FlowExecutionService {
|
|
|
5252
4428
|
await repo.save(repo.create({
|
|
5253
4429
|
flowId: entry.flowId,
|
|
5254
4430
|
flowSlug: entry.flowSlug,
|
|
5255
|
-
flowVersion: entry.flowVersion,
|
|
5256
4431
|
status: entry.result.status,
|
|
5257
4432
|
trigger: entry.trigger,
|
|
5258
4433
|
mode: entry.mode,
|
|
@@ -5317,7 +4492,6 @@ class FlowExecutionService {
|
|
|
5317
4492
|
id: true,
|
|
5318
4493
|
flowId: true,
|
|
5319
4494
|
flowSlug: true,
|
|
5320
|
-
flowVersion: true,
|
|
5321
4495
|
status: true,
|
|
5322
4496
|
trigger: true,
|
|
5323
4497
|
mode: true,
|
|
@@ -5376,8 +4550,6 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
5376
4550
|
var classes_ = __webpack_require__(6937);
|
|
5377
4551
|
// EXTERNAL MODULE: external "@flusys/nestjs-shared/exceptions"
|
|
5378
4552
|
var exceptions_ = __webpack_require__(2417);
|
|
5379
|
-
// EXTERNAL MODULE: external "@flusys/nestjs-shared/interfaces"
|
|
5380
|
-
var interfaces_ = __webpack_require__(5103);
|
|
5381
4553
|
// EXTERNAL MODULE: external "@flusys/nestjs-shared/modules"
|
|
5382
4554
|
var modules_ = __webpack_require__(1236);
|
|
5383
4555
|
// EXTERNAL MODULE: external "@nestjs/common"
|
|
@@ -5617,14 +4789,14 @@ const BLOCKED_REQUEST_HEADERS = new Set([
|
|
|
5617
4789
|
});
|
|
5618
4790
|
}
|
|
5619
4791
|
|
|
5620
|
-
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/rule-engine/index.ts +
|
|
5621
|
-
var rule_engine = __webpack_require__(
|
|
4792
|
+
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/rule-engine/index.ts + 2 modules
|
|
4793
|
+
var rule_engine = __webpack_require__(5920);
|
|
5622
4794
|
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/services/entity-builder-config.service.ts
|
|
5623
4795
|
var entity_builder_config_service = __webpack_require__(4281);
|
|
5624
4796
|
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/services/entity-builder-datasource.provider.ts
|
|
5625
4797
|
var entity_builder_datasource_provider = __webpack_require__(424);
|
|
5626
|
-
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/services/flow-definition.service.ts
|
|
5627
|
-
var flow_definition_service = __webpack_require__(
|
|
4798
|
+
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/services/flow-definition.service.ts
|
|
4799
|
+
var flow_definition_service = __webpack_require__(5229);
|
|
5628
4800
|
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/services/generic-entity.service.ts
|
|
5629
4801
|
var generic_entity_service = __webpack_require__(3998);
|
|
5630
4802
|
// EXTERNAL MODULE: ./projects/nestjs-entity-builder/src/services/generic-entity-service.factory.ts
|
|
@@ -5672,7 +4844,6 @@ function _ts_param(paramIndex, decorator) {
|
|
|
5672
4844
|
|
|
5673
4845
|
|
|
5674
4846
|
|
|
5675
|
-
|
|
5676
4847
|
|
|
5677
4848
|
|
|
5678
4849
|
const publishFlowEvent = (eventName, payload, user)=>(0,classes_.publishDomainEvent)({
|
|
@@ -5682,31 +4853,27 @@ const publishFlowEvent = (eventName, payload, user)=>(0,classes_.publishDomainEv
|
|
|
5682
4853
|
metadata: payload,
|
|
5683
4854
|
user
|
|
5684
4855
|
});
|
|
5685
|
-
/** The run's time budget, whatever a
|
|
4856
|
+
/** The run's time budget, whatever a definition asks for. */ const flowTimeout = (timeoutMs)=>typeof timeoutMs === 'number' && Number.isFinite(timeoutMs) ? Math.min(Math.max(timeoutMs, flow_types/* .FLOW_LIMITS.MIN_TIMEOUT_MS */.Or.MIN_TIMEOUT_MS), flow_types/* .FLOW_LIMITS.MAX_TIMEOUT_MS */.Or.MAX_TIMEOUT_MS) : flow_types/* .FLOW_LIMITS.DEFAULT_TIMEOUT_MS */.Or.DEFAULT_TIMEOUT_MS;
|
|
5686
4857
|
class FlowExecutorService {
|
|
5687
4858
|
provider;
|
|
5688
4859
|
ruleEngine;
|
|
5689
4860
|
moduleRef;
|
|
5690
4861
|
permissionCache;
|
|
5691
4862
|
config;
|
|
5692
|
-
companyAccess;
|
|
5693
|
-
notifications;
|
|
5694
|
-
email;
|
|
5695
4863
|
logger = new common_.Logger(FlowExecutorService.name);
|
|
5696
|
-
constructor(provider, ruleEngine, moduleRef, permissionCache, config
|
|
4864
|
+
constructor(provider, ruleEngine, moduleRef, permissionCache, config){
|
|
5697
4865
|
this.provider = provider;
|
|
5698
4866
|
this.ruleEngine = ruleEngine;
|
|
5699
4867
|
this.moduleRef = moduleRef;
|
|
5700
4868
|
this.permissionCache = permissionCache;
|
|
5701
4869
|
this.config = config;
|
|
5702
|
-
this.companyAccess = companyAccess;
|
|
5703
|
-
this.notifications = notifications;
|
|
5704
|
-
this.email = email;
|
|
5705
4870
|
}
|
|
5706
|
-
async run(
|
|
4871
|
+
async run(definition, options) {
|
|
5707
4872
|
const startedAt = Date.now();
|
|
5708
|
-
const
|
|
5709
|
-
|
|
4873
|
+
const flow = {
|
|
4874
|
+
...definition,
|
|
4875
|
+
timeoutMs: flowTimeout(definition.timeoutMs)
|
|
4876
|
+
};
|
|
5710
4877
|
const state = {
|
|
5711
4878
|
startAt: options.startAt,
|
|
5712
4879
|
input: options.input,
|
|
@@ -5714,16 +4881,14 @@ class FlowExecutorService {
|
|
|
5714
4881
|
context: {},
|
|
5715
4882
|
request: options.request,
|
|
5716
4883
|
user: options.user,
|
|
5717
|
-
authorization: options.authorization,
|
|
5718
4884
|
permissions: this.ruleEngine.createPermissionResolver(options.user),
|
|
5719
4885
|
mode: options.mode,
|
|
5720
|
-
runAs,
|
|
5721
|
-
systemAuthorized: runAs === 'system' && options.systemAuthorized === true,
|
|
4886
|
+
runAs: flow.runAs,
|
|
4887
|
+
systemAuthorized: flow.runAs === 'system' && options.systemAuthorized === true,
|
|
5722
4888
|
steps: 0,
|
|
5723
4889
|
httpCalls: 0,
|
|
5724
|
-
messages: 0,
|
|
5725
4890
|
writes: 0,
|
|
5726
|
-
deadline: startedAt +
|
|
4891
|
+
deadline: startedAt + flow.timeoutMs,
|
|
5727
4892
|
callStack: [
|
|
5728
4893
|
flow.slug
|
|
5729
4894
|
],
|
|
@@ -5731,15 +4896,15 @@ class FlowExecutorService {
|
|
|
5731
4896
|
trace: []
|
|
5732
4897
|
};
|
|
5733
4898
|
try {
|
|
5734
|
-
if (!flow_types/* .FLOW_RUN_AS.includes */.gl.includes(runAs)) {
|
|
4899
|
+
if (!flow_types/* .FLOW_RUN_AS.includes */.gl.includes(flow.runAs)) {
|
|
5735
4900
|
throw new flow_errors/* .FlowHttpError */.hk(403, 'This flow is not allowed to run.', undefined, {
|
|
5736
4901
|
messageKey: message_keys/* .FLOW_ERROR_MESSAGES.RUN_AS_NOT_ALLOWED */.zr.RUN_AS_NOT_ALLOWED,
|
|
5737
4902
|
messageVariables: {
|
|
5738
|
-
runAs: String(runAs)
|
|
4903
|
+
runAs: String(flow.runAs)
|
|
5739
4904
|
}
|
|
5740
4905
|
});
|
|
5741
4906
|
}
|
|
5742
|
-
await this.execute(flow,
|
|
4907
|
+
await this.execute(flow, state, this.createEnv());
|
|
5743
4908
|
return {
|
|
5744
4909
|
...(0,flow_engine/* .successResult */.JK)(state, startedAt),
|
|
5745
4910
|
...state.savedUpTo ? {
|
|
@@ -5769,10 +4934,10 @@ class FlowExecutorService {
|
|
|
5769
4934
|
}
|
|
5770
4935
|
}
|
|
5771
4936
|
/**
|
|
5772
|
-
* Walks `flow`. A flow called from inside a transaction joins it; otherwise a
|
|
5773
|
-
*
|
|
5774
|
-
*/ async execute(flow,
|
|
5775
|
-
if (state.qr || !(
|
|
4937
|
+
* Walks `flow`. A flow called from inside a transaction joins it; otherwise a transactional
|
|
4938
|
+
* flow (or any test run) gets its own, and its held-back events are published after the commit.
|
|
4939
|
+
*/ async execute(flow, state, env) {
|
|
4940
|
+
if (state.qr || !(flow.isTransactional || state.mode === 'dry_run')) {
|
|
5776
4941
|
await new flow_engine/* .FlowEngine */.$I(flow, env).walk(state);
|
|
5777
4942
|
return;
|
|
5778
4943
|
}
|
|
@@ -5851,6 +5016,7 @@ class FlowExecutorService {
|
|
|
5851
5016
|
max: flow_types/* .FLOW_LIMITS.MAX_CALL_DEPTH */.Or.MAX_CALL_DEPTH
|
|
5852
5017
|
});
|
|
5853
5018
|
const flow = await this.findCallable(slug, parent.qr);
|
|
5019
|
+
await this.assertMayCall(flow, parent, env);
|
|
5854
5020
|
const settings = (0,flow_definition_service/* .toFlowSettings */.RK)(flow);
|
|
5855
5021
|
const start = (0,flow_types/* .findEndpoint */.vS)(settings, endpoint);
|
|
5856
5022
|
if (!start) {
|
|
@@ -5859,7 +5025,6 @@ class FlowExecutorService {
|
|
|
5859
5025
|
endpoint: endpoint ?? ''
|
|
5860
5026
|
}, `Flow '${slug}' has no URL '${endpoint ?? ''}'.`);
|
|
5861
5027
|
}
|
|
5862
|
-
await this.assertMayCall(flow, start, parent, env);
|
|
5863
5028
|
const checked = (0,flow_input_validator/* .validateFlowInput */.v)(start.inputSchema, input, start.bodyType);
|
|
5864
5029
|
if (checked.errors.length) {
|
|
5865
5030
|
throw new flow_errors/* .FlowHttpError */.hk(400, 'Validation failed', checked.errors, {
|
|
@@ -5876,17 +5041,15 @@ class FlowExecutorService {
|
|
|
5876
5041
|
context: {},
|
|
5877
5042
|
request: parent.request,
|
|
5878
5043
|
user: parent.user,
|
|
5879
|
-
authorization: parent.authorization,
|
|
5880
5044
|
permissions: parent.permissions,
|
|
5881
5045
|
mode: parent.mode,
|
|
5882
|
-
runAs:
|
|
5883
|
-
// A function inherits the caller's grant; any other called flow is a saved flow whose
|
|
5884
|
-
systemAuthorized:
|
|
5046
|
+
runAs: flow.authMode === 'internal' ? parent.runAs : settings.runAs,
|
|
5047
|
+
// A function inherits the caller's grant; any other called flow is a saved flow whose own run-as was checked when it was saved.
|
|
5048
|
+
systemAuthorized: flow.authMode === 'internal' ? parent.systemAuthorized === true : settings.runAs === 'system',
|
|
5885
5049
|
steps: parent.steps,
|
|
5886
5050
|
httpCalls: parent.httpCalls,
|
|
5887
|
-
messages: parent.messages,
|
|
5888
5051
|
writes: parent.writes,
|
|
5889
|
-
deadline: Math.min(parent.deadline, Date.now() + flowTimeout(
|
|
5052
|
+
deadline: Math.min(parent.deadline, Date.now() + flowTimeout(settings.timeoutMs)),
|
|
5890
5053
|
qr: parent.qr,
|
|
5891
5054
|
callStack: [
|
|
5892
5055
|
...parent.callStack,
|
|
@@ -5901,14 +5064,13 @@ class FlowExecutorService {
|
|
|
5901
5064
|
if (child.pendingEvents === parent.pendingEvents) parent.pendingEvents.length = queued;
|
|
5902
5065
|
};
|
|
5903
5066
|
try {
|
|
5904
|
-
await this.execute(settings,
|
|
5067
|
+
await this.execute(settings, child, env);
|
|
5905
5068
|
} catch (error) {
|
|
5906
5069
|
dropQueued();
|
|
5907
5070
|
throw calledFlowFailure(flow, error);
|
|
5908
5071
|
} finally{
|
|
5909
5072
|
parent.steps = child.steps;
|
|
5910
5073
|
parent.httpCalls = child.httpCalls;
|
|
5911
|
-
parent.messages = child.messages;
|
|
5912
5074
|
parent.writes = child.writes;
|
|
5913
5075
|
}
|
|
5914
5076
|
if (child.response) {
|
|
@@ -5927,8 +5089,7 @@ class FlowExecutorService {
|
|
|
5927
5089
|
where: {
|
|
5928
5090
|
slug,
|
|
5929
5091
|
isActive: true,
|
|
5930
|
-
deletedAt: (0,external_typeorm_.IsNull)()
|
|
5931
|
-
version: (0,external_typeorm_.MoreThan)(0)
|
|
5092
|
+
deletedAt: (0,external_typeorm_.IsNull)()
|
|
5932
5093
|
}
|
|
5933
5094
|
});
|
|
5934
5095
|
if (!flow) throw new flow_errors/* .FlowKeyedError */.Hp(message_keys/* .FLOW_ERROR_MESSAGES.CALLED_FLOW_NOT_FOUND */.zr.CALLED_FLOW_NOT_FOUND, {
|
|
@@ -5938,22 +5099,20 @@ class FlowExecutorService {
|
|
|
5938
5099
|
}
|
|
5939
5100
|
/**
|
|
5940
5101
|
* Any flow may call a function, and a flow running as the system may call any flow. One running
|
|
5941
|
-
* as the caller may call only
|
|
5942
|
-
* and permission
|
|
5943
|
-
*/ async assertMayCall(flow,
|
|
5944
|
-
|
|
5945
|
-
if (
|
|
5946
|
-
if (mode === 'api_key' || !parent.user) {
|
|
5102
|
+
* as the caller may call only what that caller could call directly: public and signed-in flows,
|
|
5103
|
+
* and permission flows when the caller holds the permission - never an API-key flow.
|
|
5104
|
+
*/ async assertMayCall(flow, parent, env) {
|
|
5105
|
+
if (parent.runAs === 'system' && parent.systemAuthorized === true || flow.authMode === 'public' || flow.authMode === 'internal') return;
|
|
5106
|
+
if (flow.authMode === 'api_key' || !parent.user) {
|
|
5947
5107
|
throw new flow_errors/* .FlowKeyedError */.Hp(message_keys/* .FLOW_ERROR_MESSAGES.CALLED_FLOW_NOT_ALLOWED */.zr.CALLED_FLOW_NOT_ALLOWED, {
|
|
5948
5108
|
flow: flow.slug,
|
|
5949
|
-
authMode:
|
|
5950
|
-
}, `Flow '${flow.slug}' (${
|
|
5109
|
+
authMode: flow.authMode
|
|
5110
|
+
}, `Flow '${flow.slug}' (${flow.authMode}) cannot be called by this caller.`);
|
|
5951
5111
|
}
|
|
5952
|
-
if (
|
|
5112
|
+
if (flow.authMode === 'permission') await env.assertPermission(flow.permissionCode || (0,flow_definition_service/* .defaultFlowPermissionCode */.Er)(flow.slug), parent.user);
|
|
5953
5113
|
}
|
|
5954
5114
|
createEnv() {
|
|
5955
5115
|
const entityServices = new Map();
|
|
5956
|
-
/** One lookup per user for the whole run, however many steps ask. */ const access = new Map();
|
|
5957
5116
|
let permissions;
|
|
5958
5117
|
const env = {
|
|
5959
5118
|
ruleEngine: this.ruleEngine,
|
|
@@ -5976,18 +5135,6 @@ class FlowExecutorService {
|
|
|
5976
5135
|
atomic: (state, work)=>this.atomic(state, work),
|
|
5977
5136
|
commit: (state)=>this.commitProgress(state),
|
|
5978
5137
|
http: flowHttpRequest,
|
|
5979
|
-
notifications: this.notifications,
|
|
5980
|
-
email: this.email,
|
|
5981
|
-
...this.companyAccess ? {
|
|
5982
|
-
companyMembers: (companyId, branchIds)=>this.companyAccess.getCompanyMembers(companyId, branchIds)
|
|
5983
|
-
} : {},
|
|
5984
|
-
companyAccess: (userId)=>{
|
|
5985
|
-
if (!access.has(userId)) access.set(userId, this.companyAccess ? this.companyAccess.getUserAccess(userId) : Promise.resolve({
|
|
5986
|
-
companies: [],
|
|
5987
|
-
branches: []
|
|
5988
|
-
}));
|
|
5989
|
-
return access.get(userId);
|
|
5990
|
-
},
|
|
5991
5138
|
publish: (eventName, payload, user)=>publishFlowEvent(eventName, payload, user),
|
|
5992
5139
|
assertPermission: async (code, user)=>{
|
|
5993
5140
|
if (!user) throw new common_.UnauthorizedException({
|
|
@@ -6008,13 +5155,9 @@ class FlowExecutorService {
|
|
|
6008
5155
|
};
|
|
6009
5156
|
return env;
|
|
6010
5157
|
}
|
|
6011
|
-
/** After commit, so listeners see committed data
|
|
5158
|
+
/** After commit, so listeners see committed data. A failing publish never turns a completed run into an error. */ async publishPendingEvents(events, user) {
|
|
6012
5159
|
for (const event of events){
|
|
6013
5160
|
try {
|
|
6014
|
-
if ('delivery' in event) {
|
|
6015
|
-
await event.send();
|
|
6016
|
-
continue;
|
|
6017
|
-
}
|
|
6018
5161
|
if ('eventName' in event) {
|
|
6019
5162
|
await publishFlowEvent(event.eventName, event.payload, user);
|
|
6020
5163
|
continue;
|
|
@@ -6033,10 +5176,6 @@ class FlowExecutorService {
|
|
|
6033
5176
|
user
|
|
6034
5177
|
});
|
|
6035
5178
|
} catch (error) {
|
|
6036
|
-
if ('delivery' in event) {
|
|
6037
|
-
this.logger.error(`Could not send the message of "${event.delivery}" after the commit: ${error.message}`);
|
|
6038
|
-
continue;
|
|
6039
|
-
}
|
|
6040
5179
|
const name = 'eventName' in event ? event.eventName : `${event.entityCode}.${event.action}`;
|
|
6041
5180
|
this.logger.error(`Could not publish ${name}: ${error.message}`);
|
|
6042
5181
|
}
|
|
@@ -6050,22 +5189,13 @@ FlowExecutorService = _ts_decorate([
|
|
|
6050
5189
|
_ts_param(2, (0,common_.Inject)(core_.ModuleRef)),
|
|
6051
5190
|
_ts_param(3, (0,common_.Inject)(modules_.SharedPermissionCacheService)),
|
|
6052
5191
|
_ts_param(4, (0,common_.Inject)(entity_builder_config_service/* .EntityBuilderConfigService */.E)),
|
|
6053
|
-
_ts_param(5, (0,common_.Optional)()),
|
|
6054
|
-
_ts_param(5, (0,common_.Inject)(interfaces_.COMPANY_ACCESS_RESOLVER)),
|
|
6055
|
-
_ts_param(6, (0,common_.Optional)()),
|
|
6056
|
-
_ts_param(6, (0,common_.Inject)(interfaces_.NOTIFICATION_ADAPTER)),
|
|
6057
|
-
_ts_param(7, (0,common_.Optional)()),
|
|
6058
|
-
_ts_param(7, (0,common_.Inject)(interfaces_.EMAIL_ADAPTER)),
|
|
6059
5192
|
_ts_metadata("design:type", Function),
|
|
6060
5193
|
_ts_metadata("design:paramtypes", [
|
|
6061
5194
|
typeof entity_builder_datasource_provider/* .EntityBuilderDataSourceProvider */.D === "undefined" ? Object : entity_builder_datasource_provider/* .EntityBuilderDataSourceProvider */.D,
|
|
6062
5195
|
typeof rule_engine/* .RuleEngineService */.iI === "undefined" ? Object : rule_engine/* .RuleEngineService */.iI,
|
|
6063
5196
|
typeof core_.ModuleRef === "undefined" ? Object : core_.ModuleRef,
|
|
6064
5197
|
typeof modules_.SharedPermissionCacheService === "undefined" ? Object : modules_.SharedPermissionCacheService,
|
|
6065
|
-
typeof entity_builder_config_service/* .EntityBuilderConfigService */.E === "undefined" ? Object : entity_builder_config_service/* .EntityBuilderConfigService */.E
|
|
6066
|
-
typeof ICompanyAccessResolver === "undefined" ? Object : ICompanyAccessResolver,
|
|
6067
|
-
typeof INotificationAdapter === "undefined" ? Object : INotificationAdapter,
|
|
6068
|
-
typeof IEmailAdapter === "undefined" ? Object : IEmailAdapter
|
|
5198
|
+
typeof entity_builder_config_service/* .EntityBuilderConfigService */.E === "undefined" ? Object : entity_builder_config_service/* .EntityBuilderConfigService */.E
|
|
6069
5199
|
])
|
|
6070
5200
|
], FlowExecutorService);
|
|
6071
5201
|
/** A rejection or a limit inside the called flow is passed on as it is; anything else fails the calling node with the reason. */ function calledFlowFailure(flow, error) {
|
|
@@ -6106,7 +5236,7 @@ FlowExecutorService = _ts_decorate([
|
|
|
6106
5236
|
/* import */ var _flow_engine_flow_input_validator_js__rspack_import_3 = __webpack_require__(6390);
|
|
6107
5237
|
/* import */ var _flow_engine_flow_types_js__rspack_import_4 = __webpack_require__(6256);
|
|
6108
5238
|
/* import */ var _entity_builder_datasource_provider_js__rspack_import_5 = __webpack_require__(424);
|
|
6109
|
-
/* import */ var _flow_definition_service_js__rspack_import_6 = __webpack_require__(
|
|
5239
|
+
/* import */ var _flow_definition_service_js__rspack_import_6 = __webpack_require__(5229);
|
|
6110
5240
|
/* import */ var _flow_execution_service_js__rspack_import_7 = __webpack_require__(7810);
|
|
6111
5241
|
/* import */ var _flow_executor_service_js__rspack_import_8 = __webpack_require__(4698);
|
|
6112
5242
|
function _ts_decorate(decorators, target, key, desc) {
|
|
@@ -6178,11 +5308,6 @@ const MAX_QUERY_VALUE_LENGTH = 2000;
|
|
|
6178
5308
|
receivedAt: new Date().toISOString()
|
|
6179
5309
|
};
|
|
6180
5310
|
}
|
|
6181
|
-
/** The caller's own `Authorization` header, kept for Request steps that forward it: only for a signed-in (verified) caller. */ function callerAuthorization(caller, user) {
|
|
6182
|
-
if (!user) return undefined;
|
|
6183
|
-
const value = Object.entries(caller.headers).find(([key])=>key.toLowerCase() === 'authorization')?.[1];
|
|
6184
|
-
return typeof value === 'string' && value ? value : undefined;
|
|
6185
|
-
}
|
|
6186
5311
|
/** A test run's request: the designer's own, with the headers / query / IP the author chose to simulate on top. */ function simulatedCaller(caller, simulated) {
|
|
6187
5312
|
if (!simulated) return caller;
|
|
6188
5313
|
const headers = {
|
|
@@ -6222,13 +5347,13 @@ class FlowRuntimeService {
|
|
|
6222
5347
|
this.executions = executions;
|
|
6223
5348
|
this.definitions = definitions;
|
|
6224
5349
|
}
|
|
6225
|
-
/** A flow
|
|
5350
|
+
/** A function flow has no endpoint: it looks the same as an unknown one. */ async findActive(slug) {
|
|
6226
5351
|
return (await this.provider.getRepository(_entities_flow_definition_entity_js__rspack_import_2/* .FlowDefinition */.G)).findOne({
|
|
6227
5352
|
where: {
|
|
6228
5353
|
slug,
|
|
6229
5354
|
isActive: true,
|
|
6230
5355
|
deletedAt: (0,typeorm__rspack_import_1.IsNull)(),
|
|
6231
|
-
|
|
5356
|
+
authMode: (0,typeorm__rspack_import_1.Not)('internal')
|
|
6232
5357
|
}
|
|
6233
5358
|
});
|
|
6234
5359
|
}
|
|
@@ -6240,14 +5365,13 @@ class FlowRuntimeService {
|
|
|
6240
5365
|
await this.logWebhook(flow, body, result, startedAt, user, caller);
|
|
6241
5366
|
return result;
|
|
6242
5367
|
}
|
|
6243
|
-
// A saved flow: saving
|
|
5368
|
+
// A saved flow: saving it as `runAs: system` needed the system permission.
|
|
6244
5369
|
const result = await this.executor.run((0,_flow_definition_service_js__rspack_import_6/* .toFlowSettings */.RK)(flow), {
|
|
6245
5370
|
mode: 'live',
|
|
6246
5371
|
user,
|
|
6247
5372
|
input: checked.values,
|
|
6248
5373
|
startAt: endpoint.nodeId,
|
|
6249
5374
|
request: requestInfo(caller),
|
|
6250
|
-
authorization: callerAuthorization(caller, user),
|
|
6251
5375
|
exposeDetails: false,
|
|
6252
5376
|
systemAuthorized: true
|
|
6253
5377
|
});
|
|
@@ -6256,6 +5380,7 @@ class FlowRuntimeService {
|
|
|
6256
5380
|
}
|
|
6257
5381
|
/** The designer's "Test run": a saved flow or an unsaved draft. */ async testRun(dto, user, caller) {
|
|
6258
5382
|
let settings;
|
|
5383
|
+
let permissionCode;
|
|
6259
5384
|
let flow = null;
|
|
6260
5385
|
if (dto.flowId) {
|
|
6261
5386
|
flow = await this.definitions.findOrFail(dto.flowId);
|
|
@@ -6263,8 +5388,10 @@ class FlowRuntimeService {
|
|
|
6263
5388
|
if (dto.definition) {
|
|
6264
5389
|
// The designer's current draft, even for a saved flow: `flow` above is kept only to attribute the run.
|
|
6265
5390
|
settings = (0,_flow_definition_service_js__rspack_import_6/* .toFlowSettings */.RK)(dto.definition);
|
|
5391
|
+
permissionCode = dto.definition.permissionCode;
|
|
6266
5392
|
} else if (flow) {
|
|
6267
5393
|
settings = (0,_flow_definition_service_js__rspack_import_6/* .toFlowSettings */.RK)(flow);
|
|
5394
|
+
permissionCode = flow.permissionCode;
|
|
6268
5395
|
} else {
|
|
6269
5396
|
throw new _nestjs_common__rspack_import_0.BadRequestException({
|
|
6270
5397
|
message: 'Send a flowId or a definition to test.',
|
|
@@ -6272,22 +5399,15 @@ class FlowRuntimeService {
|
|
|
6272
5399
|
});
|
|
6273
5400
|
}
|
|
6274
5401
|
const mode = dto.mode ?? 'dry_run';
|
|
6275
|
-
const endpoint = (0,_flow_engine_flow_types_js__rspack_import_4/* .findEndpoint */.vS)(settings, dto.endpoint);
|
|
6276
5402
|
// Checked before anything runs; passing it is what lets a `runAs: system` test touch entities.
|
|
6277
|
-
await this.definitions.assertMayTest(
|
|
5403
|
+
await this.definitions.assertMayTest({
|
|
5404
|
+
...settings,
|
|
5405
|
+
permissionCode
|
|
5406
|
+
}, user, {
|
|
6278
5407
|
mode,
|
|
6279
5408
|
draft: !!dto.definition,
|
|
6280
5409
|
saved: !!flow
|
|
6281
5410
|
});
|
|
6282
|
-
if (!endpoint) {
|
|
6283
|
-
throw new _nestjs_common__rspack_import_0.BadRequestException({
|
|
6284
|
-
message: `This flow has no URL '${dto.endpoint ?? ''}'.`,
|
|
6285
|
-
messageKey: _config_message_keys_js__rspack_import_9/* .FLOW_MESSAGES.ENDPOINT_NOT_FOUND */.wu.ENDPOINT_NOT_FOUND,
|
|
6286
|
-
messageVariables: {
|
|
6287
|
-
endpoint: dto.endpoint ?? ''
|
|
6288
|
-
}
|
|
6289
|
-
});
|
|
6290
|
-
}
|
|
6291
5411
|
const validation = await this.definitions.validate(settings);
|
|
6292
5412
|
if (validation.errors.length) {
|
|
6293
5413
|
throw new _nestjs_common__rspack_import_0.BadRequestException({
|
|
@@ -6299,6 +5419,16 @@ class FlowRuntimeService {
|
|
|
6299
5419
|
}))
|
|
6300
5420
|
});
|
|
6301
5421
|
}
|
|
5422
|
+
const endpoint = (0,_flow_engine_flow_types_js__rspack_import_4/* .findEndpoint */.vS)(settings, dto.endpoint);
|
|
5423
|
+
if (!endpoint) {
|
|
5424
|
+
throw new _nestjs_common__rspack_import_0.BadRequestException({
|
|
5425
|
+
message: `This flow has no URL '${dto.endpoint ?? ''}'.`,
|
|
5426
|
+
messageKey: _config_message_keys_js__rspack_import_9/* .FLOW_MESSAGES.ENDPOINT_NOT_FOUND */.wu.ENDPOINT_NOT_FOUND,
|
|
5427
|
+
messageVariables: {
|
|
5428
|
+
endpoint: dto.endpoint ?? ''
|
|
5429
|
+
}
|
|
5430
|
+
});
|
|
5431
|
+
}
|
|
6302
5432
|
const startedAt = new Date();
|
|
6303
5433
|
const simulated = simulatedCaller(caller, dto.request);
|
|
6304
5434
|
const body = dto.input ?? (endpoint.bodyType === 'list' ? [] : {});
|
|
@@ -6309,14 +5439,12 @@ class FlowRuntimeService {
|
|
|
6309
5439
|
input: checked.values,
|
|
6310
5440
|
startAt: endpoint.nodeId,
|
|
6311
5441
|
request: requestInfo(simulated),
|
|
6312
|
-
authorization: callerAuthorization(caller, user),
|
|
6313
5442
|
exposeDetails: true,
|
|
6314
5443
|
systemAuthorized: true
|
|
6315
5444
|
});
|
|
6316
5445
|
await this.executions.record({
|
|
6317
5446
|
flowId: flow?.id ?? null,
|
|
6318
5447
|
flowSlug: settings.slug,
|
|
6319
|
-
flowVersion: dto.definition ? null : flow?.version ?? null,
|
|
6320
5448
|
trigger: 'test',
|
|
6321
5449
|
mode,
|
|
6322
5450
|
input: body,
|
|
@@ -6335,7 +5463,6 @@ class FlowRuntimeService {
|
|
|
6335
5463
|
await this.executions.record({
|
|
6336
5464
|
flowId: flow.id,
|
|
6337
5465
|
flowSlug: flow.slug,
|
|
6338
|
-
flowVersion: flow.version,
|
|
6339
5466
|
trigger: 'webhook',
|
|
6340
5467
|
mode: 'live',
|
|
6341
5468
|
input,
|
|
@@ -6738,7 +5865,6 @@ const FILTER_COMPARISON_SQL = {
|
|
|
6738
5865
|
/** Soft-deletes the record, or deletes it for good when the entity has soft delete turned off. */ async delete(id, user, options = {}) {
|
|
6739
5866
|
this.ensureActive();
|
|
6740
5867
|
const repository = await this.ensureRepository();
|
|
6741
|
-
const soft = this.definition.isSoftDeleteEnabled;
|
|
6742
5868
|
await this.withTransaction(options, async (queryRunner)=>{
|
|
6743
5869
|
const existing = await queryRunner.manager.findOne(repository.target, {
|
|
6744
5870
|
where: {
|
|
@@ -6746,6 +5872,7 @@ const FILTER_COMPARISON_SQL = {
|
|
|
6746
5872
|
}
|
|
6747
5873
|
});
|
|
6748
5874
|
if (!existing) throw this.notFound(id);
|
|
5875
|
+
const soft = this.definition.isSoftDeleteEnabled;
|
|
6749
5876
|
if (soft) {
|
|
6750
5877
|
await queryRunner.manager.softDelete(repository.target, [
|
|
6751
5878
|
id
|
|
@@ -6771,7 +5898,6 @@ const FILTER_COMPARISON_SQL = {
|
|
|
6771
5898
|
]
|
|
6772
5899
|
};
|
|
6773
5900
|
}, user);
|
|
6774
|
-
return soft ? 'deleted' : 'purged';
|
|
6775
5901
|
}
|
|
6776
5902
|
async findById(id, options = {}) {
|
|
6777
5903
|
const repository = await this.repositoryFor(options.queryRunner);
|