@rytass/bpm-core-client 0.5.0 → 0.6.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 (64) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/package.json +4 -3
  3. package/src/index.js +8 -0
  4. package/src/index.js.map +1 -0
  5. package/src/lib/api-auth-client.d.ts +73 -0
  6. package/src/lib/api-auth-client.js +129 -0
  7. package/src/lib/api-auth-client.js.map +1 -0
  8. package/src/lib/client-config.d.ts +81 -0
  9. package/src/lib/client-config.js +63 -0
  10. package/src/lib/client-config.js.map +1 -0
  11. package/src/lib/form/form-api.d.ts +54 -0
  12. package/src/lib/form/form-api.js +240 -0
  13. package/src/lib/form/form-api.js.map +1 -0
  14. package/src/lib/form/form-rendering.d.ts +52 -0
  15. package/src/lib/form/form-rendering.js +351 -0
  16. package/src/lib/form/form-rendering.js.map +1 -0
  17. package/src/lib/form/index.js +6 -0
  18. package/src/lib/form/index.js.map +1 -0
  19. package/src/lib/graphql-client.d.ts +45 -0
  20. package/src/lib/graphql-client.js +101 -0
  21. package/src/lib/graphql-client.js.map +1 -0
  22. package/src/lib/member-api.d.ts +49 -0
  23. package/src/lib/member-api.js +72 -0
  24. package/src/lib/member-api.js.map +1 -0
  25. package/src/lib/organization/index.js +5 -0
  26. package/src/lib/organization/index.js.map +1 -0
  27. package/src/lib/organization/organization-api.d.ts +173 -0
  28. package/src/lib/organization/organization-api.js +394 -0
  29. package/src/lib/organization/organization-api.js.map +1 -0
  30. package/src/lib/template/index.js +5 -0
  31. package/src/lib/template/index.js.map +1 -0
  32. package/src/lib/template/template-api.d.ts +174 -0
  33. package/src/lib/template/template-api.js +469 -0
  34. package/src/lib/template/template-api.js.map +1 -0
  35. package/src/lib/workflow/index.js +5 -0
  36. package/src/lib/workflow/index.js.map +1 -0
  37. package/src/lib/workflow/workflow-api.d.ts +517 -0
  38. package/src/lib/workflow/workflow-api.js +1068 -0
  39. package/src/lib/workflow/workflow-api.js.map +1 -0
  40. package/eslint.config.mjs +0 -19
  41. package/jest.config.cts +0 -10
  42. package/project.json +0 -66
  43. package/src/lib/api-auth-client.ts +0 -182
  44. package/src/lib/client-config.ts +0 -99
  45. package/src/lib/form/form-api.spec.ts +0 -81
  46. package/src/lib/form/form-api.ts +0 -402
  47. package/src/lib/form/form-rendering.ts +0 -580
  48. package/src/lib/graphql-client.spec.ts +0 -65
  49. package/src/lib/graphql-client.ts +0 -128
  50. package/src/lib/member-api.ts +0 -129
  51. package/src/lib/organization/organization-api.spec.ts +0 -90
  52. package/src/lib/organization/organization-api.ts +0 -711
  53. package/src/lib/template/template-api.spec.ts +0 -88
  54. package/src/lib/template/template-api.ts +0 -894
  55. package/src/lib/workflow/workflow-api.spec.ts +0 -132
  56. package/src/lib/workflow/workflow-api.ts +0 -2124
  57. package/tsconfig.json +0 -27
  58. package/tsconfig.lib.json +0 -16
  59. package/tsconfig.spec.json +0 -16
  60. /package/src/{index.ts → index.d.ts} +0 -0
  61. /package/src/lib/form/{index.ts → index.d.ts} +0 -0
  62. /package/src/lib/organization/{index.ts → index.d.ts} +0 -0
  63. /package/src/lib/template/{index.ts → index.d.ts} +0 -0
  64. /package/src/lib/workflow/{index.ts → index.d.ts} +0 -0
@@ -0,0 +1,1068 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listApprovalInstances = listApprovalInstances;
4
+ exports.listApprovalInstancesPage = listApprovalInstancesPage;
5
+ exports.readLaunchContext = readLaunchContext;
6
+ exports.listLaunchableTemplates = listLaunchableTemplates;
7
+ exports.readApprovalInstance = readApprovalInstance;
8
+ exports.listInboxTasks = listInboxTasks;
9
+ exports.listApprovalHistoryTasks = listApprovalHistoryTasks;
10
+ exports.readWorkflowDashboardSummary = readWorkflowDashboardSummary;
11
+ exports.listTaskDecisions = listTaskDecisions;
12
+ exports.listAttachments = listAttachments;
13
+ exports.uploadAttachment = uploadAttachment;
14
+ exports.readAttachmentDownloadUrl = readAttachmentDownloadUrl;
15
+ exports.readAttachmentPreviewUrl = readAttachmentPreviewUrl;
16
+ exports.readInstanceSignatures = readInstanceSignatures;
17
+ exports.resolveMemberProfiles = resolveMemberProfiles;
18
+ exports.searchMembers = searchMembers;
19
+ exports.listMemberDirectoryPage = listMemberDirectoryPage;
20
+ exports.listDelegationRules = listDelegationRules;
21
+ exports.listDelegationRulesPage = listDelegationRulesPage;
22
+ exports.createDelegationRule = createDelegationRule;
23
+ exports.revokeDelegationRule = revokeDelegationRule;
24
+ exports.listNotifications = listNotifications;
25
+ exports.readUnreadNotificationCount = readUnreadNotificationCount;
26
+ exports.markNotificationRead = markNotificationRead;
27
+ exports.markAllNotificationsRead = markAllNotificationsRead;
28
+ exports.readNotificationPreference = readNotificationPreference;
29
+ exports.updateNotificationPreference = updateNotificationPreference;
30
+ exports.submitApprovalInstance = submitApprovalInstance;
31
+ exports.decideTask = decideTask;
32
+ exports.cancelApprovalInstance = cancelApprovalInstance;
33
+ exports.resubmitApprovalInstance = resubmitApprovalInstance;
34
+ exports.requestAdhocCountersign = requestAdhocCountersign;
35
+ exports.requestAdhocPreApproval = requestAdhocPreApproval;
36
+ exports.configureAdhocStageNotification = configureAdhocStageNotification;
37
+ exports.configureAdhocCompletionNotification = configureAdhocCompletionNotification;
38
+ exports.cancelAdhocDirective = cancelAdhocDirective;
39
+ exports.listAdhocDirectives = listAdhocDirectives;
40
+ exports.readApprovalInstanceCaseTitle = readApprovalInstanceCaseTitle;
41
+ exports.readFormDataCaseTitle = readFormDataCaseTitle;
42
+ const graphql_client_1 = require("../graphql-client");
43
+ async function listApprovalInstances() {
44
+ const data = await (0, graphql_client_1.requestGraphQl)(`query ApprovalInstances {
45
+ approvalInstances {
46
+ completedAt
47
+ formDataJson
48
+ formDefinitionSnapshotJson
49
+ id
50
+ initiatorMemberId
51
+ startedAt
52
+ state
53
+ templateId
54
+ templateVersionId
55
+ title
56
+ workflowSnapshotJson
57
+ }
58
+ }`);
59
+ return data.approvalInstances.map(parseInstanceJson);
60
+ }
61
+ async function listApprovalInstancesPage({ page, pageSize, searchText, state, templateId, view, }) {
62
+ const variables = {
63
+ page,
64
+ pageSize,
65
+ searchText: searchText?.trim() || null,
66
+ state: state ? [state] : null,
67
+ templateId: templateId?.trim() || null,
68
+ view,
69
+ };
70
+ const [pageData, pageInfoData] = await Promise.all([
71
+ (0, graphql_client_1.requestGraphQl)(`query ApprovalInstancesPage(
72
+ $view: ApprovalInstanceListView
73
+ $searchText: String
74
+ $state: [ApprovalInstanceState!]
75
+ $templateId: String
76
+ $page: Int
77
+ $pageSize: Int
78
+ ) {
79
+ approvalInstances(
80
+ view: $view
81
+ searchText: $searchText
82
+ state: $state
83
+ templateId: $templateId
84
+ page: $page
85
+ pageSize: $pageSize
86
+ ) {
87
+ completedAt
88
+ formDataJson
89
+ formDefinitionSnapshotJson
90
+ id
91
+ initiatorMemberId
92
+ startedAt
93
+ state
94
+ templateId
95
+ templateVersionId
96
+ title
97
+ workflowSnapshotJson
98
+ }
99
+ }`, variables),
100
+ (0, graphql_client_1.requestGraphQl)(`query ApprovalInstancePageInfo(
101
+ $view: ApprovalInstanceListView
102
+ $searchText: String
103
+ $state: [ApprovalInstanceState!]
104
+ $templateId: String
105
+ $page: Int
106
+ $pageSize: Int
107
+ ) {
108
+ approvalInstancePageInfo(
109
+ view: $view
110
+ searchText: $searchText
111
+ state: $state
112
+ templateId: $templateId
113
+ page: $page
114
+ pageSize: $pageSize
115
+ ) {
116
+ hasNextPage
117
+ hasPreviousPage
118
+ page
119
+ pageSize
120
+ totalCount
121
+ totalPages
122
+ }
123
+ }`, variables),
124
+ ]);
125
+ const pageInfo = pageInfoData.approvalInstancePageInfo;
126
+ return {
127
+ instances: pageData.approvalInstances.map(parseInstanceJson),
128
+ pageInfo,
129
+ totalCount: pageInfo.totalCount,
130
+ };
131
+ }
132
+ async function readLaunchContext(templateId) {
133
+ const templateData = await (0, graphql_client_1.requestGraphQl)(`query LaunchTemplate($id: String!) {
134
+ approvalTemplate(id: $id) {
135
+ currentVersionId
136
+ id
137
+ name
138
+ }
139
+ approvalTemplateVersions(templateId: $id) {
140
+ formDefinitionVersionId
141
+ id
142
+ status
143
+ version
144
+ }
145
+ launchableApprovalTemplates {
146
+ currentVersionId
147
+ id
148
+ name
149
+ updatedAt
150
+ }
151
+ }`, { id: templateId });
152
+ const templateVersion = templateData.approvalTemplateVersions.find((version) => version.id === templateData.approvalTemplate.currentVersionId);
153
+ if (!templateVersion || templateVersion.status !== 'PUBLISHED') {
154
+ throw new Error('模板尚未發布,無法發起簽核。');
155
+ }
156
+ if (!templateVersion.formDefinitionVersionId) {
157
+ throw new Error('模板尚未綁定表單版本,無法發起簽核。');
158
+ }
159
+ const launchableApprovalTemplates = templateData.launchableApprovalTemplates ?? [templateData.approvalTemplate];
160
+ if (!launchableApprovalTemplates.some((template) => template.id === templateId)) {
161
+ throw new Error('目前登入者沒有此模板的發起權限。');
162
+ }
163
+ const formData = await (0, graphql_client_1.requestGraphQl)(`query LaunchFormVersion($id: String!) {
164
+ formDefinitionVersion(id: $id) {
165
+ id
166
+ schemaJson
167
+ uiSchemaJson
168
+ version
169
+ }
170
+ }`, { id: templateVersion.formDefinitionVersionId });
171
+ return {
172
+ formVersion: {
173
+ id: formData.formDefinitionVersion.id,
174
+ schema: JSON.parse(formData.formDefinitionVersion.schemaJson),
175
+ uiSchema: JSON.parse(formData.formDefinitionVersion.uiSchemaJson),
176
+ version: formData.formDefinitionVersion.version,
177
+ },
178
+ template: templateData.approvalTemplate,
179
+ templateVersion,
180
+ };
181
+ }
182
+ async function listLaunchableTemplates() {
183
+ const templateData = await (0, graphql_client_1.requestGraphQl)(`query ApprovalTemplates {
184
+ launchableApprovalTemplates {
185
+ currentVersionId
186
+ id
187
+ name
188
+ updatedAt
189
+ }
190
+ }`);
191
+ const launchableApprovalTemplates = templateData.launchableApprovalTemplates ??
192
+ templateData.approvalTemplates ??
193
+ [];
194
+ const versionLists = await Promise.all(launchableApprovalTemplates.map((template) => (0, graphql_client_1.requestGraphQl)(`query LaunchTemplateVersions($templateId: String!) {
195
+ approvalTemplateVersions(templateId: $templateId) {
196
+ formDefinitionVersionId
197
+ id
198
+ status
199
+ version
200
+ }
201
+ }`, { templateId: template.id })));
202
+ return launchableApprovalTemplates.flatMap((template, index) => {
203
+ const currentVersion = versionLists[index]?.approvalTemplateVersions.find((version) => version.id === template.currentVersionId);
204
+ return currentVersion?.status === 'PUBLISHED' &&
205
+ currentVersion.formDefinitionVersionId
206
+ ? [
207
+ {
208
+ currentVersionId: currentVersion.id,
209
+ formDefinitionVersionId: currentVersion.formDefinitionVersionId,
210
+ id: template.id,
211
+ name: template.name,
212
+ updatedAt: template.updatedAt,
213
+ version: currentVersion.version,
214
+ },
215
+ ]
216
+ : [];
217
+ });
218
+ }
219
+ async function readApprovalInstance(instanceId) {
220
+ const data = await (0, graphql_client_1.requestGraphQl)(`query ApprovalInstance($id: String!) {
221
+ approvalInstance(id: $id) {
222
+ completedAt
223
+ formDataJson
224
+ formDefinitionSnapshotJson
225
+ id
226
+ initiatorMemberId
227
+ startedAt
228
+ state
229
+ templateId
230
+ templateVersionId
231
+ title
232
+ workflowSnapshotJson
233
+ }
234
+ tasks(instanceId: $id) {
235
+ adhocDirectiveId
236
+ adhocOriginTaskId
237
+ adhocType
238
+ assigneeMemberId
239
+ assignmentType
240
+ candidateMemberIds
241
+ completedAt
242
+ createdAt
243
+ decisionPolicySnapshotJson
244
+ delegationChainJson
245
+ id
246
+ instanceId
247
+ isAdhoc
248
+ nodeId
249
+ openedAt
250
+ originalAssigneeMemberId
251
+ slaDueAt
252
+ status
253
+ tokenId
254
+ }
255
+ workflowTokens(instanceId: $id) {
256
+ consumedAt
257
+ createdAt
258
+ currentNodeId
259
+ id
260
+ instanceId
261
+ parentTokenId
262
+ status
263
+ }
264
+ activityLogs(instanceId: $id) {
265
+ actorMemberId
266
+ createdAt
267
+ eventType
268
+ id
269
+ nodeId
270
+ payloadJson
271
+ taskId
272
+ }
273
+ }`, { id: instanceId });
274
+ return {
275
+ activityLogs: data.activityLogs,
276
+ instance: parseInstanceJson(data.approvalInstance),
277
+ tasks: normalizeTaskRecords(data.tasks),
278
+ workflowTokens: data.workflowTokens,
279
+ };
280
+ }
281
+ async function listInboxTasks(assigneeMemberId) {
282
+ const data = await (0, graphql_client_1.requestGraphQl)(`query InboxTasks($assigneeMemberId: String!) {
283
+ inboxTasks(assigneeMemberId: $assigneeMemberId) {
284
+ adhocDirectiveId
285
+ adhocOriginTaskId
286
+ adhocType
287
+ assigneeMemberId
288
+ assignmentType
289
+ candidateMemberIds
290
+ completedAt
291
+ createdAt
292
+ decisionPolicySnapshotJson
293
+ delegationChainJson
294
+ id
295
+ instanceId
296
+ isAdhoc
297
+ nodeId
298
+ openedAt
299
+ originalAssigneeMemberId
300
+ slaDueAt
301
+ status
302
+ tokenId
303
+ }
304
+ }`, { assigneeMemberId });
305
+ return normalizeTaskRecords(data.inboxTasks);
306
+ }
307
+ async function listApprovalHistoryTasks(assigneeMemberId) {
308
+ const data = await (0, graphql_client_1.requestGraphQl)(`query ApprovalHistoryTasks($assigneeMemberId: String!) {
309
+ approvalHistoryTasks(assigneeMemberId: $assigneeMemberId) {
310
+ adhocDirectiveId
311
+ adhocOriginTaskId
312
+ adhocType
313
+ assigneeMemberId
314
+ assignmentType
315
+ candidateMemberIds
316
+ completedAt
317
+ createdAt
318
+ decisionPolicySnapshotJson
319
+ delegationChainJson
320
+ id
321
+ instanceId
322
+ isAdhoc
323
+ nodeId
324
+ openedAt
325
+ originalAssigneeMemberId
326
+ slaDueAt
327
+ status
328
+ tokenId
329
+ }
330
+ }`, { assigneeMemberId });
331
+ return normalizeTaskRecords(data.approvalHistoryTasks);
332
+ }
333
+ async function readWorkflowDashboardSummary({ currentMemberId, from, to, }) {
334
+ const [summaryData, notificationResult] = await Promise.all([
335
+ (0, graphql_client_1.requestGraphQl)(`query WorkflowDashboardSummary($from: DateTime, $to: DateTime) {
336
+ workflowDashboardSummary(from: $from, to: $to) {
337
+ activeInstanceCount
338
+ completedInstanceCount
339
+ overdueTaskCount
340
+ pendingTaskCount
341
+ rejectedInstanceCount
342
+ totalInstanceCount
343
+ }
344
+ }`, { from, to }),
345
+ listNotifications({
346
+ includeRead: true,
347
+ page: 1,
348
+ pageSize: 1,
349
+ recipientMemberId: currentMemberId,
350
+ }),
351
+ ]);
352
+ return {
353
+ ...summaryData.workflowDashboardSummary,
354
+ unreadNotificationCount: notificationResult.unreadCount,
355
+ };
356
+ }
357
+ function normalizeTaskRecords(tasks) {
358
+ return tasks.map((task) => ({
359
+ ...task,
360
+ adhocDirectiveId: task.adhocDirectiveId ?? null,
361
+ adhocOriginTaskId: task.adhocOriginTaskId ?? null,
362
+ adhocType: task.adhocType ?? null,
363
+ assignmentType: task.assignmentType ?? 'DIRECT_MEMBER',
364
+ candidateMemberIds: task.candidateMemberIds ?? [],
365
+ decisionPolicySnapshotJson: task.decisionPolicySnapshotJson ?? JSON.stringify({ type: 'SINGLE' }),
366
+ isAdhoc: task.isAdhoc ?? false,
367
+ }));
368
+ }
369
+ async function listTaskDecisions(taskId) {
370
+ const data = await (0, graphql_client_1.requestGraphQl)(`query TaskDecisions($taskId: String!) {
371
+ taskDecisions(taskId: $taskId) {
372
+ action
373
+ comment
374
+ decidedAt
375
+ decidedByMemberId
376
+ id
377
+ returnToNodeId
378
+ signatureId
379
+ taskId
380
+ transferToMemberId
381
+ }
382
+ }`, { taskId });
383
+ return data.taskDecisions;
384
+ }
385
+ async function listAttachments(instanceId) {
386
+ const data = await (0, graphql_client_1.requestGraphQl)(`query InstanceAttachments($instanceId: String!) {
387
+ attachments(instanceId: $instanceId) {
388
+ checksumSha256
389
+ createdAt
390
+ filename
391
+ formFieldPath
392
+ id
393
+ instanceId
394
+ mimeType
395
+ sizeBytes
396
+ storageKey
397
+ storageProvider
398
+ taskId
399
+ uploaderMemberId
400
+ }
401
+ }`, { instanceId });
402
+ return data.attachments ?? [];
403
+ }
404
+ async function uploadAttachment({ file, formFieldPath, }) {
405
+ const contentBase64 = await readFileBase64(file);
406
+ const checksumSha256 = await hashFileSha256(file);
407
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation UploadAttachment($input: UploadAttachmentInput!) {
408
+ uploadAttachment(input: $input) {
409
+ checksumSha256
410
+ createdAt
411
+ filename
412
+ formFieldPath
413
+ id
414
+ instanceId
415
+ mimeType
416
+ sizeBytes
417
+ storageKey
418
+ storageProvider
419
+ taskId
420
+ uploaderMemberId
421
+ }
422
+ }`, {
423
+ input: {
424
+ checksumSha256,
425
+ contentBase64,
426
+ filename: file.name,
427
+ formFieldPath,
428
+ instanceId: null,
429
+ mimeType: file.type || 'application/octet-stream',
430
+ sizeBytes: file.size,
431
+ taskId: null,
432
+ },
433
+ });
434
+ return data.uploadAttachment;
435
+ }
436
+ async function readAttachmentDownloadUrl({ id, }) {
437
+ const data = await (0, graphql_client_1.requestGraphQl)(`query AttachmentDownloadUrl($id: String!) {
438
+ attachmentDownloadUrl(id: $id)
439
+ }`, { id });
440
+ return data.attachmentDownloadUrl;
441
+ }
442
+ async function readAttachmentPreviewUrl({ id, }) {
443
+ const data = await (0, graphql_client_1.requestGraphQl)(`query AttachmentPreviewUrl($id: String!) {
444
+ attachmentPreviewUrl(id: $id)
445
+ }`, { id });
446
+ return data.attachmentPreviewUrl;
447
+ }
448
+ async function readInstanceSignatures(instanceId) {
449
+ const data = await (0, graphql_client_1.requestGraphQl)(`query InstanceSignatures($instanceId: String!) {
450
+ signatures(instanceId: $instanceId) {
451
+ algorithm
452
+ id
453
+ instanceId
454
+ keyVersion
455
+ previousSignatureHash
456
+ signature
457
+ signedAt
458
+ signedPayloadHash
459
+ signedPayloadJson
460
+ signerMemberId
461
+ taskId
462
+ timestampTokenBase64
463
+ }
464
+ verifySignatureChain(instanceId: $instanceId) {
465
+ checkedCount
466
+ errors
467
+ instanceId
468
+ valid
469
+ }
470
+ }`, { instanceId });
471
+ return {
472
+ signatures: data.signatures ?? [],
473
+ verification: data.verifySignatureChain ?? {
474
+ checkedCount: 0,
475
+ errors: [],
476
+ instanceId,
477
+ valid: true,
478
+ },
479
+ };
480
+ }
481
+ async function resolveMemberProfiles(memberIds) {
482
+ if (memberIds.length === 0) {
483
+ return [];
484
+ }
485
+ const data = await (0, graphql_client_1.requestGraphQl)(`query InstanceMembers($memberIds: [String!]!) {
486
+ members(memberIds: $memberIds) {
487
+ email
488
+ memberId
489
+ name
490
+ }
491
+ }`, { memberIds });
492
+ return data.members;
493
+ }
494
+ async function searchMembers(searchText) {
495
+ const data = await (0, graphql_client_1.requestGraphQl)(`query SearchMembers($searchText: String!) {
496
+ searchMembers(searchText: $searchText) {
497
+ email
498
+ memberId
499
+ name
500
+ }
501
+ }`, { searchText });
502
+ return data.searchMembers;
503
+ }
504
+ async function listMemberDirectoryPage({ page, pageSize, searchText = '', }) {
505
+ const data = await (0, graphql_client_1.requestGraphQl)(`query MemberDirectoryPage($page: Int, $pageSize: Int, $searchText: String!) {
506
+ searchMembers(page: $page, pageSize: $pageSize, searchText: $searchText) {
507
+ email
508
+ memberId
509
+ name
510
+ }
511
+ memberCount(searchText: $searchText)
512
+ }`, { page, pageSize, searchText });
513
+ return {
514
+ members: data.searchMembers,
515
+ totalCount: data.memberCount,
516
+ };
517
+ }
518
+ async function listDelegationRules({ includeInactive = true, principalMemberId = null, } = {}) {
519
+ const data = await (0, graphql_client_1.requestGraphQl)(`query DelegationRules($includeInactive: Boolean, $principalMemberId: String) {
520
+ delegationRules(
521
+ includeInactive: $includeInactive
522
+ principalMemberId: $principalMemberId
523
+ ) {
524
+ agentMemberId
525
+ createdAt
526
+ createdByMemberId
527
+ endAt
528
+ id
529
+ principalMemberId
530
+ priority
531
+ requiresConfirmation
532
+ revokedAt
533
+ revokedByMemberId
534
+ scopeConditionCel
535
+ scopeTemplateIds
536
+ scopeType
537
+ startAt
538
+ status
539
+ updatedAt
540
+ }
541
+ }`, { includeInactive, principalMemberId });
542
+ return data.delegationRules;
543
+ }
544
+ async function listDelegationRulesPage({ agentMemberId = null, includeInactive = true, page = 1, pageSize = 10, principalMemberId = null, scopeType = null, status = null, } = {}) {
545
+ const data = await (0, graphql_client_1.requestGraphQl)(`query DelegationRulesPage(
546
+ $includeInactive: Boolean
547
+ $page: Int
548
+ $pageSize: Int
549
+ $principalMemberId: String
550
+ $agentMemberId: String
551
+ $scopeType: DelegationScopeType
552
+ $status: DelegationRuleStatus
553
+ ) {
554
+ delegationRules(
555
+ agentMemberId: $agentMemberId
556
+ includeInactive: $includeInactive
557
+ page: $page
558
+ pageSize: $pageSize
559
+ principalMemberId: $principalMemberId
560
+ scopeType: $scopeType
561
+ status: $status
562
+ ) {
563
+ agentMemberId
564
+ createdAt
565
+ createdByMemberId
566
+ endAt
567
+ id
568
+ principalMemberId
569
+ priority
570
+ requiresConfirmation
571
+ revokedAt
572
+ revokedByMemberId
573
+ scopeConditionCel
574
+ scopeTemplateIds
575
+ scopeType
576
+ startAt
577
+ status
578
+ updatedAt
579
+ }
580
+ delegationRuleCount(
581
+ agentMemberId: $agentMemberId
582
+ includeInactive: $includeInactive
583
+ principalMemberId: $principalMemberId
584
+ scopeType: $scopeType
585
+ status: $status
586
+ )
587
+ }`, {
588
+ agentMemberId,
589
+ includeInactive,
590
+ page,
591
+ pageSize,
592
+ principalMemberId,
593
+ scopeType,
594
+ status,
595
+ });
596
+ return {
597
+ rules: data.delegationRules,
598
+ totalCount: data.delegationRuleCount,
599
+ };
600
+ }
601
+ async function createDelegationRule(input) {
602
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation CreateDelegationRule($input: CreateDelegationRuleInput!) {
603
+ createDelegationRule(input: $input) {
604
+ agentMemberId
605
+ createdAt
606
+ createdByMemberId
607
+ endAt
608
+ id
609
+ principalMemberId
610
+ priority
611
+ requiresConfirmation
612
+ revokedAt
613
+ revokedByMemberId
614
+ scopeConditionCel
615
+ scopeTemplateIds
616
+ scopeType
617
+ startAt
618
+ status
619
+ updatedAt
620
+ }
621
+ }`, { input });
622
+ return data.createDelegationRule;
623
+ }
624
+ async function revokeDelegationRule({ id, revokedByMemberId, }) {
625
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation RevokeDelegationRule($id: String!, $revokedByMemberId: String) {
626
+ revokeDelegationRule(id: $id, revokedByMemberId: $revokedByMemberId) {
627
+ agentMemberId
628
+ createdAt
629
+ createdByMemberId
630
+ endAt
631
+ id
632
+ principalMemberId
633
+ priority
634
+ requiresConfirmation
635
+ revokedAt
636
+ revokedByMemberId
637
+ scopeConditionCel
638
+ scopeTemplateIds
639
+ scopeType
640
+ startAt
641
+ status
642
+ updatedAt
643
+ }
644
+ }`, { id, revokedByMemberId });
645
+ return data.revokeDelegationRule;
646
+ }
647
+ async function listNotifications({ includeRead = true, page = 1, pageSize = 10, recipientMemberId, }) {
648
+ const data = await (0, graphql_client_1.requestGraphQl)(`query Notifications(
649
+ $recipientMemberId: String!
650
+ $includeRead: Boolean
651
+ $page: Int
652
+ $pageSize: Int
653
+ ) {
654
+ notifications(
655
+ includeRead: $includeRead
656
+ page: $page
657
+ pageSize: $pageSize
658
+ recipientMemberId: $recipientMemberId
659
+ ) {
660
+ actionable
661
+ attemptCount
662
+ body
663
+ channel
664
+ createdAt
665
+ deliveredAt
666
+ deliveryError
667
+ deliveryTarget
668
+ id
669
+ instanceId
670
+ lastAttemptAt
671
+ nextRetryAt
672
+ payloadJson
673
+ readAt
674
+ recipientMemberId
675
+ resolution
676
+ resolvedAt
677
+ sentAt
678
+ status
679
+ taskId
680
+ title
681
+ type
682
+ }
683
+ notificationCount(
684
+ includeRead: $includeRead
685
+ recipientMemberId: $recipientMemberId
686
+ )
687
+ unreadNotificationCount(recipientMemberId: $recipientMemberId)
688
+ }`, { includeRead, page, pageSize, recipientMemberId });
689
+ return {
690
+ notifications: data.notifications,
691
+ totalCount: data.notificationCount,
692
+ unreadCount: data.unreadNotificationCount,
693
+ };
694
+ }
695
+ async function readUnreadNotificationCount(recipientMemberId) {
696
+ const data = await (0, graphql_client_1.requestGraphQl)(`query UnreadNotificationCount($recipientMemberId: String!) {
697
+ unreadNotificationCount(recipientMemberId: $recipientMemberId)
698
+ }`, { recipientMemberId });
699
+ return data.unreadNotificationCount;
700
+ }
701
+ async function markNotificationRead({ id, readerMemberId, }) {
702
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation MarkNotificationRead($id: String!, $readerMemberId: String) {
703
+ markNotificationRead(id: $id, readerMemberId: $readerMemberId) {
704
+ id
705
+ readAt
706
+ status
707
+ }
708
+ }`, { id, readerMemberId });
709
+ return data.markNotificationRead;
710
+ }
711
+ async function markAllNotificationsRead({ recipientMemberId, }) {
712
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation MarkAllNotificationsRead($recipientMemberId: String) {
713
+ markAllNotificationsRead(recipientMemberId: $recipientMemberId)
714
+ }`, { recipientMemberId });
715
+ return data.markAllNotificationsRead;
716
+ }
717
+ async function readNotificationPreference(memberId) {
718
+ const data = await (0, graphql_client_1.requestGraphQl)(`query NotificationPreference($memberId: String!) {
719
+ notificationPreference(memberId: $memberId) {
720
+ emailDigestMode
721
+ emailEnabled
722
+ inAppEnabled
723
+ memberId
724
+ quietHoursEnd
725
+ quietHoursStart
726
+ updatedAt
727
+ }
728
+ }`, { memberId });
729
+ return data.notificationPreference;
730
+ }
731
+ async function updateNotificationPreference(input) {
732
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation UpdateNotificationPreference($input: UpdateNotificationPreferenceInput!) {
733
+ updateNotificationPreference(input: $input) {
734
+ emailDigestMode
735
+ emailEnabled
736
+ inAppEnabled
737
+ memberId
738
+ quietHoursEnd
739
+ quietHoursStart
740
+ updatedAt
741
+ }
742
+ }`, { input });
743
+ return data.updateNotificationPreference;
744
+ }
745
+ async function submitApprovalInstance({ formData, initiatorMemberId, templateId, title, }) {
746
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation SubmitApprovalInstance($input: SubmitApprovalInstanceInput!) {
747
+ submitApprovalInstance(input: $input) {
748
+ id
749
+ }
750
+ }`, {
751
+ input: {
752
+ formDataJson: JSON.stringify(formData),
753
+ initiatorMemberId,
754
+ initiatorMetadataSnapshotJson: null,
755
+ templateId,
756
+ title,
757
+ },
758
+ });
759
+ return data.submitApprovalInstance.id;
760
+ }
761
+ async function decideTask({ action, comment, decidedByMemberId, returnToNodeId = null, taskId, transferToMemberId = null, }) {
762
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation DecideTask($input: DecideTaskInput!) {
763
+ decideTask(input: $input) {
764
+ action
765
+ comment
766
+ decidedAt
767
+ decidedByMemberId
768
+ id
769
+ returnToNodeId
770
+ signatureId
771
+ taskId
772
+ transferToMemberId
773
+ }
774
+ }`, {
775
+ input: {
776
+ action,
777
+ comment,
778
+ decidedByMemberId,
779
+ returnToNodeId,
780
+ taskId,
781
+ transferToMemberId,
782
+ },
783
+ });
784
+ return data.decideTask;
785
+ }
786
+ async function cancelApprovalInstance({ cancelledByMemberId, comment, instanceId, }) {
787
+ await (0, graphql_client_1.requestGraphQl)(`mutation CancelApprovalInstance($input: CancelApprovalInstanceInput!) {
788
+ cancelApprovalInstance(input: $input) {
789
+ id
790
+ state
791
+ }
792
+ }`, {
793
+ input: {
794
+ cancelledByMemberId,
795
+ comment,
796
+ instanceId,
797
+ },
798
+ });
799
+ }
800
+ async function resubmitApprovalInstance({ formData, initiatorMemberId, instanceId, title, }) {
801
+ await (0, graphql_client_1.requestGraphQl)(`mutation ResubmitApprovalInstance($input: ResubmitApprovalInstanceInput!) {
802
+ resubmitApprovalInstance(input: $input) {
803
+ id
804
+ state
805
+ }
806
+ }`, {
807
+ input: {
808
+ formDataJson: JSON.stringify(formData),
809
+ initiatorMemberId,
810
+ instanceId,
811
+ title,
812
+ },
813
+ });
814
+ }
815
+ const ADHOC_DIRECTIVE_FIELDS = `
816
+ channels
817
+ comment
818
+ consumedAt
819
+ createdAt
820
+ createdByMemberId
821
+ id
822
+ instanceId
823
+ onReject
824
+ originNodeId
825
+ originTaskId
826
+ status
827
+ targetKind
828
+ targetValueJson
829
+ type
830
+ `;
831
+ const ADHOC_TASK_FIELDS = `
832
+ adhocDirectiveId
833
+ adhocOriginTaskId
834
+ adhocType
835
+ assigneeMemberId
836
+ assignmentType
837
+ candidateMemberIds
838
+ completedAt
839
+ createdAt
840
+ decisionPolicySnapshotJson
841
+ delegationChainJson
842
+ id
843
+ instanceId
844
+ isAdhoc
845
+ nodeId
846
+ openedAt
847
+ originalAssigneeMemberId
848
+ slaDueAt
849
+ status
850
+ tokenId
851
+ `;
852
+ function buildAdhocTargetInput(target) {
853
+ return {
854
+ includeDescendants: target.includeDescendants ?? null,
855
+ kind: target.kind,
856
+ memberIds: target.memberIds ? [...target.memberIds] : null,
857
+ orgUnitId: target.orgUnitId ?? null,
858
+ positionId: target.positionId ?? null,
859
+ webhookHeadersJson: target.webhookHeaders
860
+ ? JSON.stringify(target.webhookHeaders)
861
+ : null,
862
+ webhookUrl: target.webhookUrl ?? null,
863
+ };
864
+ }
865
+ /**
866
+ * Ad-hoc countersign (臨時會簽): asks the given target to co-sign the NEXT
867
+ * stage of this instance. When the next user task is created, a parallel
868
+ * ad-hoc task is spawned for the target, and the flow only advances past
869
+ * that stage once BOTH the original task and every countersign task are
870
+ * approved. A countersigner's rejection rejects the whole instance.
871
+ *
872
+ * Only the current task's assignee/candidate may call this, and only on
873
+ * nodes whose template sets `allowAddSigner: true`. Returns the recorded
874
+ * directive (`PENDING` until the next user task consumes it; withdrawable
875
+ * via {@link cancelAdhocDirective} while pending). Never alters the
876
+ * workflow template.
877
+ */
878
+ async function requestAdhocCountersign({ comment = null, target, taskId, }) {
879
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation RequestAdhocCountersign($taskId: ID!, $target: AdhocTargetInput!, $comment: String) {
880
+ requestAdhocCountersign(taskId: $taskId, target: $target, comment: $comment) {
881
+ ${ADHOC_DIRECTIVE_FIELDS}
882
+ }
883
+ }`, { comment, target: buildAdhocTargetInput(target), taskId });
884
+ return data.requestAdhocCountersign;
885
+ }
886
+ /**
887
+ * Ad-hoc pre-approval (臨時加簽): immediately spawns a blocking ad-hoc task
888
+ * for the given target on the CURRENT stage. Even after the original
889
+ * approver approves, the flow stays on this stage until the pre-approver
890
+ * also approves. `onReject` decides what happens when the pre-approver
891
+ * rejects: `REJECT_INSTANCE` rejects the whole instance;
892
+ * `RETURN_TO_ORIGIN` hands the decision back to the original approver
893
+ * (re-opening their task if they had already approved).
894
+ *
895
+ * Only the current task's assignee/candidate may call this, and only on
896
+ * nodes whose template sets `allowAddSigner: true`. Returns the spawned
897
+ * ad-hoc task. Never alters the workflow template.
898
+ */
899
+ async function requestAdhocPreApproval({ comment = null, onReject, target, taskId, }) {
900
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation RequestAdhocPreApproval($taskId: ID!, $target: AdhocTargetInput!, $onReject: AdhocPreApprovalRejectBehavior!, $comment: String) {
901
+ requestAdhocPreApproval(taskId: $taskId, target: $target, onReject: $onReject, comment: $comment) {
902
+ ${ADHOC_TASK_FIELDS}
903
+ }
904
+ }`, {
905
+ comment,
906
+ onReject,
907
+ target: buildAdhocTargetInput(target),
908
+ taskId,
909
+ });
910
+ return data.requestAdhocPreApproval;
911
+ }
912
+ /**
913
+ * Ad-hoc stage notification (臨時階段通知): notifies the target once the
914
+ * CURRENT stage ends — regardless of outcome (approved, rejected, or
915
+ * returned). Targets may be members, a position, an org unit, or a webhook
916
+ * URL. `channels` defaults to in-app notification.
917
+ *
918
+ * Available to the current task's assignee/candidate on any user-task node
919
+ * (no `allowAddSigner` requirement). Returns the recorded directive
920
+ * (withdrawable via {@link cancelAdhocDirective} while pending). Never
921
+ * alters the workflow template.
922
+ */
923
+ async function configureAdhocStageNotification({ channels = null, target, taskId, }) {
924
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation ConfigureAdhocStageNotification($taskId: ID!, $input: AdhocNotificationInput!) {
925
+ configureAdhocStageNotification(taskId: $taskId, input: $input) {
926
+ ${ADHOC_DIRECTIVE_FIELDS}
927
+ }
928
+ }`, {
929
+ input: {
930
+ channels: channels ? [...channels] : null,
931
+ target: buildAdhocTargetInput(target),
932
+ },
933
+ taskId,
934
+ });
935
+ return data.configureAdhocStageNotification;
936
+ }
937
+ /**
938
+ * Ad-hoc completion notification (臨時完成通知): notifies the target once
939
+ * the WHOLE instance reaches a terminal state (`APPROVED`, `REJECTED`, or
940
+ * `CANCELLED`). Targets may be members, a position, an org unit, or a
941
+ * webhook URL. `channels` defaults to in-app notification.
942
+ *
943
+ * Available to the current task's assignee/candidate on any user-task node
944
+ * (no `allowAddSigner` requirement). Returns the recorded directive
945
+ * (withdrawable via {@link cancelAdhocDirective} while pending). Never
946
+ * alters the workflow template.
947
+ */
948
+ async function configureAdhocCompletionNotification({ channels = null, target, taskId, }) {
949
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation ConfigureAdhocCompletionNotification($taskId: ID!, $input: AdhocNotificationInput!) {
950
+ configureAdhocCompletionNotification(taskId: $taskId, input: $input) {
951
+ ${ADHOC_DIRECTIVE_FIELDS}
952
+ }
953
+ }`, {
954
+ input: {
955
+ channels: channels ? [...channels] : null,
956
+ target: buildAdhocTargetInput(target),
957
+ },
958
+ taskId,
959
+ });
960
+ return data.configureAdhocCompletionNotification;
961
+ }
962
+ /**
963
+ * Withdraws a still-`PENDING` ad-hoc directive (countersign / stage-notify /
964
+ * completion-notify) before it takes effect. Only the directive's creator
965
+ * may withdraw it; pre-approval directives are consumed immediately on
966
+ * creation and therefore cannot be withdrawn.
967
+ */
968
+ async function cancelAdhocDirective(directiveId) {
969
+ const data = await (0, graphql_client_1.requestGraphQl)(`mutation CancelAdhocDirective($directiveId: ID!) {
970
+ cancelAdhocDirective(directiveId: $directiveId) {
971
+ ${ADHOC_DIRECTIVE_FIELDS}
972
+ }
973
+ }`, { directiveId });
974
+ return data.cancelAdhocDirective;
975
+ }
976
+ /**
977
+ * Lists every ad-hoc directive recorded on one approval instance, ordered by
978
+ * creation time. Use the `status` field to find directives that are still
979
+ * pending (withdrawable) versus already consumed or cancelled.
980
+ */
981
+ async function listAdhocDirectives(instanceId) {
982
+ const data = await (0, graphql_client_1.requestGraphQl)(`query AdhocDirectives($instanceId: String!) {
983
+ adhocDirectives(instanceId: $instanceId) {
984
+ ${ADHOC_DIRECTIVE_FIELDS}
985
+ }
986
+ }`, { instanceId });
987
+ // Tolerate hosts (and test mocks) whose GraphQL layer does not answer the
988
+ // adhocDirectives query yet.
989
+ return data.adhocDirectives ?? [];
990
+ }
991
+ function readApprovalInstanceCaseTitle(instance) {
992
+ return readFormDataCaseTitle({
993
+ fallbackTitle: instance.title || instance.id,
994
+ formData: instance.formData,
995
+ schema: instance.formDefinitionSnapshot.schema ?? null,
996
+ uiSchema: instance.formDefinitionSnapshot.uiSchema ?? null,
997
+ });
998
+ }
999
+ function readFormDataCaseTitle({ fallbackTitle, formData, schema, uiSchema, }) {
1000
+ const firstField = readFirstCaseTitleField(schema, uiSchema);
1001
+ if (!firstField) {
1002
+ return fallbackTitle;
1003
+ }
1004
+ const valueLabel = readFieldValueLabel(firstField, formData[firstField.fieldKey]);
1005
+ return valueLabel ? `${firstField.label}:${valueLabel}` : fallbackTitle;
1006
+ }
1007
+ function parseInstanceJson(record) {
1008
+ return {
1009
+ ...record,
1010
+ formData: JSON.parse(record.formDataJson),
1011
+ formDefinitionSnapshot: JSON.parse(record.formDefinitionSnapshotJson),
1012
+ workflowSnapshot: JSON.parse(record.workflowSnapshotJson),
1013
+ };
1014
+ }
1015
+ async function readFileBase64(file) {
1016
+ const buffer = await file.arrayBuffer();
1017
+ const bytes = new Uint8Array(buffer);
1018
+ const chunkSize = 0x8000;
1019
+ const chunks = Array.from({ length: Math.ceil(bytes.length / chunkSize) }, (_, index) => String.fromCharCode(...bytes.slice(index * chunkSize, (index + 1) * chunkSize)));
1020
+ return btoa(chunks.join(''));
1021
+ }
1022
+ async function hashFileSha256(file) {
1023
+ const digest = await crypto.subtle.digest('SHA-256', await file.arrayBuffer());
1024
+ const bytes = Array.from(new Uint8Array(digest));
1025
+ return bytes.map((byte) => byte.toString(16).padStart(2, '0')).join('');
1026
+ }
1027
+ function readFirstCaseTitleField(schema, uiSchema) {
1028
+ if (!schema?.fields.length) {
1029
+ return null;
1030
+ }
1031
+ const fieldsByKey = new Map(schema.fields.map((field) => [field.fieldKey, field]));
1032
+ const firstLayoutField = uiSchema?.layout
1033
+ .map((layoutItem) => fieldsByKey.get(layoutItem.fieldKey) ?? null)
1034
+ .find((field) => Boolean(field));
1035
+ return firstLayoutField ?? schema.fields[0] ?? null;
1036
+ }
1037
+ function readFieldValueLabel(field, value) {
1038
+ if (typeof value === 'undefined' || value === null) {
1039
+ return null;
1040
+ }
1041
+ if (Array.isArray(value)) {
1042
+ return readArrayFieldValueLabel(field, value);
1043
+ }
1044
+ if (field.type === 'boolean') {
1045
+ return value === true ? '是' : '否';
1046
+ }
1047
+ if (isSelectFieldDefinition(field) && typeof value === 'string') {
1048
+ return readSelectOptionLabel(field, value);
1049
+ }
1050
+ const valueLabel = String(value).trim();
1051
+ return valueLabel || null;
1052
+ }
1053
+ function readArrayFieldValueLabel(field, value) {
1054
+ const labels = isSelectFieldDefinition(field)
1055
+ ? value.map((item) => readSelectOptionLabel(field, item))
1056
+ : value;
1057
+ const label = labels.filter((item) => item.trim()).join('、');
1058
+ return label || null;
1059
+ }
1060
+ function readSelectOptionLabel(field, value) {
1061
+ return (field.options.find((option) => option.value === value)?.label ?? value).trim();
1062
+ }
1063
+ function isSelectFieldDefinition(field) {
1064
+ return (field.type === 'select' ||
1065
+ field.type === 'radio' ||
1066
+ field.type === 'checkbox');
1067
+ }
1068
+ //# sourceMappingURL=workflow-api.js.map