@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.
Files changed (40) hide show
  1. package/README.md +22 -28
  2. package/config/message-keys.d.ts +9 -62
  3. package/controllers/flow-api-key.controller.d.ts +14 -0
  4. package/controllers/flow-definition.controller.d.ts +1 -7
  5. package/controllers/index.d.ts +1 -0
  6. package/dtos/flow.dto.d.ts +20 -10
  7. package/entities/flow-api-key.entity.d.ts +10 -0
  8. package/entities/flow-definition.entity.d.ts +9 -3
  9. package/entities/flow-execution.entity.d.ts +0 -1
  10. package/entities/index.d.ts +3 -3
  11. package/fesm/21.js +11 -64
  12. package/fesm/{582.js → 489.js} +11 -20
  13. package/fesm/{913.js → 606.js} +295 -209
  14. package/fesm/719.js +186 -162
  15. package/fesm/794.js +187 -116
  16. package/fesm/{677.js → 996.js} +616 -1490
  17. package/fesm/controllers/index.js +6 -5
  18. package/fesm/docs/index.js +2 -2
  19. package/fesm/entities/index.js +2 -2
  20. package/fesm/guards/index.js +19 -12
  21. package/fesm/index.js +638 -50
  22. package/fesm/modules/index.js +625 -7
  23. package/fesm/rule-engine/index.js +2 -2
  24. package/fesm/services/index.js +25 -54
  25. package/flow-engine/flow-api-key.d.ts +7 -3
  26. package/flow-engine/flow-graph.validator.d.ts +2 -4
  27. package/flow-engine/flow-run.types.d.ts +4 -14
  28. package/flow-engine/flow.types.d.ts +9 -91
  29. package/interfaces/flow-definition.interface.d.ts +9 -13
  30. package/package.json +5 -5
  31. package/rule-engine/rule-engine.service.d.ts +0 -1
  32. package/services/entity-flow-scaffold.d.ts +1 -1
  33. package/services/flow-api-key.service.d.ts +31 -0
  34. package/services/flow-definition.service.d.ts +12 -24
  35. package/services/flow-execution.service.d.ts +0 -1
  36. package/services/flow-executor.service.d.ts +7 -7
  37. package/services/generic-entity.service.d.ts +1 -1
  38. package/services/index.d.ts +1 -0
  39. package/entities/flow-version.entity.d.ts +0 -10
  40. package/fesm/458.js +0 -649
@@ -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 = 677;
12
- export const __rspack_esm_ids = [677];
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 */.u9)(check.rule)) ? 403 : 400);
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(undefined) : [];
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
- return deniedResult(cfg, {
583
+ const output = {
633
584
  allowed,
634
585
  missing
635
- }, allowed);
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
- action = await service.delete(id, state.user, writeOptions(state));
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 _config_entity_builder_constants_js__rspack_import_9 = __webpack_require__(6576);
1872
- /* import */ var _config_message_keys_js__rspack_import_8 = __webpack_require__(5732);
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__(8429);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.NOT_AN_EXPRESSION */.IP.NOT_AN_EXPRESSION);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.TOO_DEEP */.IP.TOO_DEEP);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.EMPTY_REFERENCE */.IP.EMPTY_REFERENCE);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.NO_TEMPLATE_TEXT */.IP.NO_TEMPLATE_TEXT);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.TEMPLATE_TOO_LONG */.IP.TEMPLATE_TOO_LONG);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.NO_OPERANDS */.IP.NO_OPERANDS);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.NO_PARTS */.IP.NO_PARTS);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.UNKNOWN_EXPRESSION_TYPE */.IP.UNKNOWN_EXPRESSION_TYPE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.NO_ARGUMENTS */.IP.NO_ARGUMENTS);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.UNKNOWN_FUNCTION */.IP.UNKNOWN_FUNCTION, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.WRONG_ARGUMENT_COUNT */.IP.WRONG_ARGUMENT_COUNT, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.DURATION_UNIT_INVALID */.IP.DURATION_UNIT_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .RULE_ENGINE_MESSAGES.TOO_MANY_PERMISSION_CODES */.x3.TOO_MANY_PERMISSION_CODES, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.PERMISSION_CODE_REQUIRED */.IP.PERMISSION_CODE_REQUIRED, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.IP_RANGE_INVALID */.IP.IP_RANGE_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.REGEX_TOO_LONG */.IP.REGEX_TOO_LONG, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.REGEX_INVALID */.IP.REGEX_INVALID);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.REGEX_TOO_COMPLEX */.IP.REGEX_TOO_COMPLEX, {
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' || !_config_entity_builder_constants_js__rspack_import_9/* .ENTITY_CODE_PATTERN.test */.vs.test(value.entity)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.LOOKUP_ENTITY_INVALID */.IP.LOOKUP_ENTITY_INVALID);
2162
- if (options.knownEntityCodes && !options.knownEntityCodes.has(value.entity)) return (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.LOOKUP_ENTITY_UNKNOWN */.IP.LOOKUP_ENTITY_UNKNOWN, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.LOOKUP_MODE_INVALID */.IP.LOOKUP_MODE_INVALID);
2170
- 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_8/* .FLOW_SHAPE_MESSAGES.LOOKUP_FIELD_INVALID */.IP.LOOKUP_FIELD_INVALID);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.LOOKUP_FIELD_INVALID */.IP.LOOKUP_FIELD_INVALID);
2172
- 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_8/* .FLOW_SHAPE_MESSAGES.LOOKUP_FILTER_INVALID */.IP.LOOKUP_FILTER_INVALID);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.LOOKUP_FILTER_INVALID */.IP.LOOKUP_FILTER_INVALID);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.FILTER_OPERATOR_UNKNOWN */.IP.FILTER_OPERATOR_UNKNOWN, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.FILTER_VALUE_REQUIRED */.IP.FILTER_VALUE_REQUIRED, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.CONDITION_INCOMPLETE */.IP.CONDITION_INCOMPLETE);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.UNKNOWN_COMPARISON */.IP.UNKNOWN_COMPARISON, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.NOT_A_RULE */.IP.NOT_A_RULE);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.TOO_DEEP */.IP.TOO_DEEP);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.TOO_MANY_CONDITIONS */.IP.TOO_MANY_CONDITIONS);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SHAPE_MESSAGES.UNKNOWN_OPERATOR */.IP.UNKNOWN_OPERATOR);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.SLUG_INVALID */.qj.SLUG_INVALID));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NO_NODES */.qj.NO_NODES));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TOO_MANY_NODES */.qj.TOO_MANY_NODES, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TOO_MANY_EDGES */.qj.TOO_MANY_EDGES, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_ID_INVALID */.qj.NODE_ID_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_ID_DUPLICATE */.qj.NODE_ID_DUPLICATE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_TYPE_UNKNOWN */.qj.NODE_TYPE_UNKNOWN, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.EDGE_ID_DUPLICATE */.qj.EDGE_ID_DUPLICATE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.EDGE_DANGLING */.qj.EDGE_DANGLING, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.EDGE_SELF */.qj.EDGE_SELF, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.EDGE_INTO_TRIGGER */.qj.EDGE_INTO_TRIGGER));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.EDGE_NO_PORT */.qj.EDGE_NO_PORT, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.EDGE_TWICE */.qj.EDGE_TWICE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.CYCLE */.qj.CYCLE));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_UNREACHABLE */.qj.NODE_UNREACHABLE, {
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
- // Run-as, transaction and access are a Request step's own: each is checked against the steps its runs reach.
2336
- const runs = (0,_flow_types_js__rspack_import_6/* .flowEndpoints */.Xr)(flow).map((endpoint)=>({
2337
- endpoint,
2338
- label: (0,_flow_types_js__rspack_import_6/* .nodeLabel */.dA)(byId.get(endpoint.nodeId) ?? {
2339
- id: endpoint.nodeId,
2340
- name: ''
2341
- }),
2342
- steps: [
2343
- ...reach(endpoint.nodeId, outgoing)
2344
- ].map((id)=>byId.get(id)).filter((node)=>!!node)
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_MISSING */.qj.TRIGGER_MISSING));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_MAIN_DUPLICATE */.qj.TRIGGER_MAIN_DUPLICATE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_PATH_DUPLICATE */.qj.TRIGGER_PATH_DUPLICATE, {
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 URL called from a run as the
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(node, flow, known, err, warn) {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INACTIVE */.qj.NODE_FLOW_INACTIVE, vars));
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 ? _config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_ENDPOINT_UNKNOWN */.qj.NODE_FLOW_ENDPOINT_UNKNOWN : _config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_ENDPOINT_REQUIRED */.qj.NODE_FLOW_ENDPOINT_REQUIRED, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INPUT_LIST_REQUIRED */.qj.NODE_FLOW_INPUT_LIST_REQUIRED, vars));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INPUT_LIST_UNEXPECTED */.qj.NODE_FLOW_INPUT_LIST_UNEXPECTED, vars));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_LOOP */.qj.NODE_FLOW_LOOP, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_TOO_DEEP */.qj.NODE_FLOW_TOO_DEEP, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INPUT_UNDECLARED */.qj.NODE_FLOW_INPUT_UNDECLARED, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_INPUT_MISSING */.qj.NODE_FLOW_INPUT_MISSING, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.INPUT_TOO_MANY */.qj.INPUT_TOO_MANY, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.INPUT_NAME_INVALID */.qj.INPUT_NAME_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.INPUT_NAME_DUPLICATE */.qj.INPUT_NAME_DUPLICATE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.INPUT_TYPE_UNKNOWN */.qj.INPUT_TYPE_UNKNOWN, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.INPUT_ITEM_TYPE_UNKNOWN */.qj.INPUT_ITEM_TYPE_UNKNOWN, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.INPUT_CHOICE_NO_OPTIONS */.qj.INPUT_CHOICE_NO_OPTIONS, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.INPUT_TOO_DEEP */.qj.INPUT_TOO_DEEP, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_EXPRESSION_PROBLEM */.qj.NODE_EXPRESSION_PROBLEM, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_PAIRS_INVALID */.qj.NODE_PAIRS_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_PAIRS_INVALID */.qj.NODE_PAIRS_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_EXPRESSION_PROBLEM */.qj.NODE_EXPRESSION_PROBLEM, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_RULE_PROBLEM */.qj.NODE_RULE_PROBLEM, {
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' || !_config_entity_builder_constants_js__rspack_import_9/* .ENTITY_CODE_PATTERN.test */.vs.test(value)) return err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHOOSE_ENTITY */.qj.NODE_CHOOSE_ENTITY, at));
2625
- if (context.knownEntityCodes && !context.knownEntityCodes.has(value)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_ENTITY_UNKNOWN */.qj.NODE_ENTITY_UNKNOWN, {
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: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.VARIABLES */.bc.VARIABLES,
2633
- item: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.VARIABLE */.bc.VARIABLE
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: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.FIELDS */.bc.FIELDS,
2637
- item: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.FIELD */.bc.FIELD
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: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.FILTERS */.bc.FILTERS,
2641
- item: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.FILTER */.bc.FILTER
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: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.INPUTS */.bc.INPUTS,
2645
- item: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.INPUT */.bc.INPUT
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: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.HEADERS */.bc.HEADERS,
2649
- item: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.HEADER */.bc.HEADER
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: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.BODY_VALUES */.bc.BODY_VALUES,
2653
- item: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.BODY_VALUE */.bc.BODY_VALUE
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: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.PAYLOAD_VALUES */.bc.PAYLOAD_VALUES,
2657
- item: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.PAYLOAD_VALUE */.bc.PAYLOAD_VALUE
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: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.RESPONSE_VALUES */.bc.RESPONSE_VALUES,
2661
- item: _config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.RESPONSE_VALUE */.bc.RESPONSE_VALUE
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_PATH_INVALID */.qj.TRIGGER_PATH_INVALID, at));
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 (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_8/* .FLOW_VALIDATION_MESSAGES.BODY_TYPE_UNKNOWN */.qj.BODY_TYPE_UNKNOWN, {
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 : [], path ? `${path}: ` : '', 1, err);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_MODE_INVALID */.qj.NODE_MODE_INVALID, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_STATUS_4XX */.qj.NODE_STATUS_4XX, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_PERMISSION_REQUIRED */.qj.NODE_PERMISSION_REQUIRED, at));
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)(_config_message_keys_js__rspack_import_8/* .RULE_ENGINE_MESSAGES.TOO_MANY_PERMISSION_CODES */.x3.TOO_MANY_PERMISSION_CODES, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_PERMISSION_OPTION_INVALID */.qj.NODE_PERMISSION_OPTION_INVALID, at));
2730
- 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));
2731
- 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));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_STATUS_4XX */.qj.NODE_STATUS_4XX, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_SETS_NOTHING */.qj.NODE_SETS_NOTHING, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_VARIABLE_INVALID */.qj.NODE_VARIABLE_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_RULE */.bc.THE_RULE));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_VALUE */.bc.THE_VALUE));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CASE_REQUIRED */.qj.NODE_CASE_REQUIRED, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CASE_INVALID */.qj.NODE_CASE_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CASE_DUPLICATE */.qj.NODE_CASE_DUPLICATE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_LIST */.bc.THE_LIST));
2784
- if (c.collect !== undefined) expr(c.collect, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_COLLECTED_VALUE */.bc.THE_COLLECTED_VALUE));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_MAX_ITEMS_RANGE */.qj.NODE_MAX_ITEMS_RANGE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_RECORD_ID */.bc.THE_RECORD_ID));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_SEARCH_TEXT */.bc.THE_SEARCH_TEXT));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_LIMIT_RANGE */.qj.NODE_LIMIT_RANGE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHOOSE_FLOW */.qj.NODE_CHOOSE_FLOW, at));
2858
- else if (c.flowSlug === flow.slug) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CALLS_ITSELF */.qj.NODE_CALLS_ITSELF, at));
2859
- 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_8/* .FLOW_VALIDATION_MESSAGES.NODE_FLOW_UNKNOWN */.qj.NODE_FLOW_UNKNOWN, {
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(node, flow, context.knownFlows, err, warn);
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.TRIGGER_PATH_INVALID */.qj.TRIGGER_PATH_INVALID, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_INPUT_LIST */.bc.THE_INPUT_LIST));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHOOSE_METHOD */.qj.NODE_CHOOSE_METHOD, at));
2877
- expr(c.url, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_URL */.bc.THE_URL));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_TIMEOUT_RANGE */.qj.NODE_TIMEOUT_RANGE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_EVENT_NAME_INVALID */.qj.NODE_EVENT_NAME_INVALID, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_STATUS_2XX_5XX */.qj.NODE_STATUS_2XX_5XX, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_RESPONSE */.bc.THE_RESPONSE));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_COMMIT_CONTINUE */.qj.NODE_COMMIT_CONTINUE, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CODE_REQUIRED */.qj.NODE_CODE_REQUIRED, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CODE_TOO_LONG */.qj.NODE_CODE_TOO_LONG, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CODE_TIMEOUT_RANGE */.qj.NODE_CODE_TIMEOUT_RANGE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_WRITE_TARGET_INVALID */.qj.NODE_WRITE_TARGET_INVALID, at));
2966
- if (c.onNotFound !== undefined && !notFound.includes(c.onNotFound)) err((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_NOT_FOUND_INVALID */.qj.NODE_NOT_FOUND_INVALID, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_RECORD_ID */.bc.THE_RECORD_ID));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_LIST */.bc.THE_LIST));
2971
- if (needsId && c.id !== undefined) expr(c.id, (0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_RECORD_ID */.bc.THE_RECORD_ID));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_FILTER_REQUIRED */.qj.NODE_FILTER_REQUIRED, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_LIMIT_RANGE */.qj.NODE_LIMIT_RANGE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHILDREN_INVALID */.qj.NODE_CHILDREN_INVALID, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHILDREN_TOO_MANY */.qj.NODE_CHILDREN_TOO_MANY, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHILDREN_INVALID */.qj.NODE_CHILDREN_INVALID, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHILD_NAME_INVALID */.qj.NODE_CHILD_NAME_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHILD_NAME_DUPLICATE */.qj.NODE_CHILD_NAME_DUPLICATE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHILD_PARENT_FIELD_REQUIRED */.qj.NODE_CHILD_PARENT_FIELD_REQUIRED, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.CHILD_LIST */.bc.CHILD_LIST, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_PAIRS_INVALID */.qj.NODE_PAIRS_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.FIELDS */.bc.FIELDS)
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.CHILD_FIELD */.bc.CHILD_FIELD, {
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; a many message step's values
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHECK_REQUIRED */.qj.NODE_CHECK_REQUIRED, at));
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_TOO_MANY_CHECKS */.qj.NODE_TOO_MANY_CHECKS, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHECK_ID_INVALID */.qj.NODE_CHECK_ID_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHECK_ID_DUPLICATE */.qj.NODE_CHECK_ID_DUPLICATE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_SUBJECT_MESSAGES.THE_CHECK */.bc.THE_CHECK, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHECK_MESSAGE_REQUIRED */.qj.NODE_CHECK_MESSAGE_REQUIRED, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.NODE_CHECK_FIELD_INVALID */.qj.NODE_CHECK_FIELD_INVALID, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.REF_BAD_SCOPE */.qj.REF_BAD_SCOPE, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.REF_NODE_MISSING */.qj.REF_NODE_MISSING, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.REF_SELF */.qj.REF_SELF, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.REF_INPUT_UNDECLARED */.qj.REF_INPUT_UNDECLARED, {
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: reached
3181
- * from a Request step without the transaction setting, inside a loop (once per item), or in a flow
3182
- * other flows call (inside its caller's transaction it is skipped).
3183
- */ function checkTransactionUse(flow, runs, outgoing, context, warnings) {
3184
- for (const { endpoint, label, steps } of runs){
3185
- if (endpoint.isTransactional) continue;
3186
- const writes = steps.filter((n)=>WRITE_NODE_TYPES.has(n.type)).length;
3187
- if (writes >= 2) warnings.push((0,_flusys_nestjs_shared_utils__rspack_import_0.messageRef)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.WRITES_NOT_TRANSACTIONAL */.qj.WRITES_NOT_TRANSACTIONAL, {
3188
- count: writes,
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.COMMIT_IN_LOOP */.qj.COMMIT_IN_LOOP, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.COMMIT_IN_CALLED_FLOW */.qj.COMMIT_IN_CALLED_FLOW, at));
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(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.REF_LOOP_OUTSIDE */.qj.REF_LOOP_OUTSIDE, {});
3324
- else if ((parents < 0 ? segs.length - 1 : parents) >= depth) warn(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.REF_LOOP_PARENT_MISSING */.qj.REF_LOOP_PARENT_MISSING, {});
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(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.REF_NODE_NOT_YET */.qj.REF_NODE_NOT_YET, {
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(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.REF_LOOP_RESULTS_EARLY */.qj.REF_LOOP_RESULTS_EARLY, {
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)(_config_message_keys_js__rspack_import_8/* .FLOW_VALIDATION_MESSAGES.LOOP_TOO_DEEP */.qj.LOOP_TOO_DEEP, {
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
- nC: () => (validateFlow),
3392
- r7: () => (callProblems),
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, with the body and access it sets. */ function flowEndpoints(flow) {
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
- const config = node.config ?? {};
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
- 4921(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
3843
+ 8888(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
4617
3844
 
4618
3845
  // EXPORTS
4619
3846
  __webpack_require__.d(__webpack_exports__, {
4620
- Tk: () => (/* binding */ FlowDefinitionService),
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/entity-definition.entity.ts
4646
- var entity_definition_entity = __webpack_require__(3189);
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/entities/flow-version.entity.ts
4650
- var flow_version_entity = __webpack_require__(2399);
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
- ;// CONCATENATED MODULE: ./projects/nestjs-entity-builder/src/services/flow-definition.service.ts
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 common_.NotFoundException({
4120
+ const flowNotFound = ()=>new _nestjs_common__rspack_import_3.NotFoundException({
4712
4121
  message: 'Flow not found.',
4713
- messageKey: message_keys/* .FLOW_MESSAGES.NOT_FOUND */.wu.NOT_FOUND
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
- /** What running a flow needs; everything about a run is on its Request steps. */ function toFlowSettings(dto) {
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
- /** A Request step with a URL that runs as the system (an `internal` one runs as its caller, whatever it says). */ const runsAsSystem = (settings)=>(0,flow_types/* .flowEndpoints */.Xr)(settings).some((endpoint)=>endpoint.authMode !== 'internal' && endpoint.runAs === 'system');
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
- notifications;
4742
- email;
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(flow_definition_entity/* .FlowDefinition */.G)).findOne({
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 and the modules this app runs. Returns errors and warnings without throwing. */ async validate(settings) {
4757
- const entities = await (await this.provider.getRepository(entity_definition_entity/* .EntityDefinition */.f)).find({
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(flow_definition_entity/* .FlowDefinition */.G)).find();
4763
- return (0,flow_graph_validator/* .validateFlow */.nC)(settings, {
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
- callableOf(flow)
4768
- ])),
4769
- messageServices: {
4770
- notification: !!this.notifications,
4771
- email: !!this.email
4772
- },
4773
- companyMembers: !!this.companyAccess
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(flow_definition_entity/* .FlowDefinition */.G)).find({
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 common_.ConflictException({
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: message_keys/* .FLOW_MESSAGES.CALLED_BY_OTHER_FLOWS */.wu.CALLED_BY_OTHER_FLOWS,
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,flow_types/* .flowEndpoints */.Xr)(after).map((e)=>e.path));
4863
- const removed = (0,flow_types/* .flowEndpoints */.Xr)(before).map((e)=>e.path).filter((path)=>!kept.has(path));
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(flow_definition_entity/* .FlowDefinition */.G)).find({
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 common_.ConflictException({
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: message_keys/* .FLOW_MESSAGES.ENDPOINT_CALLED_BY_OTHER_FLOWS */.wu.ENDPOINT_CALLED_BY_OTHER_FLOWS,
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 common_.BadRequestException({
4225
+ throw new _nestjs_common__rspack_import_3.BadRequestException({
4890
4226
  message: 'The flow has problems.',
4891
- messageKey: message_keys/* .FLOW_MESSAGES.INVALID */.wu.INVALID,
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(flow_definition_entity/* .FlowDefinition */.G)).findOne({
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 common_.ConflictException({
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: message_keys/* .FLOW_MESSAGES.SLUG_TAKEN */.wu.SLUG_TAKEN,
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 (runsAsSystem(settings)) await this.assertHasPermission(user, nestjs_shared_.FLOW_DEFINITION_PERMISSIONS.SYSTEM);
4918
- if (settings.nodes.some((node)=>node?.type === 'code')) await this.assertHasPermission(user, nestjs_shared_.FLOW_DEFINITION_PERMISSIONS.CODE);
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, nestjs_shared_.FLOW_DEFINITION_PERMISSIONS.CREATE);
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 URL its own execute permission.
4927
- */ async assertMayTest(settings, endpoint, user, run) {
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 ? nestjs_shared_.FLOW_DEFINITION_PERMISSIONS.UPDATE : nestjs_shared_.FLOW_DEFINITION_PERMISSIONS.CREATE);
4931
- if (endpoint?.authMode === 'permission') await this.assertHasPermission(user, endpoint.permissionCode || defaultFlowPermissionCode(settings.slug));
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
- d.nodes = (0,flow_api_key/* .sealApiKeys */.ue)(d.nodes);
4942
- d.version = 0;
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 settings = toFlowSettings({
4954
- ...workingCopy(existing),
4289
+ const merged = toFlowSettings({
4290
+ ...existing,
4955
4291
  ...stripUndefined(d)
4956
4292
  });
4957
- await this.assertSaveable(settings, user, existing.id);
4958
- if (!isPublished(existing)) await this.assertCallersKept(existing, settings, {
4959
- isActive: d.isActive ?? existing.isActive,
4960
- version: existing.version
4961
- });
4962
- if (d.nodes) d.nodes = (0,flow_api_key/* .sealApiKeys */.ue)(d.nodes);
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(flow_definition_entity/* .FlowDefinition */.G)).find({
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,external_typeorm_.In)(ids)
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
- /** The execute permissions a published flow's URLs ask for (the flow's own and any a Request step sets), registered so they can be granted. */ async provisionPermissions(flows) {
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
- const actions = new Map();
5132
- for (const flow of flows){
5133
- for (const endpoint of (0,flow_types/* .flowEndpoints */.Xr)(flow)){
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,common_.Injectable)({
5149
- scope: common_.Scope.REQUEST
4332
+ (0,_nestjs_common__rspack_import_3.Injectable)({
4333
+ scope: _nestjs_common__rspack_import_3.Scope.REQUEST
5150
4334
  }),
5151
- _ts_param(0, (0,common_.Inject)('CACHE_INSTANCE')),
5152
- _ts_param(1, (0,common_.Inject)(modules_.UtilsService)),
5153
- _ts_param(2, (0,common_.Inject)(entity_builder_datasource_provider/* .EntityBuilderDataSourceProvider */.D)),
5154
- _ts_param(3, (0,common_.Inject)(modules_.SharedPermissionCacheService)),
5155
- _ts_param(4, (0,common_.Optional)()),
5156
- _ts_param(4, (0,common_.Inject)(nestjs_shared_.PERMISSION_ACTION_REGISTRY)),
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 classes_.HybridCache === "undefined" ? Object : classes_.HybridCache,
5166
- typeof modules_.UtilsService === "undefined" ? Object : modules_.UtilsService,
5167
- typeof entity_builder_datasource_provider/* .EntityBuilderDataSourceProvider */.D === "undefined" ? Object : entity_builder_datasource_provider/* .EntityBuilderDataSourceProvider */.D,
5168
- typeof modules_.SharedPermissionCacheService === "undefined" ? Object : modules_.SharedPermissionCacheService,
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 + 1 modules
5621
- var rule_engine = __webpack_require__(8429);
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 + 1 modules
5627
- var flow_definition_service = __webpack_require__(4921);
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 Request step 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;
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, companyAccess, notifications, email){
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(flow, options) {
4871
+ async run(definition, options) {
5707
4872
  const startedAt = Date.now();
5708
- const start = (0,flow_types/* .startEndpoint */.IE)(flow, options.startAt);
5709
- const runAs = start?.runAs ?? 'caller';
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 + flowTimeout(start?.timeoutMs),
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, start?.isTransactional === true, state, this.createEnv());
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 run whose Request step
5773
- * is transactional (or any test run) gets its own, and its held-back events are published after the commit.
5774
- */ async execute(flow, transactional, state, env) {
5775
- if (state.qr || !(transactional || state.mode === 'dry_run')) {
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: start.authMode === 'internal' ? parent.runAs : start.runAs,
5883
- // A function inherits the caller's grant; any other called flow is a saved flow whose Request steps' run-as was checked when it was saved.
5884
- systemAuthorized: start.authMode === 'internal' ? parent.systemAuthorized === true : start.runAs === 'system',
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(start.timeoutMs)),
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, start.isTransactional, child, env);
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 the URLs that caller could call directly: public and signed-in ones,
5942
- * and permission ones when the caller holds the permission - never an API-key one.
5943
- */ async assertMayCall(flow, endpoint, parent, env) {
5944
- const mode = endpoint.authMode;
5945
- if (parent.runAs === 'system' && parent.systemAuthorized === true || mode === 'public' || mode === 'internal') return;
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: mode
5950
- }, `Flow '${flow.slug}' (${mode}) cannot be called by this caller.`);
5109
+ authMode: flow.authMode
5110
+ }, `Flow '${flow.slug}' (${flow.authMode}) cannot be called by this caller.`);
5951
5111
  }
5952
- if (mode === 'permission') await env.assertPermission(endpoint.permissionCode || (0,flow_definition_service/* .defaultFlowPermissionCode */.Er)(flow.slug), parent.user);
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 and messages go out only for what was saved. A failing publish or send never turns a completed run into an error. */ async publishPendingEvents(events, user) {
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__(4921);
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 never published is not live yet: it looks the same as an unknown one. */ async findActive(slug) {
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
- version: (0,typeorm__rspack_import_1.MoreThan)(0)
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 a Request step as `runAs: system` needed the system permission.
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(settings, endpoint, user, {
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);