@rytass/bpm-core-client 0.1.1 → 0.1.3

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 (62) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +113 -3
  3. package/eslint.config.mjs +19 -0
  4. package/jest.config.cts +10 -0
  5. package/package.json +4 -5
  6. package/project.json +66 -0
  7. package/src/lib/api-auth-client.ts +169 -0
  8. package/src/lib/form/form-api.spec.ts +81 -0
  9. package/src/lib/form/form-api.ts +388 -0
  10. package/src/lib/form/form-rendering.ts +580 -0
  11. package/src/lib/graphql-client.spec.ts +65 -0
  12. package/src/lib/graphql-client.ts +114 -0
  13. package/src/lib/member-api.ts +129 -0
  14. package/src/lib/organization/organization-api.spec.ts +90 -0
  15. package/src/lib/organization/organization-api.ts +710 -0
  16. package/src/lib/template/template-api.spec.ts +88 -0
  17. package/src/lib/template/template-api.ts +772 -0
  18. package/src/lib/workflow/workflow-api.spec.ts +132 -0
  19. package/src/lib/workflow/workflow-api.ts +1749 -0
  20. package/tsconfig.json +27 -0
  21. package/tsconfig.lib.json +16 -0
  22. package/tsconfig.spec.json +16 -0
  23. package/LICENSE +0 -21
  24. package/src/index.js +0 -7
  25. package/src/index.js.map +0 -1
  26. package/src/lib/api-auth-client.d.ts +0 -73
  27. package/src/lib/api-auth-client.js +0 -121
  28. package/src/lib/api-auth-client.js.map +0 -1
  29. package/src/lib/form/form-api.d.ts +0 -48
  30. package/src/lib/form/form-api.js +0 -228
  31. package/src/lib/form/form-api.js.map +0 -1
  32. package/src/lib/form/form-rendering.d.ts +0 -52
  33. package/src/lib/form/form-rendering.js +0 -341
  34. package/src/lib/form/form-rendering.js.map +0 -1
  35. package/src/lib/form/index.js +0 -6
  36. package/src/lib/form/index.js.map +0 -1
  37. package/src/lib/graphql-client.d.ts +0 -45
  38. package/src/lib/graphql-client.js +0 -92
  39. package/src/lib/graphql-client.js.map +0 -1
  40. package/src/lib/member-api.d.ts +0 -49
  41. package/src/lib/member-api.js +0 -72
  42. package/src/lib/member-api.js.map +0 -1
  43. package/src/lib/organization/index.js +0 -5
  44. package/src/lib/organization/index.js.map +0 -1
  45. package/src/lib/organization/organization-api.d.ts +0 -168
  46. package/src/lib/organization/organization-api.js +0 -394
  47. package/src/lib/organization/organization-api.js.map +0 -1
  48. package/src/lib/template/index.js +0 -5
  49. package/src/lib/template/index.js.map +0 -1
  50. package/src/lib/template/template-api.d.ts +0 -150
  51. package/src/lib/template/template-api.js +0 -407
  52. package/src/lib/template/template-api.js.map +0 -1
  53. package/src/lib/workflow/index.js +0 -5
  54. package/src/lib/workflow/index.js.map +0 -1
  55. package/src/lib/workflow/workflow-api.d.ts +0 -376
  56. package/src/lib/workflow/workflow-api.js +0 -867
  57. package/src/lib/workflow/workflow-api.js.map +0 -1
  58. /package/src/{index.d.ts → index.ts} +0 -0
  59. /package/src/lib/form/{index.d.ts → index.ts} +0 -0
  60. /package/src/lib/organization/{index.d.ts → index.ts} +0 -0
  61. /package/src/lib/template/{index.d.ts → index.ts} +0 -0
  62. /package/src/lib/workflow/{index.d.ts → index.ts} +0 -0
@@ -0,0 +1,772 @@
1
+ import { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
2
+ import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
3
+ import { requestGraphQl } from '../graphql-client';
4
+
5
+ export interface ApprovalTemplateRecord {
6
+ readonly category: string | null;
7
+ readonly categoryDetail: ApprovalTemplateCategoryRecord | null;
8
+ readonly categoryId: string | null;
9
+ readonly currentVersionId: string | null;
10
+ readonly description: string | null;
11
+ readonly id: string;
12
+ readonly name: string;
13
+ readonly updatedAt: string;
14
+ }
15
+
16
+ export type ApprovalTemplateListStatus = 'DRAFT' | 'PUBLISHED';
17
+ export type ApprovalTemplateCategoryStatus = 'ACTIVE' | 'ALL' | 'INACTIVE';
18
+
19
+ export interface ApprovalTemplateCategoryRecord {
20
+ readonly createdAt: string;
21
+ readonly description: string | null;
22
+ readonly id: string;
23
+ readonly isActive: boolean;
24
+ readonly name: string;
25
+ readonly sortOrder: number;
26
+ readonly updatedAt: string;
27
+ }
28
+
29
+ export interface ApprovalTemplateVersionRecord {
30
+ readonly archivedAt: string | null;
31
+ readonly formDefinitionVersionId: string | null;
32
+ readonly id: string;
33
+ readonly initiatorPolicyCel: string | null;
34
+ readonly notificationConfigJson: string | null;
35
+ readonly publishedAt: string | null;
36
+ readonly slaDefaultsJson: string | null;
37
+ readonly status: 'ARCHIVED' | 'DRAFT' | 'PUBLISHED';
38
+ readonly updatedAt: string;
39
+ readonly version: number;
40
+ readonly workflowDefinition: WorkflowDefinition;
41
+ readonly workflowDefinitionJson: string;
42
+ }
43
+
44
+ export interface FormDefinitionRecord {
45
+ readonly currentVersionId: string | null;
46
+ readonly id: string;
47
+ readonly name: string;
48
+ readonly updatedAt: string;
49
+ }
50
+
51
+ export interface FormDefinitionVersionRecord {
52
+ readonly formDefinitionId: string;
53
+ readonly id: string;
54
+ readonly publishedAt: string | null;
55
+ readonly schema: FormDefinitionSchema;
56
+ readonly schemaJson: string;
57
+ readonly status: 'ARCHIVED' | 'DRAFT' | 'PUBLISHED';
58
+ readonly version: number;
59
+ }
60
+
61
+ export interface PublishedFormVersionOption {
62
+ readonly formDefinitionId: string;
63
+ readonly formName: string;
64
+ readonly id: string;
65
+ readonly label: string;
66
+ readonly schema: FormDefinitionSchema;
67
+ readonly version: number;
68
+ }
69
+
70
+ export interface MemberProfileRecord {
71
+ readonly email: string;
72
+ readonly memberId: string;
73
+ readonly name: string;
74
+ }
75
+
76
+ export interface WorkflowDryRunStepRecord {
77
+ readonly assigneeMemberId: string | null;
78
+ readonly edgeDefault: boolean | null;
79
+ readonly edgeId: string | null;
80
+ readonly edgeLabel: string | null;
81
+ readonly edgeMatched: boolean | null;
82
+ readonly edgeReason: string | null;
83
+ readonly entryCondition: string | null;
84
+ readonly entryConditionMatched: boolean | null;
85
+ readonly id: string;
86
+ readonly message: string;
87
+ readonly nodeId: string;
88
+ readonly nodeLabel: string;
89
+ readonly nodeType: string;
90
+ readonly status: string;
91
+ }
92
+
93
+ export interface WorkflowDryRunResultRecord {
94
+ readonly errors: readonly string[];
95
+ readonly steps: readonly WorkflowDryRunStepRecord[];
96
+ readonly valid: boolean;
97
+ }
98
+
99
+ export interface TemplateDesignerRecord {
100
+ readonly formVersions: readonly PublishedFormVersionOption[];
101
+ readonly template: ApprovalTemplateRecord;
102
+ readonly versions: readonly ApprovalTemplateVersionRecord[];
103
+ }
104
+
105
+ export interface ApprovalTemplatesPage {
106
+ readonly templates: readonly ApprovalTemplateRecord[];
107
+ readonly totalCount: number;
108
+ }
109
+
110
+ export interface ApprovalTemplateCategoriesPage {
111
+ readonly categories: readonly ApprovalTemplateCategoryRecord[];
112
+ readonly totalCount: number;
113
+ }
114
+
115
+ interface ApprovalTemplatesQueryData {
116
+ readonly approvalTemplates: readonly ApprovalTemplateRecord[];
117
+ }
118
+
119
+ interface ApprovalTemplatesPageQueryData extends ApprovalTemplatesQueryData {
120
+ readonly approvalTemplateCount: number;
121
+ }
122
+
123
+ interface ApprovalTemplateCategoriesPageQueryData {
124
+ readonly approvalTemplateCategories: readonly ApprovalTemplateCategoryRecord[];
125
+ readonly approvalTemplateCategoryCount: number;
126
+ }
127
+
128
+ interface CreateApprovalTemplateMutationData {
129
+ readonly createApprovalTemplate: Pick<ApprovalTemplateRecord, 'id'>;
130
+ }
131
+
132
+ interface CreateApprovalTemplateCategoryMutationData {
133
+ readonly createApprovalTemplateCategory: ApprovalTemplateCategoryRecord;
134
+ }
135
+
136
+ interface DeleteApprovalTemplateCategoryMutationData {
137
+ readonly deleteApprovalTemplateCategory: Pick<
138
+ ApprovalTemplateCategoryRecord,
139
+ 'id'
140
+ >;
141
+ }
142
+
143
+ interface UpdateApprovalTemplateCategoryMutationData {
144
+ readonly updateApprovalTemplateCategory: ApprovalTemplateCategoryRecord;
145
+ }
146
+
147
+ interface TemplateDesignerQueryData {
148
+ readonly approvalTemplate: ApprovalTemplateRecord;
149
+ readonly approvalTemplateVersions: readonly VersionJsonRecord[];
150
+ readonly formDefinitions: readonly FormDefinitionRecord[];
151
+ }
152
+
153
+ interface FormVersionsQueryData {
154
+ readonly formDefinitionVersions: readonly FormDefinitionVersionRecord[];
155
+ }
156
+
157
+ interface MembersQueryData {
158
+ readonly members: readonly MemberProfileRecord[];
159
+ }
160
+
161
+ interface SearchMembersQueryData {
162
+ readonly searchMembers: readonly MemberProfileRecord[];
163
+ }
164
+
165
+ interface UpdateTemplateDraftMutationData {
166
+ readonly updateApprovalTemplateDraft: VersionJsonRecord;
167
+ }
168
+
169
+ interface PublishTemplateVersionMutationData {
170
+ readonly publishApprovalTemplateVersion: VersionJsonRecord;
171
+ }
172
+
173
+ interface RollbackTemplateVersionMutationData {
174
+ readonly rollbackApprovalTemplateVersion: VersionJsonRecord;
175
+ }
176
+
177
+ interface ForkTemplateMutationData {
178
+ readonly forkApprovalTemplate: VersionJsonRecord;
179
+ }
180
+
181
+ interface DryRunApprovalWorkflowMutationData {
182
+ readonly dryRunApprovalWorkflow: WorkflowDryRunResultRecord;
183
+ }
184
+
185
+ interface VersionJsonRecord extends Omit<
186
+ ApprovalTemplateVersionRecord,
187
+ 'workflowDefinition'
188
+ > {
189
+ readonly workflowDefinitionJson: string;
190
+ }
191
+
192
+ export async function listApprovalTemplates(): Promise<
193
+ readonly ApprovalTemplateRecord[]
194
+ > {
195
+ const data = await requestGraphQl<ApprovalTemplatesQueryData>(
196
+ `query ApprovalTemplates {
197
+ approvalTemplates {
198
+ category
199
+ categoryId
200
+ categoryDetail {
201
+ id
202
+ isActive
203
+ name
204
+ }
205
+ currentVersionId
206
+ description
207
+ id
208
+ name
209
+ updatedAt
210
+ }
211
+ }`,
212
+ );
213
+
214
+ return data.approvalTemplates;
215
+ }
216
+
217
+ export async function listApprovalTemplatesPage({
218
+ page,
219
+ pageSize,
220
+ searchText,
221
+ status,
222
+ categoryId,
223
+ }: {
224
+ readonly categoryId?: string | null;
225
+ readonly page: number;
226
+ readonly pageSize: number;
227
+ readonly searchText?: string;
228
+ readonly status?: ApprovalTemplateListStatus | null;
229
+ }): Promise<ApprovalTemplatesPage> {
230
+ const data = await requestGraphQl<ApprovalTemplatesPageQueryData>(
231
+ `query ApprovalTemplatesPage(
232
+ $page: Int
233
+ $pageSize: Int
234
+ $searchText: String
235
+ $status: ApprovalTemplateListStatus
236
+ $categoryId: String
237
+ ) {
238
+ approvalTemplates(
239
+ categoryId: $categoryId
240
+ page: $page
241
+ pageSize: $pageSize
242
+ searchText: $searchText
243
+ status: $status
244
+ ) {
245
+ category
246
+ categoryId
247
+ categoryDetail {
248
+ id
249
+ isActive
250
+ name
251
+ }
252
+ currentVersionId
253
+ description
254
+ id
255
+ name
256
+ updatedAt
257
+ }
258
+ approvalTemplateCount(
259
+ categoryId: $categoryId
260
+ searchText: $searchText
261
+ status: $status
262
+ )
263
+ }`,
264
+ {
265
+ categoryId: categoryId ?? null,
266
+ page,
267
+ pageSize,
268
+ searchText,
269
+ status: status ?? null,
270
+ },
271
+ );
272
+
273
+ return {
274
+ templates: data.approvalTemplates,
275
+ totalCount: data.approvalTemplateCount,
276
+ };
277
+ }
278
+
279
+ export async function listApprovalTemplateCategoriesPage({
280
+ page,
281
+ pageSize,
282
+ searchText,
283
+ status,
284
+ }: {
285
+ readonly page: number;
286
+ readonly pageSize: number;
287
+ readonly searchText?: string;
288
+ readonly status?: ApprovalTemplateCategoryStatus | null;
289
+ }): Promise<ApprovalTemplateCategoriesPage> {
290
+ const data = await requestGraphQl<ApprovalTemplateCategoriesPageQueryData>(
291
+ `query ApprovalTemplateCategoriesPage(
292
+ $page: Int
293
+ $pageSize: Int
294
+ $searchText: String
295
+ $status: ApprovalTemplateCategoryStatus
296
+ ) {
297
+ approvalTemplateCategories(
298
+ page: $page
299
+ pageSize: $pageSize
300
+ searchText: $searchText
301
+ status: $status
302
+ ) {
303
+ createdAt
304
+ description
305
+ id
306
+ isActive
307
+ name
308
+ sortOrder
309
+ updatedAt
310
+ }
311
+ approvalTemplateCategoryCount(
312
+ searchText: $searchText
313
+ status: $status
314
+ )
315
+ }`,
316
+ { page, pageSize, searchText, status: status ?? null },
317
+ );
318
+
319
+ return {
320
+ categories: data.approvalTemplateCategories,
321
+ totalCount: data.approvalTemplateCategoryCount,
322
+ };
323
+ }
324
+
325
+ export async function createApprovalTemplate({
326
+ categoryId,
327
+ name,
328
+ }: {
329
+ readonly categoryId: string | null;
330
+ readonly name: string;
331
+ }): Promise<string> {
332
+ const data = await requestGraphQl<CreateApprovalTemplateMutationData>(
333
+ `mutation CreateApprovalTemplate($input: CreateApprovalTemplateInput!) {
334
+ createApprovalTemplate(input: $input) {
335
+ id
336
+ }
337
+ }`,
338
+ {
339
+ input: {
340
+ category: null,
341
+ categoryId,
342
+ createdByMemberId: null,
343
+ description: null,
344
+ formDefinitionVersionId: null,
345
+ name,
346
+ },
347
+ },
348
+ );
349
+
350
+ return data.createApprovalTemplate.id;
351
+ }
352
+
353
+ export async function createApprovalTemplateCategory({
354
+ description,
355
+ isActive,
356
+ name,
357
+ sortOrder,
358
+ }: {
359
+ readonly description: string | null;
360
+ readonly isActive: boolean;
361
+ readonly name: string;
362
+ readonly sortOrder: number;
363
+ }): Promise<ApprovalTemplateCategoryRecord> {
364
+ const data = await requestGraphQl<CreateApprovalTemplateCategoryMutationData>(
365
+ `mutation CreateApprovalTemplateCategory($input: CreateApprovalTemplateCategoryInput!) {
366
+ createApprovalTemplateCategory(input: $input) {
367
+ createdAt
368
+ description
369
+ id
370
+ isActive
371
+ name
372
+ sortOrder
373
+ updatedAt
374
+ }
375
+ }`,
376
+ { input: { description, isActive, name, sortOrder } },
377
+ );
378
+
379
+ return data.createApprovalTemplateCategory;
380
+ }
381
+
382
+ export async function updateApprovalTemplateCategory({
383
+ description,
384
+ id,
385
+ isActive,
386
+ name,
387
+ sortOrder,
388
+ }: {
389
+ readonly description: string | null;
390
+ readonly id: string;
391
+ readonly isActive: boolean;
392
+ readonly name: string;
393
+ readonly sortOrder: number;
394
+ }): Promise<ApprovalTemplateCategoryRecord> {
395
+ const data = await requestGraphQl<UpdateApprovalTemplateCategoryMutationData>(
396
+ `mutation UpdateApprovalTemplateCategory($input: UpdateApprovalTemplateCategoryInput!) {
397
+ updateApprovalTemplateCategory(input: $input) {
398
+ createdAt
399
+ description
400
+ id
401
+ isActive
402
+ name
403
+ sortOrder
404
+ updatedAt
405
+ }
406
+ }`,
407
+ { input: { description, id, isActive, name, sortOrder } },
408
+ );
409
+
410
+ return data.updateApprovalTemplateCategory;
411
+ }
412
+
413
+ export async function deleteApprovalTemplateCategory(
414
+ id: string,
415
+ ): Promise<void> {
416
+ await requestGraphQl<DeleteApprovalTemplateCategoryMutationData>(
417
+ `mutation DeleteApprovalTemplateCategory($id: String!) {
418
+ deleteApprovalTemplateCategory(id: $id) {
419
+ id
420
+ }
421
+ }`,
422
+ { id },
423
+ );
424
+ }
425
+
426
+ export async function readTemplateDesigner(
427
+ templateId: string,
428
+ ): Promise<TemplateDesignerRecord> {
429
+ const data = await requestGraphQl<TemplateDesignerQueryData>(
430
+ `query TemplateDesigner($id: String!) {
431
+ approvalTemplate(id: $id) {
432
+ category
433
+ categoryId
434
+ categoryDetail {
435
+ id
436
+ isActive
437
+ name
438
+ }
439
+ currentVersionId
440
+ description
441
+ id
442
+ name
443
+ updatedAt
444
+ }
445
+ approvalTemplateVersions(templateId: $id) {
446
+ archivedAt
447
+ formDefinitionVersionId
448
+ id
449
+ initiatorPolicyCel
450
+ notificationConfigJson
451
+ publishedAt
452
+ slaDefaultsJson
453
+ status
454
+ updatedAt
455
+ version
456
+ workflowDefinitionJson
457
+ }
458
+ formDefinitions {
459
+ currentVersionId
460
+ id
461
+ name
462
+ updatedAt
463
+ }
464
+ }`,
465
+ { id: templateId },
466
+ );
467
+ const formVersionLists = await Promise.all(
468
+ data.formDefinitions.map((definition) =>
469
+ readFormDefinitionVersions(definition.id),
470
+ ),
471
+ );
472
+
473
+ return {
474
+ formVersions: data.formDefinitions.flatMap((definition, index) =>
475
+ formVersionLists[index]
476
+ .filter((version) => version.status === 'PUBLISHED')
477
+ .map((version) => ({
478
+ formDefinitionId: definition.id,
479
+ formName: definition.name,
480
+ id: version.id,
481
+ label: `${definition.name} v${version.version}`,
482
+ schema: version.schema,
483
+ version: version.version,
484
+ })),
485
+ ),
486
+ template: data.approvalTemplate,
487
+ versions: data.approvalTemplateVersions.map(parseVersionJson),
488
+ };
489
+ }
490
+
491
+ export async function searchPublishedFormVersionOptions(
492
+ searchText: string,
493
+ ): Promise<readonly PublishedFormVersionOption[]> {
494
+ const data = await requestGraphQl<
495
+ Pick<TemplateDesignerQueryData, 'formDefinitions'>
496
+ >(
497
+ `query PublishedFormVersionOptions {
498
+ formDefinitions {
499
+ currentVersionId
500
+ id
501
+ name
502
+ updatedAt
503
+ }
504
+ }`,
505
+ );
506
+ const normalizedSearchText = searchText.trim().toLocaleLowerCase();
507
+ const matchedDefinitions = data.formDefinitions.filter((definition) =>
508
+ normalizedSearchText
509
+ ? definition.name.toLocaleLowerCase().includes(normalizedSearchText)
510
+ : true,
511
+ );
512
+ const formVersionLists = await Promise.all(
513
+ matchedDefinitions.map((definition) =>
514
+ readFormDefinitionVersions(definition.id),
515
+ ),
516
+ );
517
+
518
+ return matchedDefinitions.flatMap((definition, index) =>
519
+ formVersionLists[index]
520
+ .filter((version) => version.status === 'PUBLISHED')
521
+ .map((version) => ({
522
+ formDefinitionId: definition.id,
523
+ formName: definition.name,
524
+ id: version.id,
525
+ label: `${definition.name} v${version.version}`,
526
+ schema: version.schema,
527
+ version: version.version,
528
+ })),
529
+ );
530
+ }
531
+
532
+ export async function resolveMemberOptions(
533
+ memberIds: readonly string[],
534
+ ): Promise<readonly MemberProfileRecord[]> {
535
+ if (memberIds.length === 0) {
536
+ return [];
537
+ }
538
+
539
+ const data = await requestGraphQl<MembersQueryData>(
540
+ `query SelectedMembers($memberIds: [String!]!) {
541
+ members(memberIds: $memberIds) {
542
+ email
543
+ memberId
544
+ name
545
+ }
546
+ }`,
547
+ { memberIds },
548
+ );
549
+
550
+ return data.members;
551
+ }
552
+
553
+ export async function searchMemberOptions(
554
+ searchText: string,
555
+ ): Promise<readonly MemberProfileRecord[]> {
556
+ const data = await requestGraphQl<SearchMembersQueryData>(
557
+ `query MemberOptions($searchText: String!) {
558
+ searchMembers(searchText: $searchText) {
559
+ email
560
+ memberId
561
+ name
562
+ }
563
+ }`,
564
+ { searchText },
565
+ );
566
+
567
+ return data.searchMembers;
568
+ }
569
+
570
+ export async function updateApprovalTemplateDraft({
571
+ formDefinitionVersionId,
572
+ initiatorPolicyCel,
573
+ versionId,
574
+ workflowDefinition,
575
+ }: {
576
+ readonly formDefinitionVersionId: string | null;
577
+ readonly initiatorPolicyCel: string | null;
578
+ readonly versionId: string;
579
+ readonly workflowDefinition: WorkflowDefinition;
580
+ }): Promise<ApprovalTemplateVersionRecord> {
581
+ const data = await requestGraphQl<UpdateTemplateDraftMutationData>(
582
+ `mutation UpdateApprovalTemplateDraft($input: UpdateApprovalTemplateDraftInput!) {
583
+ updateApprovalTemplateDraft(input: $input) {
584
+ archivedAt
585
+ formDefinitionVersionId
586
+ id
587
+ initiatorPolicyCel
588
+ notificationConfigJson
589
+ publishedAt
590
+ slaDefaultsJson
591
+ status
592
+ updatedAt
593
+ version
594
+ workflowDefinitionJson
595
+ }
596
+ }`,
597
+ {
598
+ input: {
599
+ formDefinitionVersionId,
600
+ initiatorPolicyCel,
601
+ notificationConfigJson: null,
602
+ slaDefaultsJson: null,
603
+ versionId,
604
+ workflowDefinitionJson: JSON.stringify(workflowDefinition),
605
+ },
606
+ },
607
+ );
608
+
609
+ return parseVersionJson(data.updateApprovalTemplateDraft);
610
+ }
611
+
612
+ export async function forkApprovalTemplate(
613
+ templateId: string,
614
+ ): Promise<ApprovalTemplateVersionRecord> {
615
+ const data = await requestGraphQl<ForkTemplateMutationData>(
616
+ `mutation ForkApprovalTemplate($templateId: String!) {
617
+ forkApprovalTemplate(templateId: $templateId) {
618
+ archivedAt
619
+ formDefinitionVersionId
620
+ id
621
+ initiatorPolicyCel
622
+ notificationConfigJson
623
+ publishedAt
624
+ slaDefaultsJson
625
+ status
626
+ updatedAt
627
+ version
628
+ workflowDefinitionJson
629
+ }
630
+ }`,
631
+ { templateId },
632
+ );
633
+
634
+ return parseVersionJson(data.forkApprovalTemplate);
635
+ }
636
+
637
+ export async function publishApprovalTemplateVersion(
638
+ versionId: string,
639
+ ): Promise<ApprovalTemplateVersionRecord> {
640
+ const data = await requestGraphQl<PublishTemplateVersionMutationData>(
641
+ `mutation PublishApprovalTemplateVersion($versionId: String!) {
642
+ publishApprovalTemplateVersion(versionId: $versionId) {
643
+ archivedAt
644
+ formDefinitionVersionId
645
+ id
646
+ initiatorPolicyCel
647
+ notificationConfigJson
648
+ publishedAt
649
+ slaDefaultsJson
650
+ status
651
+ updatedAt
652
+ version
653
+ workflowDefinitionJson
654
+ }
655
+ }`,
656
+ { versionId },
657
+ );
658
+
659
+ return parseVersionJson(data.publishApprovalTemplateVersion);
660
+ }
661
+
662
+ export async function rollbackApprovalTemplateVersion(
663
+ versionId: string,
664
+ ): Promise<ApprovalTemplateVersionRecord> {
665
+ const data = await requestGraphQl<RollbackTemplateVersionMutationData>(
666
+ `mutation RollbackApprovalTemplateVersion($versionId: String!) {
667
+ rollbackApprovalTemplateVersion(versionId: $versionId) {
668
+ archivedAt
669
+ formDefinitionVersionId
670
+ id
671
+ initiatorPolicyCel
672
+ notificationConfigJson
673
+ publishedAt
674
+ slaDefaultsJson
675
+ status
676
+ updatedAt
677
+ version
678
+ workflowDefinitionJson
679
+ }
680
+ }`,
681
+ { versionId },
682
+ );
683
+
684
+ return parseVersionJson(data.rollbackApprovalTemplateVersion);
685
+ }
686
+
687
+ export async function dryRunApprovalWorkflow({
688
+ formData,
689
+ initiatorMemberId,
690
+ initiatorMetadataSnapshot,
691
+ workflowDefinition,
692
+ }: {
693
+ readonly formData: Readonly<Record<string, unknown>>;
694
+ readonly initiatorMemberId: string;
695
+ readonly initiatorMetadataSnapshot: Readonly<Record<string, unknown>> | null;
696
+ readonly workflowDefinition: WorkflowDefinition;
697
+ }): Promise<WorkflowDryRunResultRecord> {
698
+ const data = await requestGraphQl<DryRunApprovalWorkflowMutationData>(
699
+ `mutation DryRunApprovalWorkflow($input: DryRunApprovalWorkflowInput!) {
700
+ dryRunApprovalWorkflow(input: $input) {
701
+ errors
702
+ valid
703
+ steps {
704
+ assigneeMemberId
705
+ edgeDefault
706
+ edgeId
707
+ edgeLabel
708
+ edgeMatched
709
+ edgeReason
710
+ entryCondition
711
+ entryConditionMatched
712
+ id
713
+ message
714
+ nodeId
715
+ nodeLabel
716
+ nodeType
717
+ status
718
+ }
719
+ }
720
+ }`,
721
+ {
722
+ input: {
723
+ formDataJson: JSON.stringify(formData),
724
+ initiatorMemberId,
725
+ initiatorMetadataSnapshotJson: initiatorMetadataSnapshot
726
+ ? JSON.stringify(initiatorMetadataSnapshot)
727
+ : null,
728
+ workflowDefinitionJson: JSON.stringify(workflowDefinition),
729
+ },
730
+ },
731
+ );
732
+
733
+ return data.dryRunApprovalWorkflow;
734
+ }
735
+
736
+ async function readFormDefinitionVersions(
737
+ formDefinitionId: string,
738
+ ): Promise<readonly FormDefinitionVersionRecord[]> {
739
+ const data = await requestGraphQl<FormVersionsQueryData>(
740
+ `query FormVersions($formDefinitionId: String!) {
741
+ formDefinitionVersions(formDefinitionId: $formDefinitionId) {
742
+ formDefinitionId
743
+ id
744
+ publishedAt
745
+ schemaJson
746
+ status
747
+ version
748
+ }
749
+ }`,
750
+ { formDefinitionId },
751
+ );
752
+
753
+ return data.formDefinitionVersions.map((version) => ({
754
+ ...version,
755
+ schema: parseFormDefinitionSchema(version.schemaJson),
756
+ }));
757
+ }
758
+
759
+ function parseVersionJson(
760
+ version: VersionJsonRecord,
761
+ ): ApprovalTemplateVersionRecord {
762
+ return {
763
+ ...version,
764
+ workflowDefinition: JSON.parse(
765
+ version.workflowDefinitionJson,
766
+ ) as WorkflowDefinition,
767
+ };
768
+ }
769
+
770
+ function parseFormDefinitionSchema(schemaJson: string): FormDefinitionSchema {
771
+ return JSON.parse(schemaJson) as FormDefinitionSchema;
772
+ }