@rytass/bpm-core-client 0.3.0 → 0.5.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 +22 -0
  2. package/eslint.config.mjs +19 -0
  3. package/jest.config.cts +10 -0
  4. package/package.json +3 -4
  5. package/project.json +66 -0
  6. package/src/lib/api-auth-client.ts +182 -0
  7. package/src/lib/client-config.ts +99 -0
  8. package/src/lib/form/form-api.spec.ts +81 -0
  9. package/src/lib/form/form-api.ts +402 -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 +128 -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 +711 -0
  16. package/src/lib/template/template-api.spec.ts +88 -0
  17. package/src/lib/template/template-api.ts +894 -0
  18. package/src/lib/workflow/workflow-api.spec.ts +132 -0
  19. package/src/lib/workflow/workflow-api.ts +2124 -0
  20. package/tsconfig.json +27 -0
  21. package/tsconfig.lib.json +16 -0
  22. package/tsconfig.spec.json +16 -0
  23. package/src/index.js +0 -8
  24. package/src/index.js.map +0 -1
  25. package/src/lib/api-auth-client.d.ts +0 -73
  26. package/src/lib/api-auth-client.js +0 -129
  27. package/src/lib/api-auth-client.js.map +0 -1
  28. package/src/lib/client-config.d.ts +0 -81
  29. package/src/lib/client-config.js +0 -63
  30. package/src/lib/client-config.js.map +0 -1
  31. package/src/lib/form/form-api.d.ts +0 -54
  32. package/src/lib/form/form-api.js +0 -240
  33. package/src/lib/form/form-api.js.map +0 -1
  34. package/src/lib/form/form-rendering.d.ts +0 -52
  35. package/src/lib/form/form-rendering.js +0 -341
  36. package/src/lib/form/form-rendering.js.map +0 -1
  37. package/src/lib/form/index.js +0 -6
  38. package/src/lib/form/index.js.map +0 -1
  39. package/src/lib/graphql-client.d.ts +0 -45
  40. package/src/lib/graphql-client.js +0 -101
  41. package/src/lib/graphql-client.js.map +0 -1
  42. package/src/lib/member-api.d.ts +0 -49
  43. package/src/lib/member-api.js +0 -72
  44. package/src/lib/member-api.js.map +0 -1
  45. package/src/lib/organization/index.js +0 -5
  46. package/src/lib/organization/index.js.map +0 -1
  47. package/src/lib/organization/organization-api.d.ts +0 -173
  48. package/src/lib/organization/organization-api.js +0 -394
  49. package/src/lib/organization/organization-api.js.map +0 -1
  50. package/src/lib/template/index.js +0 -5
  51. package/src/lib/template/index.js.map +0 -1
  52. package/src/lib/template/template-api.d.ts +0 -174
  53. package/src/lib/template/template-api.js +0 -469
  54. package/src/lib/template/template-api.js.map +0 -1
  55. package/src/lib/workflow/index.js +0 -5
  56. package/src/lib/workflow/index.js.map +0 -1
  57. package/src/lib/workflow/workflow-api.d.ts +0 -517
  58. package/src/lib/workflow/workflow-api.js +0 -1068
  59. package/src/lib/workflow/workflow-api.js.map +0 -1
  60. /package/src/{index.d.ts → index.ts} +0 -0
  61. /package/src/lib/form/{index.d.ts → index.ts} +0 -0
  62. /package/src/lib/organization/{index.d.ts → index.ts} +0 -0
  63. /package/src/lib/template/{index.d.ts → index.ts} +0 -0
  64. /package/src/lib/workflow/{index.d.ts → index.ts} +0 -0
@@ -0,0 +1,402 @@
1
+ import {
2
+ FormDefinitionSchema,
3
+ FormFieldDefinition,
4
+ FormUiSchema,
5
+ } from '@rytass/bpm-core-shared/form';
6
+ import { requestGraphQl } from '../graphql-client';
7
+
8
+ export interface FormDefinitionRecord {
9
+ readonly currentVersionId: string | null;
10
+ readonly currentVersionCreatedAt: string | null;
11
+ readonly currentVersionNumber: number | null;
12
+ readonly currentVersionPublishedAt: string | null;
13
+ readonly description: string | null;
14
+ readonly id: string;
15
+ readonly name: string;
16
+ readonly updatedAt: string;
17
+ }
18
+
19
+ export type FormDefinitionListStatus = 'DRAFT' | 'PUBLISHED';
20
+
21
+ export interface FormDefinitionVersionRecord {
22
+ readonly id: string;
23
+ readonly publishedAt: string | null;
24
+ readonly schema: FormDefinitionSchema;
25
+ readonly schemaJson: string;
26
+ readonly status: 'ARCHIVED' | 'DRAFT' | 'PUBLISHED';
27
+ readonly uiSchema: FormUiSchema;
28
+ readonly uiSchemaJson: string;
29
+ readonly updatedAt: string;
30
+ readonly version: number;
31
+ }
32
+
33
+ export interface FormBuilderRecord {
34
+ readonly definition: FormDefinitionRecord;
35
+ readonly versions: readonly FormDefinitionVersionRecord[];
36
+ }
37
+
38
+ export interface FormSchemaLintResult {
39
+ readonly errors: readonly string[];
40
+ readonly valid: boolean;
41
+ }
42
+
43
+ interface FormDefinitionsQueryData {
44
+ readonly formDefinitions: readonly FormDefinitionRecord[];
45
+ }
46
+
47
+ interface FormDefinitionsPageQueryData extends FormDefinitionsQueryData {
48
+ readonly formDefinitionCount: number;
49
+ }
50
+
51
+ interface CreateFormDefinitionMutationData {
52
+ readonly createFormDefinition: Pick<FormDefinitionRecord, 'id'>;
53
+ }
54
+
55
+ interface UpdateFormDefinitionMutationData {
56
+ readonly updateFormDefinition: FormDefinitionRecord;
57
+ }
58
+
59
+ interface FormBuilderQueryData {
60
+ readonly formDefinition: FormDefinitionRecord;
61
+ readonly formDefinitionVersions: readonly VersionJsonRecord[];
62
+ }
63
+
64
+ interface VersionJsonRecord extends Omit<
65
+ FormDefinitionVersionRecord,
66
+ 'schema' | 'uiSchema'
67
+ > {
68
+ readonly schemaJson: string;
69
+ readonly uiSchemaJson: string;
70
+ }
71
+
72
+ interface UpdateDraftMutationData {
73
+ readonly updateFormDefinitionDraft: VersionJsonRecord;
74
+ }
75
+
76
+ interface PublishVersionMutationData {
77
+ readonly publishFormDefinitionVersion: VersionJsonRecord;
78
+ }
79
+
80
+ interface PublishContentMutationData {
81
+ readonly publishFormDefinitionContent: VersionJsonRecord;
82
+ }
83
+
84
+ interface LintFormSchemaQueryData {
85
+ readonly lintFormSchema: FormSchemaLintResult;
86
+ }
87
+
88
+ export async function listFormDefinitions(): Promise<
89
+ readonly FormDefinitionRecord[]
90
+ > {
91
+ const data = await requestGraphQl<FormDefinitionsQueryData>(
92
+ `query FormDefinitions {
93
+ formDefinitions {
94
+ currentVersionCreatedAt
95
+ currentVersionId
96
+ currentVersionNumber
97
+ currentVersionPublishedAt
98
+ description
99
+ id
100
+ name
101
+ updatedAt
102
+ }
103
+ }`,
104
+ );
105
+
106
+ return data.formDefinitions;
107
+ }
108
+
109
+ export async function listFormDefinitionsPage({
110
+ page,
111
+ pageSize,
112
+ status,
113
+ }: {
114
+ readonly page: number;
115
+ readonly pageSize: number;
116
+ readonly status?: FormDefinitionListStatus | null;
117
+ }): Promise<{
118
+ readonly forms: readonly FormDefinitionRecord[];
119
+ readonly totalCount: number;
120
+ }> {
121
+ const data = await requestGraphQl<FormDefinitionsPageQueryData>(
122
+ `query FormDefinitionsPage(
123
+ $page: Int!
124
+ $pageSize: Int!
125
+ $status: FormDefinitionListStatus
126
+ ) {
127
+ formDefinitions(page: $page, pageSize: $pageSize, status: $status) {
128
+ currentVersionCreatedAt
129
+ currentVersionId
130
+ currentVersionNumber
131
+ currentVersionPublishedAt
132
+ description
133
+ id
134
+ name
135
+ updatedAt
136
+ }
137
+ formDefinitionCount(status: $status)
138
+ }`,
139
+ { page, pageSize, status: status ?? null },
140
+ );
141
+
142
+ return {
143
+ forms: data.formDefinitions,
144
+ totalCount: data.formDefinitionCount,
145
+ };
146
+ }
147
+
148
+ export async function createFormDefinition(name: string): Promise<string> {
149
+ const data = await requestGraphQl<CreateFormDefinitionMutationData>(
150
+ `mutation CreateFormDefinition($input: CreateFormDefinitionInput!) {
151
+ createFormDefinition(input: $input) {
152
+ id
153
+ }
154
+ }`,
155
+ {
156
+ input: {
157
+ createdByMemberId: null,
158
+ description: null,
159
+ name,
160
+ schemaJson: null,
161
+ uiSchemaJson: null,
162
+ },
163
+ },
164
+ );
165
+
166
+ return data.createFormDefinition.id;
167
+ }
168
+
169
+ export async function updateFormDefinition(
170
+ id: string,
171
+ name: string,
172
+ ): Promise<FormDefinitionRecord> {
173
+ const data = await requestGraphQl<UpdateFormDefinitionMutationData>(
174
+ `mutation UpdateFormDefinition($input: UpdateFormDefinitionInput!) {
175
+ updateFormDefinition(input: $input) {
176
+ currentVersionCreatedAt
177
+ currentVersionId
178
+ currentVersionNumber
179
+ currentVersionPublishedAt
180
+ description
181
+ id
182
+ name
183
+ updatedAt
184
+ }
185
+ }`,
186
+ {
187
+ input: {
188
+ description: null,
189
+ id,
190
+ name,
191
+ },
192
+ },
193
+ );
194
+
195
+ return data.updateFormDefinition;
196
+ }
197
+
198
+ export async function readFormBuilder(
199
+ formDefinitionId: string,
200
+ ): Promise<FormBuilderRecord> {
201
+ const data = await requestGraphQl<FormBuilderQueryData>(
202
+ `query FormBuilder($id: String!) {
203
+ formDefinition(id: $id) {
204
+ currentVersionCreatedAt
205
+ currentVersionId
206
+ currentVersionNumber
207
+ currentVersionPublishedAt
208
+ description
209
+ id
210
+ name
211
+ updatedAt
212
+ }
213
+ formDefinitionVersions(formDefinitionId: $id) {
214
+ id
215
+ publishedAt
216
+ schemaJson
217
+ status
218
+ uiSchemaJson
219
+ updatedAt
220
+ version
221
+ }
222
+ }`,
223
+ { id: formDefinitionId },
224
+ );
225
+
226
+ return {
227
+ definition: data.formDefinition,
228
+ versions: data.formDefinitionVersions.map(parseVersionJson),
229
+ };
230
+ }
231
+
232
+ export async function updateFormDefinitionDraft(
233
+ versionId: string,
234
+ schema: FormDefinitionSchema,
235
+ uiSchema: FormUiSchema,
236
+ ): Promise<FormDefinitionVersionRecord> {
237
+ const data = await requestGraphQl<UpdateDraftMutationData>(
238
+ `mutation UpdateFormDefinitionDraft($input: UpdateFormDefinitionDraftInput!) {
239
+ updateFormDefinitionDraft(input: $input) {
240
+ id
241
+ publishedAt
242
+ schemaJson
243
+ status
244
+ uiSchemaJson
245
+ updatedAt
246
+ version
247
+ }
248
+ }`,
249
+ {
250
+ input: {
251
+ schemaJson: JSON.stringify(schema),
252
+ uiSchemaJson: JSON.stringify(uiSchema),
253
+ versionId,
254
+ },
255
+ },
256
+ );
257
+
258
+ return parseVersionJson(data.updateFormDefinitionDraft);
259
+ }
260
+
261
+ export async function publishFormDefinitionVersion(
262
+ versionId: string,
263
+ ): Promise<FormDefinitionVersionRecord> {
264
+ const data = await requestGraphQl<PublishVersionMutationData>(
265
+ `mutation PublishFormDefinitionVersion($versionId: String!) {
266
+ publishFormDefinitionVersion(versionId: $versionId) {
267
+ id
268
+ publishedAt
269
+ schemaJson
270
+ status
271
+ uiSchemaJson
272
+ updatedAt
273
+ version
274
+ }
275
+ }`,
276
+ { versionId },
277
+ );
278
+
279
+ return parseVersionJson(data.publishFormDefinitionVersion);
280
+ }
281
+
282
+ /**
283
+ * Publishes the given content as the form's current version atomically.
284
+ * Before the first publish the single draft is updated and published;
285
+ * afterwards a brand-new published version is created directly. Content
286
+ * identical to the current published version is a no-op.
287
+ */
288
+ export async function publishFormDefinitionContent(
289
+ formDefinitionId: string,
290
+ schema: FormDefinitionSchema,
291
+ uiSchema: FormUiSchema,
292
+ ): Promise<FormDefinitionVersionRecord> {
293
+ const data = await requestGraphQl<PublishContentMutationData>(
294
+ `mutation PublishFormDefinitionContent($input: PublishFormDefinitionContentInput!) {
295
+ publishFormDefinitionContent(input: $input) {
296
+ id
297
+ publishedAt
298
+ schemaJson
299
+ status
300
+ uiSchemaJson
301
+ updatedAt
302
+ version
303
+ }
304
+ }`,
305
+ {
306
+ input: {
307
+ formDefinitionId,
308
+ schemaJson: JSON.stringify(schema),
309
+ uiSchemaJson: JSON.stringify(uiSchema),
310
+ },
311
+ },
312
+ );
313
+
314
+ return parseVersionJson(data.publishFormDefinitionContent);
315
+ }
316
+
317
+ export async function lintFormSchema(
318
+ schema: FormDefinitionSchema,
319
+ uiSchema: FormUiSchema,
320
+ ): Promise<FormSchemaLintResult> {
321
+ const data = await requestGraphQl<LintFormSchemaQueryData>(
322
+ `query LintFormSchema($input: LintFormSchemaInput!) {
323
+ lintFormSchema(input: $input) {
324
+ errors
325
+ valid
326
+ }
327
+ }`,
328
+ {
329
+ input: {
330
+ schemaJson: JSON.stringify(schema),
331
+ uiSchemaJson: JSON.stringify(uiSchema),
332
+ },
333
+ },
334
+ );
335
+
336
+ return data.lintFormSchema;
337
+ }
338
+
339
+ export function createFieldDefinition(
340
+ type: FormFieldDefinition['type'],
341
+ index: number,
342
+ ): FormFieldDefinition {
343
+ const fieldKey = `${type}_${index}`;
344
+ const base = {
345
+ fieldKey,
346
+ label: readDefaultFieldLabel(type, index),
347
+ required: false,
348
+ type,
349
+ };
350
+
351
+ if (type === 'select' || type === 'radio' || type === 'checkbox') {
352
+ return {
353
+ ...base,
354
+ options: [
355
+ { label: '選項 A', value: 'option_a' },
356
+ { label: '選項 B', value: 'option_b' },
357
+ ],
358
+ type,
359
+ };
360
+ }
361
+
362
+ if (type === 'file_upload') {
363
+ return {
364
+ ...base,
365
+ maxFiles: 1,
366
+ type,
367
+ };
368
+ }
369
+
370
+ return base as FormFieldDefinition;
371
+ }
372
+
373
+ function parseVersionJson(
374
+ version: VersionJsonRecord,
375
+ ): FormDefinitionVersionRecord {
376
+ return {
377
+ ...version,
378
+ schema: JSON.parse(version.schemaJson) as FormDefinitionSchema,
379
+ uiSchema: JSON.parse(version.uiSchemaJson) as FormUiSchema,
380
+ };
381
+ }
382
+
383
+ function readDefaultFieldLabel(
384
+ type: FormFieldDefinition['type'],
385
+ index: number,
386
+ ): string {
387
+ const labels: Readonly<Record<FormFieldDefinition['type'], string>> = {
388
+ boolean: '開關',
389
+ checkbox: '複選',
390
+ date: '日期',
391
+ datetime: '日期時間',
392
+ file_upload: '附件',
393
+ money: '金額',
394
+ number: '數字',
395
+ radio: '單選',
396
+ select: '下拉選單',
397
+ text: '文字',
398
+ textarea: '長文字',
399
+ };
400
+
401
+ return `${labels[type]} ${index}`;
402
+ }