@rytass/bpm-core-nestjs-module 0.20.1 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -0
- package/README.md +109 -5
- package/package.json +2 -2
- package/src/lib/attachment/attachment.service.js +2 -10
- package/src/lib/attachment/attachment.service.js.map +1 -1
- package/src/lib/attachment/file-upload-value-ids.d.ts +8 -0
- package/src/lib/attachment/file-upload-value-ids.js +15 -0
- package/src/lib/attachment/file-upload-value-ids.js.map +1 -0
- package/src/lib/bpm/bpm-root-options.d.ts +18 -0
- package/src/lib/bpm/bpm-root-options.js.map +1 -1
- package/src/lib/bpm/bpm-root.module.d.ts +11 -0
- package/src/lib/bpm/bpm-root.module.js +9 -4
- package/src/lib/bpm/bpm-root.module.js.map +1 -1
- package/src/lib/form/form-data-issue.d.ts +34 -0
- package/src/lib/form/form-data-issue.js +59 -0
- package/src/lib/form/form-data-issue.js.map +1 -0
- package/src/lib/form/form-member-value.validator.d.ts +2 -2
- package/src/lib/form/form-member-value.validator.js +2 -3
- package/src/lib/form/form-member-value.validator.js.map +1 -1
- package/src/lib/form/form-org-unit-value.validator.d.ts +2 -2
- package/src/lib/form/form-org-unit-value.validator.js +4 -1
- package/src/lib/form/form-org-unit-value.validator.js.map +1 -1
- package/src/lib/form/form-schema.validator.js +40 -0
- package/src/lib/form/form-schema.validator.js.map +1 -1
- package/src/lib/form-data-source/form-data-source.module.d.ts +8 -0
- package/src/lib/form-data-source/form-data-source.module.js +1 -1
- package/src/lib/form-data-source/form-data-source.module.js.map +1 -1
- package/src/lib/form-data-source/form-data-source.service.js +1 -1
- package/src/lib/form-data-source/form-data-source.service.js.map +1 -1
- package/src/lib/migrations/0000000031000-approval-instance-form-data-gin.d.ts +29 -0
- package/src/lib/migrations/0000000031000-approval-instance-form-data-gin.js +44 -0
- package/src/lib/migrations/0000000031000-approval-instance-form-data-gin.js.map +1 -0
- package/src/lib/migrations/index.d.ts +1 -0
- package/src/lib/migrations/index.js +3 -0
- package/src/lib/migrations/index.js.map +1 -1
- package/src/lib/notification/notification.service.js +6 -0
- package/src/lib/notification/notification.service.js.map +1 -1
- package/src/lib/organization/organization-time-zone.d.ts +4 -2
- package/src/lib/organization/organization-time-zone.js +3 -6
- package/src/lib/organization/organization-time-zone.js.map +1 -1
- package/src/lib/template/filterable-field-guard.d.ts +49 -0
- package/src/lib/template/filterable-field-guard.js +141 -0
- package/src/lib/template/filterable-field-guard.js.map +1 -0
- package/src/lib/template/filterable-field-issue.object.d.ts +21 -0
- package/src/lib/template/filterable-field-issue.object.js +65 -0
- package/src/lib/template/filterable-field-issue.object.js.map +1 -0
- package/src/lib/template/filterable-field.queries.d.ts +20 -0
- package/src/lib/template/filterable-field.queries.js +80 -0
- package/src/lib/template/filterable-field.queries.js.map +1 -0
- package/src/lib/template/index.d.ts +1 -0
- package/src/lib/template/index.js +1 -0
- package/src/lib/template/index.js.map +1 -1
- package/src/lib/template/template.module.js +2 -0
- package/src/lib/template/template.module.js.map +1 -1
- package/src/lib/template/template.service.d.ts +39 -0
- package/src/lib/template/template.service.js +218 -49
- package/src/lib/template/template.service.js.map +1 -1
- package/src/lib/template/workflow-definition.validator.js +84 -2
- package/src/lib/template/workflow-definition.validator.js.map +1 -1
- package/src/lib/workflow-engine/approval-instance-field-filter.compiler.d.ts +49 -0
- package/src/lib/workflow-engine/approval-instance-field-filter.compiler.js +501 -0
- package/src/lib/workflow-engine/approval-instance-field-filter.compiler.js.map +1 -0
- package/src/lib/workflow-engine/approval-instance-filterable-field.policy.d.ts +15 -0
- package/src/lib/workflow-engine/approval-instance-filterable-field.policy.js +20 -0
- package/src/lib/workflow-engine/approval-instance-filterable-field.policy.js.map +1 -0
- package/src/lib/workflow-engine/dto/approval-instance-field-filter.input.d.ts +15 -0
- package/src/lib/workflow-engine/dto/approval-instance-field-filter.input.js +55 -0
- package/src/lib/workflow-engine/dto/approval-instance-field-filter.input.js.map +1 -0
- package/src/lib/workflow-engine/dto/approval-instance-list-args.d.ts +9 -0
- package/src/lib/workflow-engine/dto/approval-instance-list-args.js +24 -0
- package/src/lib/workflow-engine/dto/approval-instance-list-args.js.map +1 -0
- package/src/lib/workflow-engine/dto/approval-instance-sort.input.d.ts +10 -0
- package/src/lib/workflow-engine/dto/approval-instance-sort.input.js +32 -0
- package/src/lib/workflow-engine/dto/approval-instance-sort.input.js.map +1 -0
- package/src/lib/workflow-engine/index.d.ts +1 -0
- package/src/lib/workflow-engine/index.js +1 -0
- package/src/lib/workflow-engine/index.js.map +1 -1
- package/src/lib/workflow-engine/initiator-custom-fields-resolver.token.d.ts +108 -0
- package/src/lib/workflow-engine/initiator-custom-fields-resolver.token.js +9 -0
- package/src/lib/workflow-engine/initiator-custom-fields-resolver.token.js.map +1 -0
- package/src/lib/workflow-engine/workflow-engine.enums.d.ts +13 -0
- package/src/lib/workflow-engine/workflow-engine.enums.js +22 -1
- package/src/lib/workflow-engine/workflow-engine.enums.js.map +1 -1
- package/src/lib/workflow-engine/workflow-engine.module.d.ts +2 -0
- package/src/lib/workflow-engine/workflow-engine.module.js +9 -3
- package/src/lib/workflow-engine/workflow-engine.module.js.map +1 -1
- package/src/lib/workflow-engine/workflow-engine.queries.d.ts +6 -4
- package/src/lib/workflow-engine/workflow-engine.queries.js +35 -12
- package/src/lib/workflow-engine/workflow-engine.queries.js.map +1 -1
- package/src/lib/workflow-engine/workflow-engine.service.d.ts +166 -18
- package/src/lib/workflow-engine/workflow-engine.service.js +918 -139
- package/src/lib/workflow-engine/workflow-engine.service.js.map +1 -1
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApprovalInstanceFieldFilterCompiler = void 0;
|
|
4
|
+
exports.readStaticOptionsByPath = readStaticOptionsByPath;
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const bpm_core_shared_1 = require("@rytass/bpm-core-shared");
|
|
7
|
+
const form_1 = require("@rytass/bpm-core-shared/form");
|
|
8
|
+
const DEFAULT_DIRECTION = 'DESC';
|
|
9
|
+
/** Limits on one list request; past them the query is refused, not truncated. */
|
|
10
|
+
const MAX_FIELD_FILTERS = 20;
|
|
11
|
+
const MAX_SORT_KEYS = 5;
|
|
12
|
+
const SORT_TIME_COLUMNS = {
|
|
13
|
+
submittedAt: 'started_at',
|
|
14
|
+
updatedAt: 'updated_at',
|
|
15
|
+
completedAt: 'completed_at',
|
|
16
|
+
};
|
|
17
|
+
const DECIMAL_PATTERN = /^-?\d+(\.\d+)?$/u;
|
|
18
|
+
const DATETIME_INPUT_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2})$/u;
|
|
19
|
+
const DATE_TEXT_PATTERN = '^[0-9]{4}-[0-9]{2}-[0-9]{2}$';
|
|
20
|
+
const DATETIME_TEXT_PATTERN = '^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3}Z$';
|
|
21
|
+
/** The rejection for any field the template does not declare filterable (ADR 25 §7.1). */
|
|
22
|
+
const NOT_FILTERABLE_MESSAGE = '這個欄位不能用來篩選';
|
|
23
|
+
/** One message for every unusable sort key, so the answer reveals nothing about the form. */
|
|
24
|
+
const NOT_SORTABLE_MESSAGE = '這個欄位不能用來排序';
|
|
25
|
+
class ApprovalInstanceFieldFilterCompiler {
|
|
26
|
+
compile(input) {
|
|
27
|
+
if (input.fieldFilters.length > MAX_FIELD_FILTERS) {
|
|
28
|
+
throw new common_1.BadRequestException(`篩選條件最多 ${MAX_FIELD_FILTERS} 個`);
|
|
29
|
+
}
|
|
30
|
+
if (input.sort.length > MAX_SORT_KEYS) {
|
|
31
|
+
throw new common_1.BadRequestException(`排序條件最多 ${MAX_SORT_KEYS} 個`);
|
|
32
|
+
}
|
|
33
|
+
const alias = `"${input.alias}"`;
|
|
34
|
+
const filters = input.fieldFilters.map((filter, index) => ({
|
|
35
|
+
filter: normalizeFilter(filter, input.paths),
|
|
36
|
+
index,
|
|
37
|
+
}));
|
|
38
|
+
const topLevel = filters
|
|
39
|
+
.filter(({ filter }) => filter.path.tableKey === null)
|
|
40
|
+
.map((item) => compileTopLevelCondition(alias, item, input));
|
|
41
|
+
// Conditions on one table share a row subquery: they must hold in the same row.
|
|
42
|
+
const tables = groupByTable(filters).map((group, groupIndex) => compileTableCondition(alias, group, groupIndex, input));
|
|
43
|
+
return {
|
|
44
|
+
conditions: [...topLevel, ...tables],
|
|
45
|
+
orderBy: compileOrderBy(alias, input),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.ApprovalInstanceFieldFilterCompiler = ApprovalInstanceFieldFilterCompiler;
|
|
50
|
+
/**
|
|
51
|
+
* The static option lists of a set of form schemas, by field path. A table
|
|
52
|
+
* column is keyed `<tableKey>.<columnKey>`, the way the query names it.
|
|
53
|
+
*/
|
|
54
|
+
function readStaticOptionsByPath(schemas) {
|
|
55
|
+
const grouped = new Map();
|
|
56
|
+
const add = (path, options) => {
|
|
57
|
+
grouped.set(path, [...(grouped.get(path) ?? []), ...options]);
|
|
58
|
+
};
|
|
59
|
+
schemas.forEach((schema) => {
|
|
60
|
+
if (!schema || !Array.isArray(schema.fields)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
schema.fields.forEach((field) => {
|
|
64
|
+
if ((0, form_1.isTableFieldDefinition)(field)) {
|
|
65
|
+
field.columns.forEach((column) => {
|
|
66
|
+
const asField = column;
|
|
67
|
+
if ((0, form_1.isFormStaticOptionFieldDefinition)(asField)) {
|
|
68
|
+
add(`${field.fieldKey}.${column.fieldKey}`, asField.options);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if ((0, form_1.isFormStaticOptionFieldDefinition)(field)) {
|
|
74
|
+
add(field.fieldKey, field.options);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
return grouped;
|
|
79
|
+
}
|
|
80
|
+
function normalizeFilter(filter, paths) {
|
|
81
|
+
const path = paths.find((item) => item.path === filter.fieldKey);
|
|
82
|
+
if (!path) {
|
|
83
|
+
throw new common_1.BadRequestException(NOT_FILTERABLE_MESSAGE);
|
|
84
|
+
}
|
|
85
|
+
if (!(0, bpm_core_shared_1.readFilterOperatorsForFieldType)(path.field.type).includes(filter.operator)) {
|
|
86
|
+
throw new common_1.BadRequestException(`欄位「${path.label}」不能使用 ${filter.operator} 條件篩選`);
|
|
87
|
+
}
|
|
88
|
+
const invalid = (detail) => new common_1.BadRequestException(`欄位「${path.label}」的篩選值不正確:${detail}`);
|
|
89
|
+
const normalize = (raw) => normalizeValue(path.kind, raw, invalid);
|
|
90
|
+
switch (filter.operator) {
|
|
91
|
+
case 'EQUALS':
|
|
92
|
+
case 'NOT_EQUALS':
|
|
93
|
+
case 'CONTAINS': {
|
|
94
|
+
const raw = filter.values?.[0];
|
|
95
|
+
if (!raw) {
|
|
96
|
+
throw invalid('需要一個值');
|
|
97
|
+
}
|
|
98
|
+
return emptyFilter(path, filter.operator, { value: normalize(raw) });
|
|
99
|
+
}
|
|
100
|
+
case 'IN': {
|
|
101
|
+
const raws = filter.values ?? [];
|
|
102
|
+
if (raws.length === 0 || raws.some((raw) => raw === '')) {
|
|
103
|
+
throw invalid('需要至少一個值,且不可為空字串');
|
|
104
|
+
}
|
|
105
|
+
return emptyFilter(path, filter.operator, {
|
|
106
|
+
values: raws.map(normalize),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
case 'RANGE': {
|
|
110
|
+
if (!filter.from && !filter.to) {
|
|
111
|
+
throw invalid('需要下界或上界');
|
|
112
|
+
}
|
|
113
|
+
return emptyFilter(path, filter.operator, {
|
|
114
|
+
from: filter.from ? normalize(filter.from) : null,
|
|
115
|
+
to: filter.to ? normalize(filter.to) : null,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function emptyFilter(path, operator, overrides) {
|
|
121
|
+
return {
|
|
122
|
+
from: null,
|
|
123
|
+
operator,
|
|
124
|
+
path,
|
|
125
|
+
to: null,
|
|
126
|
+
value: null,
|
|
127
|
+
values: [],
|
|
128
|
+
...overrides,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* A filter value in its stored format (ADR 25 §6). A value that cannot be
|
|
133
|
+
* written in that format is refused rather than guessed at. A datetime must
|
|
134
|
+
* carry an explicit offset, so the server's own time zone never decides what
|
|
135
|
+
* it means; it is then stored as `toISOString()`.
|
|
136
|
+
*/
|
|
137
|
+
function normalizeValue(kind, raw, invalid) {
|
|
138
|
+
// PostgreSQL text and jsonb cannot hold U+0000: such a value would fail in
|
|
139
|
+
// the database as a 500 instead of being refused here.
|
|
140
|
+
if (raw.includes('\u0000')) {
|
|
141
|
+
throw invalid('不能包含 NUL 字元');
|
|
142
|
+
}
|
|
143
|
+
switch (kind) {
|
|
144
|
+
case 'number':
|
|
145
|
+
if (!DECIMAL_PATTERN.test(raw)) {
|
|
146
|
+
throw invalid('需要十進位數字');
|
|
147
|
+
}
|
|
148
|
+
return raw;
|
|
149
|
+
case 'date':
|
|
150
|
+
if (!(0, bpm_core_shared_1.isCanonicalDate)(raw)) {
|
|
151
|
+
throw invalid('需要 YYYY-MM-DD 格式的日期');
|
|
152
|
+
}
|
|
153
|
+
return raw;
|
|
154
|
+
case 'datetime': {
|
|
155
|
+
const time = DATETIME_INPUT_PATTERN.test(raw) ? Date.parse(raw) : NaN;
|
|
156
|
+
if (!Number.isFinite(time)) {
|
|
157
|
+
throw invalid('需要含時區的 ISO 8601 時間,例如 2026-11-03T08:30:00Z');
|
|
158
|
+
}
|
|
159
|
+
return new Date(time).toISOString();
|
|
160
|
+
}
|
|
161
|
+
case 'boolean':
|
|
162
|
+
if (raw !== 'true' && raw !== 'false') {
|
|
163
|
+
throw invalid('需要 true 或 false');
|
|
164
|
+
}
|
|
165
|
+
return raw;
|
|
166
|
+
default:
|
|
167
|
+
return raw;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function compileTopLevelCondition(alias, item, input) {
|
|
171
|
+
const target = createTarget({
|
|
172
|
+
alias,
|
|
173
|
+
path: item.filter.path,
|
|
174
|
+
prefix: `ff${item.index}`,
|
|
175
|
+
rowAlias: null,
|
|
176
|
+
staticOptionsByPath: input.staticOptionsByPath,
|
|
177
|
+
filter: item.filter,
|
|
178
|
+
});
|
|
179
|
+
return compilePredicate(target, item.filter);
|
|
180
|
+
}
|
|
181
|
+
function groupByTable(filters) {
|
|
182
|
+
const tableKeys = [
|
|
183
|
+
...new Set(filters
|
|
184
|
+
.map(({ filter }) => filter.path.tableKey)
|
|
185
|
+
.filter((key) => key !== null)),
|
|
186
|
+
];
|
|
187
|
+
return tableKeys.map((tableKey) => ({
|
|
188
|
+
items: filters.filter(({ filter }) => filter.path.tableKey === tableKey),
|
|
189
|
+
tableKey,
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* "Some row of the table satisfies every condition on it" (ADR 25 §7.4): one
|
|
194
|
+
* EXISTS over the rows, with all the table's conditions inside it.
|
|
195
|
+
*/
|
|
196
|
+
function compileTableCondition(alias, group, groupIndex, input) {
|
|
197
|
+
const rowAlias = `ffrow${groupIndex}`;
|
|
198
|
+
const tableParameter = `${rowAlias}_tk`;
|
|
199
|
+
const predicates = group.items.map((item) => compilePredicate(createTarget({
|
|
200
|
+
alias,
|
|
201
|
+
filter: item.filter,
|
|
202
|
+
path: item.filter.path,
|
|
203
|
+
prefix: `ff${item.index}`,
|
|
204
|
+
rowAlias,
|
|
205
|
+
staticOptionsByPath: input.staticOptionsByPath,
|
|
206
|
+
}), item.filter));
|
|
207
|
+
const rows = `CASE WHEN jsonb_typeof(${alias}."form_data" -> :${tableParameter}) = 'array' THEN ${alias}."form_data" -> :${tableParameter} ELSE CAST('[]' AS jsonb) END`;
|
|
208
|
+
return {
|
|
209
|
+
parameters: mergeParameters([
|
|
210
|
+
{ [tableParameter]: group.tableKey },
|
|
211
|
+
...predicates.map((predicate) => predicate.parameters),
|
|
212
|
+
]),
|
|
213
|
+
sql: `EXISTS (SELECT 1 FROM jsonb_array_elements(${rows}) ${rowAlias} WHERE ${predicates
|
|
214
|
+
.map((predicate) => predicate.sql)
|
|
215
|
+
.join(' AND ')})`,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function createTarget(input) {
|
|
219
|
+
const { alias, filter, path, prefix, rowAlias, staticOptionsByPath } = input;
|
|
220
|
+
const keyParameter = `${prefix}_key`;
|
|
221
|
+
const labelValues = labelValuesFor(filter, staticOptionsByPath);
|
|
222
|
+
if (rowAlias === null) {
|
|
223
|
+
const column = `${alias}."form_data"`;
|
|
224
|
+
return {
|
|
225
|
+
formData: { column, key: path.key },
|
|
226
|
+
json: `(${column} -> :${keyParameter})`,
|
|
227
|
+
labelValues,
|
|
228
|
+
optionSnapshot: path.usesOptionSnapshot
|
|
229
|
+
? `${alias}."form_data_option_snapshot"`
|
|
230
|
+
: null,
|
|
231
|
+
parameters: { [keyParameter]: path.key },
|
|
232
|
+
prefix,
|
|
233
|
+
text: `(${column} ->> :${keyParameter})`,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
formData: null,
|
|
238
|
+
json: `(${rowAlias} -> :${keyParameter})`,
|
|
239
|
+
labelValues,
|
|
240
|
+
optionSnapshot: null,
|
|
241
|
+
parameters: { [keyParameter]: path.key },
|
|
242
|
+
prefix,
|
|
243
|
+
text: `(${rowAlias} ->> :${keyParameter})`,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
/** The stored values whose option name contains the CONTAINS text. */
|
|
247
|
+
function labelValuesFor(filter, staticOptionsByPath) {
|
|
248
|
+
if (filter.operator !== 'CONTAINS' ||
|
|
249
|
+
filter.path.usesOptionSnapshot ||
|
|
250
|
+
filter.value === null) {
|
|
251
|
+
return [];
|
|
252
|
+
}
|
|
253
|
+
const needle = filter.value.toLocaleLowerCase();
|
|
254
|
+
return (staticOptionsByPath.get(filter.path.path) ?? [])
|
|
255
|
+
.filter((option) => option.label.toLocaleLowerCase().includes(needle))
|
|
256
|
+
.map((option) => option.value);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* One condition on one target. The target's own key parameter is part of the
|
|
260
|
+
* SQL it emits, so it travels with the predicate.
|
|
261
|
+
*/
|
|
262
|
+
function compilePredicate(target, filter) {
|
|
263
|
+
const predicate = compileOperator(target, filter);
|
|
264
|
+
return {
|
|
265
|
+
parameters: referencedParameters(mergeParameters([target.parameters, predicate.parameters]), predicate.sql),
|
|
266
|
+
sql: predicate.sql,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
/** Only the parameters the SQL text names. A key the containment form embeds is not one of them. */
|
|
270
|
+
function referencedParameters(parameters, sql) {
|
|
271
|
+
return Object.fromEntries(Object.entries(parameters).filter(([name]) => new RegExp(`:${name}(?![A-Za-z0-9_])`, 'u').test(sql)));
|
|
272
|
+
}
|
|
273
|
+
function compileOperator(target, filter) {
|
|
274
|
+
const kind = filter.path.kind;
|
|
275
|
+
switch (filter.operator) {
|
|
276
|
+
case 'EQUALS':
|
|
277
|
+
case 'IN':
|
|
278
|
+
return equalsAny(target, kind, filter.values.length > 0 ? filter.values : [filter.value ?? '']);
|
|
279
|
+
case 'NOT_EQUALS': {
|
|
280
|
+
const equal = equalsAny(target, kind, [filter.value ?? '']);
|
|
281
|
+
// "No stored value equals it", and a field with no value matches no condition.
|
|
282
|
+
return {
|
|
283
|
+
parameters: equal.parameters,
|
|
284
|
+
sql: `(${hasValueSql(target.json)} AND NOT (${equal.sql}))`,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
case 'RANGE':
|
|
288
|
+
return rangePredicate(target, kind, filter.from, filter.to);
|
|
289
|
+
case 'CONTAINS':
|
|
290
|
+
return containsPredicate(target, kind, filter.value ?? '');
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Matches any of `values`. On a top-level field, string-like values go through
|
|
295
|
+
* the form data containment operator, which the GIN index serves (ADR 25 §4.1).
|
|
296
|
+
* A table cell is compared directly.
|
|
297
|
+
*/
|
|
298
|
+
function equalsAny(target, kind, values) {
|
|
299
|
+
const parts = values.map((value, valueIndex) => equalsOne(target, kind, value, valueIndex));
|
|
300
|
+
return {
|
|
301
|
+
parameters: mergeParameters(parts.map((part) => part.parameters)),
|
|
302
|
+
sql: `(${parts.map((part) => part.sql).join(' OR ')})`,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function equalsOne(target, kind, value, valueIndex) {
|
|
306
|
+
const name = `${target.prefix}_v${valueIndex}`;
|
|
307
|
+
if (kind === 'number') {
|
|
308
|
+
return {
|
|
309
|
+
parameters: { [name]: value },
|
|
310
|
+
sql: `${numericSql(target)} = CAST(:${name} AS numeric)`,
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
// An option or member value is stored as a string or as a list of strings
|
|
314
|
+
// (`multiple`), and both shapes match.
|
|
315
|
+
const multiShape = kind === 'option' || kind === 'member';
|
|
316
|
+
const formData = target.formData;
|
|
317
|
+
if (formData !== null) {
|
|
318
|
+
const shapes = multiShape
|
|
319
|
+
? [value, [value]]
|
|
320
|
+
: [jsonScalar(kind, value)];
|
|
321
|
+
const parts = shapes.map((shape, shapeIndex) => {
|
|
322
|
+
const shapeName = `${name}_s${shapeIndex}`;
|
|
323
|
+
return {
|
|
324
|
+
parameters: {
|
|
325
|
+
[shapeName]: JSON.stringify({ [formData.key]: shape }),
|
|
326
|
+
},
|
|
327
|
+
sql: `${formData.column} @> CAST(:${shapeName} AS jsonb)`,
|
|
328
|
+
};
|
|
329
|
+
});
|
|
330
|
+
return {
|
|
331
|
+
parameters: mergeParameters(parts.map((part) => part.parameters)),
|
|
332
|
+
sql: `(${parts.map((part) => part.sql).join(' OR ')})`,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
if (multiShape) {
|
|
336
|
+
return {
|
|
337
|
+
parameters: { [name]: JSON.stringify([value]) },
|
|
338
|
+
sql: `${storedArraySql(target.json)} @> CAST(:${name} AS jsonb)`,
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
parameters: { [name]: JSON.stringify(jsonScalar(kind, value)) },
|
|
343
|
+
sql: `${target.json} = CAST(:${name} AS jsonb)`,
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function jsonScalar(kind, value) {
|
|
347
|
+
return kind === 'boolean' ? value === 'true' : value;
|
|
348
|
+
}
|
|
349
|
+
function rangePredicate(target, kind, from, to) {
|
|
350
|
+
const isNumber = kind === 'number';
|
|
351
|
+
// Dates and datetimes compare as text: their canonical forms sort in time
|
|
352
|
+
// order. The pattern keeps any value outside that form out of the comparison.
|
|
353
|
+
const pattern = kind === 'date' ? DATE_TEXT_PATTERN : DATETIME_TEXT_PATTERN;
|
|
354
|
+
const patternName = `${target.prefix}_re`;
|
|
355
|
+
const expression = isNumber
|
|
356
|
+
? numericSql(target)
|
|
357
|
+
: stringSql(target, patternName);
|
|
358
|
+
const bounds = [
|
|
359
|
+
from !== null
|
|
360
|
+
? { name: `${target.prefix}_from`, operator: '>=', value: from }
|
|
361
|
+
: null,
|
|
362
|
+
to !== null
|
|
363
|
+
? { name: `${target.prefix}_to`, operator: '<=', value: to }
|
|
364
|
+
: null,
|
|
365
|
+
].filter(isPresent);
|
|
366
|
+
const operand = (name) => isNumber ? `CAST(:${name} AS numeric)` : `:${name}`;
|
|
367
|
+
return {
|
|
368
|
+
parameters: mergeParameters([
|
|
369
|
+
isNumber ? {} : { [patternName]: pattern },
|
|
370
|
+
Object.fromEntries(bounds.map((bound) => [bound.name, bound.value])),
|
|
371
|
+
]),
|
|
372
|
+
sql: `(${bounds
|
|
373
|
+
.map((bound) => `${expression} ${bound.operator} ${operand(bound.name)}`)
|
|
374
|
+
.join(' AND ')})`,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function containsPredicate(target, kind, value) {
|
|
378
|
+
const patternName = `${target.prefix}_pat`;
|
|
379
|
+
const pattern = `%${escapeLikePattern(value)}%`;
|
|
380
|
+
if (kind === 'text') {
|
|
381
|
+
return {
|
|
382
|
+
parameters: { [patternName]: pattern },
|
|
383
|
+
sql: `(jsonb_typeof(${target.json}) = 'string' AND ${target.text} ILIKE :${patternName})`,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
// An option matches by its stored value and, where its name is known, by
|
|
387
|
+
// its name: the option snapshot for a data-source field, the static option
|
|
388
|
+
// lists otherwise.
|
|
389
|
+
const valueMatch = `EXISTS (SELECT 1 FROM jsonb_array_elements_text(${storedArraySql(target.json)}) ${target.prefix}v WHERE ${target.prefix}v ILIKE :${patternName})`;
|
|
390
|
+
const snapshotMatch = target.optionSnapshot === null
|
|
391
|
+
? null
|
|
392
|
+
: `EXISTS (SELECT 1 FROM jsonb_array_elements(CASE WHEN jsonb_typeof(${target.optionSnapshot} -> :${target.prefix}_key -> 'options') = 'array' THEN ${target.optionSnapshot} -> :${target.prefix}_key -> 'options' ELSE CAST('[]' AS jsonb) END) ${target.prefix}o WHERE ${target.prefix}o ->> 'label' ILIKE :${patternName} AND ${storedArraySql(target.json)} @> jsonb_build_array(${target.prefix}o ->> 'value'))`;
|
|
393
|
+
const labelMatches = target.labelValues.map((stored, labelIndex) => {
|
|
394
|
+
const name = `${target.prefix}_l${labelIndex}`;
|
|
395
|
+
return {
|
|
396
|
+
parameters: { [name]: JSON.stringify([stored]) },
|
|
397
|
+
sql: `${storedArraySql(target.json)} @> CAST(:${name} AS jsonb)`,
|
|
398
|
+
};
|
|
399
|
+
});
|
|
400
|
+
const labelSql = labelMatches.length === 0
|
|
401
|
+
? []
|
|
402
|
+
: [`(${labelMatches.map((match) => match.sql).join(' OR ')})`];
|
|
403
|
+
return {
|
|
404
|
+
parameters: mergeParameters([
|
|
405
|
+
{ [patternName]: pattern },
|
|
406
|
+
...labelMatches.map((match) => match.parameters),
|
|
407
|
+
]),
|
|
408
|
+
sql: `(${[valueMatch, ...(snapshotMatch ? [snapshotMatch] : []), ...labelSql].join(' OR ')})`,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
function compileOrderBy(alias, input) {
|
|
412
|
+
const idColumn = `${alias}."id"`;
|
|
413
|
+
if (input.sort.length === 0) {
|
|
414
|
+
return [
|
|
415
|
+
{ direction: 'DESC', parameters: {}, sql: `${alias}."created_at"` },
|
|
416
|
+
{ direction: 'DESC', parameters: {}, sql: idColumn },
|
|
417
|
+
];
|
|
418
|
+
}
|
|
419
|
+
const orders = input.sort.map((sort, index) => {
|
|
420
|
+
const direction = sort.direction ?? DEFAULT_DIRECTION;
|
|
421
|
+
if ((0, bpm_core_shared_1.isApprovalInstanceSortTimeField)(sort.field)) {
|
|
422
|
+
return {
|
|
423
|
+
direction,
|
|
424
|
+
parameters: {},
|
|
425
|
+
sql: `${alias}."${SORT_TIME_COLUMNS[sort.field]}"`,
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
const path = input.paths.find((item) => item.path === sort.field);
|
|
429
|
+
if (!path || !(0, bpm_core_shared_1.isFilterableFieldSortable)(path)) {
|
|
430
|
+
throw new common_1.BadRequestException(NOT_SORTABLE_MESSAGE);
|
|
431
|
+
}
|
|
432
|
+
const target = createTarget({
|
|
433
|
+
alias,
|
|
434
|
+
filter: emptyFilter(path, 'EQUALS', {}),
|
|
435
|
+
path,
|
|
436
|
+
prefix: `fs${index}`,
|
|
437
|
+
rowAlias: null,
|
|
438
|
+
staticOptionsByPath: new Map(),
|
|
439
|
+
});
|
|
440
|
+
return { direction, ...compileSortKey(target, path.kind) };
|
|
441
|
+
});
|
|
442
|
+
// The id breaks ties, in the direction of the last sort key.
|
|
443
|
+
const lastDirection = orders[orders.length - 1]?.direction ?? DEFAULT_DIRECTION;
|
|
444
|
+
return [
|
|
445
|
+
...orders,
|
|
446
|
+
{ direction: lastDirection, parameters: {}, sql: idColumn },
|
|
447
|
+
];
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* The sort key of a top-level field: its value when the value has the
|
|
451
|
+
* expected type, `NULL` otherwise, so a stray value sorts with the missing
|
|
452
|
+
* ones instead of failing the query.
|
|
453
|
+
*/
|
|
454
|
+
function compileSortKey(target, kind) {
|
|
455
|
+
if (kind === 'number') {
|
|
456
|
+
return { parameters: target.parameters, sql: numericSql(target) };
|
|
457
|
+
}
|
|
458
|
+
if (kind === 'date' || kind === 'datetime') {
|
|
459
|
+
const pattern = kind === 'date' ? DATE_TEXT_PATTERN : DATETIME_TEXT_PATTERN;
|
|
460
|
+
const patternName = `${target.prefix}_re`;
|
|
461
|
+
return {
|
|
462
|
+
parameters: { ...target.parameters, [patternName]: pattern },
|
|
463
|
+
sql: stringSql(target, patternName),
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
if (kind === 'boolean') {
|
|
467
|
+
return {
|
|
468
|
+
parameters: target.parameters,
|
|
469
|
+
sql: `CASE WHEN jsonb_typeof(${target.json}) = 'boolean' THEN ${target.text} END`,
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
return {
|
|
473
|
+
parameters: target.parameters,
|
|
474
|
+
sql: `CASE WHEN jsonb_typeof(${target.json}) = 'string' THEN ${target.text} END`,
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
function numericSql(target) {
|
|
478
|
+
return `CAST(CASE WHEN jsonb_typeof(${target.json}) = 'number' THEN ${target.text} END AS numeric)`;
|
|
479
|
+
}
|
|
480
|
+
function stringSql(target, patternName) {
|
|
481
|
+
return `CASE WHEN jsonb_typeof(${target.json}) = 'string' AND ${target.text} ~ :${patternName} THEN ${target.text} END`;
|
|
482
|
+
}
|
|
483
|
+
/** The stored value as an array, so one containment test covers a string and a list. */
|
|
484
|
+
function storedArraySql(json) {
|
|
485
|
+
return `CASE WHEN jsonb_typeof(${json}) = 'array' THEN ${json} ELSE jsonb_build_array(${json}) END`;
|
|
486
|
+
}
|
|
487
|
+
/** Has a value: not missing, not `null`, not `""`, not `[]` (ADR 25 §5.4). */
|
|
488
|
+
function hasValueSql(json) {
|
|
489
|
+
return `(${json} IS NOT NULL AND ${json} NOT IN (CAST('null' AS jsonb), CAST('""' AS jsonb), CAST('[]' AS jsonb)))`;
|
|
490
|
+
}
|
|
491
|
+
/** The pattern for ILIKE: `%`, `_` and the escape character itself are escaped. */
|
|
492
|
+
function escapeLikePattern(value) {
|
|
493
|
+
return value.replace(/[\\%_]/gu, (character) => `\\${character}`);
|
|
494
|
+
}
|
|
495
|
+
function isPresent(value) {
|
|
496
|
+
return value !== null;
|
|
497
|
+
}
|
|
498
|
+
function mergeParameters(parts) {
|
|
499
|
+
return parts.reduce((merged, part) => ({ ...merged, ...part }), {});
|
|
500
|
+
}
|
|
501
|
+
//# sourceMappingURL=approval-instance-field-filter.compiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-instance-field-filter.compiler.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/workflow-engine/approval-instance-field-filter.compiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type FilterableFieldPath } from '@rytass/bpm-core-shared';
|
|
2
|
+
import type { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
|
|
3
|
+
import type { BPMAuthContext } from '../bpm-auth';
|
|
4
|
+
/**
|
|
5
|
+
* Which form fields a viewer may filter and sort the approval-instance list
|
|
6
|
+
* by (ADR 25 §8.2). Internal: not exported from the library's public index.
|
|
7
|
+
*
|
|
8
|
+
* v1 answers with every field the template's current version marks
|
|
9
|
+
* filterable, which is what the query did before this seam existed. Server-side
|
|
10
|
+
* field masking (a field a viewer may not see must not be a filter either)
|
|
11
|
+
* would replace this class; the query and the public API would not change.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ApprovalInstanceFilterableFieldPolicy {
|
|
14
|
+
readFilterableFieldPaths(_scope: BPMAuthContext | undefined, schema: FormDefinitionSchema | null | undefined): readonly FilterableFieldPath[];
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApprovalInstanceFilterableFieldPolicy = void 0;
|
|
4
|
+
const bpm_core_shared_1 = require("@rytass/bpm-core-shared");
|
|
5
|
+
/**
|
|
6
|
+
* Which form fields a viewer may filter and sort the approval-instance list
|
|
7
|
+
* by (ADR 25 §8.2). Internal: not exported from the library's public index.
|
|
8
|
+
*
|
|
9
|
+
* v1 answers with every field the template's current version marks
|
|
10
|
+
* filterable, which is what the query did before this seam existed. Server-side
|
|
11
|
+
* field masking (a field a viewer may not see must not be a filter either)
|
|
12
|
+
* would replace this class; the query and the public API would not change.
|
|
13
|
+
*/
|
|
14
|
+
class ApprovalInstanceFilterableFieldPolicy {
|
|
15
|
+
readFilterableFieldPaths(_scope, schema) {
|
|
16
|
+
return (0, bpm_core_shared_1.readFilterableFieldPaths)(schema);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.ApprovalInstanceFilterableFieldPolicy = ApprovalInstanceFilterableFieldPolicy;
|
|
20
|
+
//# sourceMappingURL=approval-instance-filterable-field.policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-instance-filterable-field.policy.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/workflow-engine/approval-instance-filterable-field.policy.ts"],"names":[],"mappings":";;;AAAA,6DAGiC;AAIjC;;;;;;;;GAQG;AACH,MAAa,qCAAqC;IAChD,wBAAwB,CACtB,MAAkC,EAClC,MAA+C;QAE/C,OAAO,IAAA,0CAAwB,EAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;CACF;AAPD,sFAOC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ApprovalInstanceFieldFilterOperatorEnum } from '../workflow-engine.enums';
|
|
2
|
+
/**
|
|
3
|
+
* One condition on a form field of the approval-instance list (ADR 25 §7.1).
|
|
4
|
+
* `fieldKey` is a top-level fieldKey, or `<tableKey>.<columnKey>` for a table
|
|
5
|
+
* column. EQUALS, NOT_EQUALS and CONTAINS read `values[0]`; IN reads every
|
|
6
|
+
* value; RANGE reads `from` and `to`. The value formats are checked by the
|
|
7
|
+
* compiler against the field's type, not here.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ApprovalInstanceFieldFilterInput {
|
|
10
|
+
fieldKey: string;
|
|
11
|
+
operator: ApprovalInstanceFieldFilterOperatorEnum;
|
|
12
|
+
values?: readonly string[] | null;
|
|
13
|
+
from?: string | null;
|
|
14
|
+
to?: string | null;
|
|
15
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApprovalInstanceFieldFilterInput = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const graphql_1 = require("@nestjs/graphql");
|
|
6
|
+
const class_validator_1 = require("class-validator");
|
|
7
|
+
const workflow_engine_enums_1 = require("../workflow-engine.enums");
|
|
8
|
+
/**
|
|
9
|
+
* One condition on a form field of the approval-instance list (ADR 25 §7.1).
|
|
10
|
+
* `fieldKey` is a top-level fieldKey, or `<tableKey>.<columnKey>` for a table
|
|
11
|
+
* column. EQUALS, NOT_EQUALS and CONTAINS read `values[0]`; IN reads every
|
|
12
|
+
* value; RANGE reads `from` and `to`. The value formats are checked by the
|
|
13
|
+
* compiler against the field's type, not here.
|
|
14
|
+
*/
|
|
15
|
+
let ApprovalInstanceFieldFilterInput = class ApprovalInstanceFieldFilterInput {
|
|
16
|
+
};
|
|
17
|
+
exports.ApprovalInstanceFieldFilterInput = ApprovalInstanceFieldFilterInput;
|
|
18
|
+
tslib_1.__decorate([
|
|
19
|
+
(0, graphql_1.Field)(() => String),
|
|
20
|
+
(0, class_validator_1.IsString)(),
|
|
21
|
+
(0, class_validator_1.IsNotEmpty)(),
|
|
22
|
+
(0, class_validator_1.MaxLength)(200),
|
|
23
|
+
tslib_1.__metadata("design:type", String)
|
|
24
|
+
], ApprovalInstanceFieldFilterInput.prototype, "fieldKey", void 0);
|
|
25
|
+
tslib_1.__decorate([
|
|
26
|
+
(0, graphql_1.Field)(() => workflow_engine_enums_1.ApprovalInstanceFieldFilterOperatorEnum),
|
|
27
|
+
(0, class_validator_1.IsEnum)(workflow_engine_enums_1.ApprovalInstanceFieldFilterOperatorEnum),
|
|
28
|
+
tslib_1.__metadata("design:type", String)
|
|
29
|
+
], ApprovalInstanceFieldFilterInput.prototype, "operator", void 0);
|
|
30
|
+
tslib_1.__decorate([
|
|
31
|
+
(0, graphql_1.Field)(() => [String], { nullable: true }),
|
|
32
|
+
(0, class_validator_1.IsOptional)(),
|
|
33
|
+
(0, class_validator_1.ArrayMaxSize)(100),
|
|
34
|
+
(0, class_validator_1.IsString)({ each: true }),
|
|
35
|
+
(0, class_validator_1.MaxLength)(500, { each: true }),
|
|
36
|
+
tslib_1.__metadata("design:type", Object)
|
|
37
|
+
], ApprovalInstanceFieldFilterInput.prototype, "values", void 0);
|
|
38
|
+
tslib_1.__decorate([
|
|
39
|
+
(0, graphql_1.Field)(() => String, { nullable: true }),
|
|
40
|
+
(0, class_validator_1.IsOptional)(),
|
|
41
|
+
(0, class_validator_1.IsString)(),
|
|
42
|
+
(0, class_validator_1.MaxLength)(500),
|
|
43
|
+
tslib_1.__metadata("design:type", Object)
|
|
44
|
+
], ApprovalInstanceFieldFilterInput.prototype, "from", void 0);
|
|
45
|
+
tslib_1.__decorate([
|
|
46
|
+
(0, graphql_1.Field)(() => String, { nullable: true }),
|
|
47
|
+
(0, class_validator_1.IsOptional)(),
|
|
48
|
+
(0, class_validator_1.IsString)(),
|
|
49
|
+
(0, class_validator_1.MaxLength)(500),
|
|
50
|
+
tslib_1.__metadata("design:type", Object)
|
|
51
|
+
], ApprovalInstanceFieldFilterInput.prototype, "to", void 0);
|
|
52
|
+
exports.ApprovalInstanceFieldFilterInput = ApprovalInstanceFieldFilterInput = tslib_1.__decorate([
|
|
53
|
+
(0, graphql_1.InputType)()
|
|
54
|
+
], ApprovalInstanceFieldFilterInput);
|
|
55
|
+
//# sourceMappingURL=approval-instance-field-filter.input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-instance-field-filter.input.js","sourceRoot":"","sources":["../../../../../../../libs/bpm-core/src/lib/workflow-engine/dto/approval-instance-field-filter.input.ts"],"names":[],"mappings":";;;;AAAA,6CAAmD;AACnD,qDAOyB;AACzB,oEAAmF;AAEnF;;;;;;GAMG;AAEI,IAAM,gCAAgC,GAAtC,MAAM,gCAAgC;CA6B5C,CAAA;AA7BY,4EAAgC;AAK3C;IAJC,IAAA,eAAK,EAAC,GAAG,EAAE,CAAC,MAAM,CAAC;IACnB,IAAA,0BAAQ,GAAE;IACV,IAAA,4BAAU,GAAE;IACZ,IAAA,2BAAS,EAAC,GAAG,CAAC;;kEACG;AAIlB;IAFC,IAAA,eAAK,EAAC,GAAG,EAAE,CAAC,+DAAuC,CAAC;IACpD,IAAA,wBAAM,EAAC,+DAAuC,CAAC;;kEACG;AAOnD;IALC,IAAA,eAAK,EAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACzC,IAAA,4BAAU,GAAE;IACZ,IAAA,8BAAY,EAAC,GAAG,CAAC;IACjB,IAAA,0BAAQ,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,IAAA,2BAAS,EAAC,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;;gEACG;AAMlC;IAJC,IAAA,eAAK,EAAC,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACvC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,GAAG,CAAC;;8DACM;AAMrB;IAJC,IAAA,eAAK,EAAC,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACvC,IAAA,4BAAU,GAAE;IACZ,IAAA,0BAAQ,GAAE;IACV,IAAA,2BAAS,EAAC,GAAG,CAAC;;4DACI;2CA5BR,gCAAgC;IAD5C,IAAA,mBAAS,GAAE;GACC,gCAAgC,CA6B5C"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ApprovalInstanceFieldFilter, ApprovalInstanceSort } from '@rytass/bpm-core-shared';
|
|
2
|
+
import type { ApprovalInstanceFieldFilterInput } from './approval-instance-field-filter.input';
|
|
3
|
+
import type { ApprovalInstanceSortInput } from './approval-instance-sort.input';
|
|
4
|
+
/**
|
|
5
|
+
* Maps the GraphQL inputs of the approval-instance list onto the shared filter
|
|
6
|
+
* types the service takes. An absent list stays absent; `null` members drop out.
|
|
7
|
+
*/
|
|
8
|
+
export declare function toApprovalInstanceFieldFilters(filters: readonly ApprovalInstanceFieldFilterInput[] | null): readonly ApprovalInstanceFieldFilter[] | undefined;
|
|
9
|
+
export declare function toApprovalInstanceSorts(sorts: readonly ApprovalInstanceSortInput[] | null): readonly ApprovalInstanceSort[] | undefined;
|