@betterinternship/core 1.4.0 → 1.4.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.
@@ -1,346 +1,347 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DUMMY_FORM_METADATA = exports.FormMetadata = exports.FORM_SOURCE = exports.ALIGN_V = exports.ALIGN_H = exports.BLOCK_TYPES = exports.FIELD_TYPES = exports.SOURCES = exports.SCHEMA_VERSION = void 0;
4
- const zod_1 = require("zod");
5
- const fields_client_1 = require("./fields.client");
6
- exports.SCHEMA_VERSION = 1;
7
- exports.SOURCES = ['auto', 'prefill', 'derived', 'manual'];
8
- exports.FIELD_TYPES = ['text', 'signature'];
9
- exports.BLOCK_TYPES = [
10
- 'header',
11
- 'paragraph',
12
- 'form_field',
13
- 'form_phantom_field',
14
- 'divider',
15
- 'image',
16
- ];
17
- exports.ALIGN_H = ['left', 'center', 'right'];
18
- exports.ALIGN_V = ['top', 'middle', 'bottom'];
19
- exports.FORM_SOURCE = ['auto', 'prefill', 'derived', 'manual'];
20
- class FormMetadata {
21
- formMetadata;
22
- blocks;
23
- constructor(formMetadata) {
24
- this.formMetadata = formMetadata;
25
- this.blocks = formMetadata.schema.blocks;
26
- }
27
- getAllBlocks() {
28
- return this.blocks;
29
- }
30
- getBlocksByType(blockType) {
31
- return this.blocks.filter((block) => block.block_type === blockType);
32
- }
33
- getBlocksByPartyId(partyId) {
34
- return this.blocks.filter((block) => block.party_id === partyId);
35
- }
36
- getFields() {
37
- return this.blocks
38
- .filter((block) => block.block_type === 'form_field')
39
- .map((block) => block.content);
40
- }
41
- getField(index) {
42
- const fields = this.getFields();
43
- return fields[index];
44
- }
45
- getPhantomFields() {
46
- return this.blocks
47
- .filter((block) => block.block_type === 'form_phantom_field')
48
- .map((block) => block.content);
49
- }
50
- encodeAsJSON() {
51
- return JSON.stringify(this.formMetadata);
52
- }
53
- static decodeFromJSON(json) {
54
- return JSON.parse(json);
55
- }
56
- getLabel() {
57
- return this.formMetadata.label;
58
- }
59
- getFieldForClient(index, sourceDomains, derivationBase) {
60
- const field = this.getField(index);
61
- if (!field)
62
- throw new Error('Field does not exist');
63
- const finalParams = {
64
- ...derivationBase,
65
- ...sourceDomains,
66
- };
67
- const validator = this.parseValidator(field.field, finalParams);
68
- const prefiller = this.parsePrefiller(field.field, finalParams);
69
- const section = field.field.split('.')[0];
70
- let options = undefined;
71
- if (validator?.type === 'enum')
72
- options = validator.options;
73
- if (validator?.type === 'array') {
74
- const element = validator.element;
75
- if (element?.options)
76
- options = element.options;
77
- }
78
- const type = field.type === 'signature'
79
- ? 'signature'
80
- : validator
81
- ? (0, fields_client_1.getSchemaClientType)(validator)
82
- : 'text';
83
- const coerce = (value) => {
84
- switch (type) {
85
- case 'number': {
86
- const n = parseInt(value);
87
- return isNaN(n) ? 0 : n;
88
- }
89
- case 'date': {
90
- const n = parseInt(value);
91
- return isNaN(n) ? new Date() : new Date(n);
92
- }
93
- case 'checkbox': {
94
- return !!value?.trim();
95
- }
96
- case 'multiselect': {
97
- return value?.split('\n');
98
- }
99
- default:
100
- return value;
101
- }
102
- };
103
- return {
104
- field: field.field,
105
- shared: field.shared,
106
- label: field.label,
107
- source: field.source,
108
- tooltip_label: field.tooltip_label,
109
- coerce,
110
- type,
111
- section,
112
- validator,
113
- prefiller,
114
- options,
115
- };
116
- }
117
- getFieldsForClientService(sourceDomains, derivationBase) {
118
- const fields = this.getFields();
119
- return fields
120
- .map((field, i) => this.getFieldForClient(i, sourceDomains, derivationBase))
121
- .filter((field) => field !== null);
122
- }
123
- getFieldsForSigningService() {
124
- const fields = this.getFields();
125
- return fields
126
- .filter((field) => field.type !== 'image')
127
- .map((field) => ({
128
- field: field.field,
129
- type: field.type,
130
- x: field.x,
131
- y: field.y,
132
- w: field.w,
133
- h: field.h,
134
- align_h: (field.align_h ?? 'left'),
135
- align_v: (field.align_v ?? 'top'),
136
- page: field.page,
137
- }))
138
- .filter((field) => field !== null);
139
- }
140
- inferParams() {
141
- const inferenceRegex = /params\[\s*(['"])(.*?)\1\s*\]/g;
142
- const params = [];
143
- let match;
144
- for (const field of this.getFields()) {
145
- const validatorStr = typeof field.validator === 'string' ? field.validator : '';
146
- while ((match = inferenceRegex.exec(validatorStr)) !== null)
147
- if (!params.includes(match[2]))
148
- params.push(match[2]);
149
- }
150
- for (const field of this.getPhantomFields()) {
151
- const validatorStr = typeof field.validator === 'string' ? field.validator : '';
152
- while ((match = inferenceRegex.exec(validatorStr)) !== null)
153
- if (!params.includes(match[2]))
154
- params.push(match[2]);
155
- }
156
- return params;
157
- }
158
- parseValidator(fieldname, params = {}) {
159
- const field = this.getFields().find((f) => f.field === fieldname);
160
- if (!field)
161
- return null;
162
- const d = new Date();
163
- const defaults = {
164
- currentDate: d,
165
- currentDateTimestamp: d.getTime(),
166
- };
167
- const validatorStr = typeof field.validator === 'string' ? field.validator : '';
168
- const validator = this.populateParams(validatorStr, params);
169
- const ret = `return ${validator}`;
170
- const evaluator = new Function('z', 'params', ret);
171
- return evaluator(zod_1.default, { ...params, ...defaults });
172
- }
173
- parsePrefiller(fieldname, _params = {}) {
174
- const field = this.getFields().find((f) => f.field === fieldname);
175
- if (!field || !field.default_value)
176
- return null;
177
- try {
178
- const fn = eval(field.default_value);
179
- return typeof fn === 'function' ? fn : null;
180
- }
181
- catch (e) {
182
- console.error(`Failed to parse prefiller for field ${fieldname}`, e);
183
- return null;
184
- }
185
- }
186
- enumerateParams(s) {
187
- const detectedParams = s.match(/#\{[^}]*\}/g) ?? [];
188
- const params = detectedParams.map((dp) => {
189
- const [fieldName, propertyTree] = dp
190
- .replaceAll('#{', '')
191
- .replaceAll('}', '')
192
- .replaceAll(')', '')
193
- .split('(');
194
- const properties = propertyTree?.split('.') ?? [];
195
- return [fieldName, ...properties];
196
- });
197
- return params?.reduce((acc, cur, i) => ((acc[detectedParams[i]] = cur), acc), {});
198
- }
199
- populateParams(s, params) {
200
- const paramsReflection = this.enumerateParams(s);
201
- const paramsValues = {};
202
- for (const match in paramsReflection) {
203
- const path = paramsReflection[match];
204
- paramsValues[match] =
205
- path.reduce((acc, cur) => acc?.[cur], params) ?? '';
206
- }
207
- let out = s;
208
- for (const match in paramsValues) {
209
- const replacement = JSON.stringify(paramsValues[match]);
210
- out = out.replaceAll(match, replacement);
211
- }
212
- return out;
213
- }
214
- getSignatories() {
215
- return this.formMetadata.subscribers;
216
- }
217
- getSubscribers() {
218
- return this.formMetadata.subscribers;
219
- }
220
- getRequiredParties() {
221
- return this.formMetadata.parties;
222
- }
223
- }
224
- exports.FormMetadata = FormMetadata;
225
- exports.DUMMY_FORM_METADATA = {
226
- name: 'test-form',
227
- label: 'Test Form',
228
- schema_version: exports.SCHEMA_VERSION,
229
- schema: {
230
- blocks: [
231
- {
232
- block_type: 'header',
233
- order: 0,
234
- content: 'Student Information Form',
235
- party_id: 'party-1',
236
- },
237
- {
238
- block_type: 'paragraph',
239
- order: 1,
240
- content: 'Please fill in your personal details below.',
241
- party_id: 'party-1',
242
- },
243
- {
244
- block_type: 'form_field',
245
- order: 2,
246
- content: {
247
- field: 'student.full_name',
248
- type: 'text',
249
- x: 100,
250
- y: 100,
251
- w: 200,
252
- h: 20,
253
- page: 1,
254
- align_h: 'left',
255
- align_v: 'top',
256
- label: 'Full Name',
257
- tooltip_label: 'Enter your full name',
258
- shared: true,
259
- source: 'manual',
260
- default_value: '({ user }) => `${user?.first_name ?? ""} ${user?.last_name ?? ""}`',
261
- validator: 'z.string().min(1, "Name is required")',
262
- },
263
- party_id: 'party-1',
264
- },
265
- {
266
- block_type: 'form_field',
267
- order: 3,
268
- content: {
269
- field: 'student.email',
270
- type: 'text',
271
- x: 100,
272
- y: 130,
273
- w: 200,
274
- h: 20,
275
- page: 1,
276
- align_h: 'left',
277
- align_v: 'top',
278
- label: 'Email',
279
- tooltip_label: 'Enter your email address',
280
- shared: true,
281
- source: 'prefill',
282
- default_value: '({ user }) => user?.email ?? ""',
283
- validator: 'z.string().email("Invalid email")',
284
- },
285
- party_id: 'party-1',
286
- },
287
- {
288
- block_type: 'form_field',
289
- order: 4,
290
- content: {
291
- field: 'student.signature',
292
- type: 'signature',
293
- x: 100,
294
- y: 160,
295
- w: 150,
296
- h: 50,
297
- page: 1,
298
- align_h: 'left',
299
- align_v: 'top',
300
- label: 'Signature',
301
- tooltip_label: 'Please sign here',
302
- shared: true,
303
- source: 'manual',
304
- validator: 'z.string().min(1, "Signature is required")',
305
- },
306
- party_id: 'party-1',
307
- },
308
- {
309
- block_type: 'form_phantom_field',
310
- order: 5,
311
- content: {
312
- field: 'student.phone',
313
- type: 'text',
314
- label: 'Phone Number',
315
- tooltip_label: 'Optional contact number',
316
- shared: true,
317
- source: 'manual',
318
- validator: 'z.string().optional()',
319
- },
320
- party_id: 'party-1',
321
- },
322
- ],
323
- },
324
- parties: [
325
- {
326
- _id: 'party-1',
327
- order: 1,
328
- signatory_account: {
329
- account_id: 'user-1',
330
- name: 'John Doe',
331
- email: 'john@example.com',
332
- title: 'Student',
333
- },
334
- signed: false,
335
- },
336
- ],
337
- subscribers: [
338
- {
339
- account_id: 'user-2',
340
- name: 'Jane Smith',
341
- email: 'jane@example.com',
342
- title: 'Administrator',
343
- },
344
- ],
345
- };
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DUMMY_FORM_METADATA = exports.FormMetadata = exports.SOURCES = exports.ALIGN_V = exports.ALIGN_H = exports.BLOCK_TYPES = exports.FIELD_TYPES = exports.SCHEMA_VERSION = void 0;
4
+ const zod_1 = require("zod");
5
+ const fields_client_1 = require("./fields.client");
6
+ exports.SCHEMA_VERSION = 1;
7
+ exports.FIELD_TYPES = ['text', 'signature'];
8
+ exports.BLOCK_TYPES = [
9
+ 'header',
10
+ 'paragraph',
11
+ 'form_field',
12
+ 'form_phantom_field',
13
+ 'divider',
14
+ 'image',
15
+ ];
16
+ exports.ALIGN_H = ['left', 'center', 'right'];
17
+ exports.ALIGN_V = ['top', 'middle', 'bottom'];
18
+ exports.SOURCES = ['auto', 'prefill', 'derived', 'manual'];
19
+ class FormMetadata {
20
+ formMetadata;
21
+ blocks;
22
+ constructor(formMetadata) {
23
+ this.formMetadata = formMetadata;
24
+ this.blocks = formMetadata.schema.blocks;
25
+ }
26
+ getAllBlocks() {
27
+ return this.blocks;
28
+ }
29
+ getBlocksByType(blockType) {
30
+ return this.blocks.filter((block) => block.block_type === blockType);
31
+ }
32
+ getBlocksByPartyId(partyId) {
33
+ return this.blocks.filter((block) => block.party_id === partyId);
34
+ }
35
+ getFields() {
36
+ return this.blocks
37
+ .filter((block) => block.block_type === 'form_field')
38
+ .map((block) => block.content);
39
+ }
40
+ getField(index) {
41
+ const fields = this.getFields();
42
+ return fields[index];
43
+ }
44
+ getPhantomFields() {
45
+ return this.blocks
46
+ .filter((block) => block.block_type === 'form_phantom_field')
47
+ .map((block) => block.content);
48
+ }
49
+ encodeAsJSON() {
50
+ return JSON.stringify(this.formMetadata);
51
+ }
52
+ static decodeFromJSON(json) {
53
+ const parsed = JSON.parse(json);
54
+ return new FormMetadata(parsed);
55
+ }
56
+ getLabel() {
57
+ return this.formMetadata.label;
58
+ }
59
+ getFieldForClient(index, sourceDomains, derivationBase) {
60
+ const field = this.getField(index);
61
+ if (!field)
62
+ throw new Error('Field does not exist');
63
+ const finalParams = {
64
+ ...derivationBase,
65
+ ...sourceDomains,
66
+ };
67
+ const validator = this.parseValidator(field.field, finalParams);
68
+ const prefiller = this.parsePrefiller(field.field, finalParams);
69
+ const section = field.field.split('.')[0];
70
+ let options = undefined;
71
+ if (validator?.type === 'enum')
72
+ options = validator.options;
73
+ if (validator?.type === 'array') {
74
+ const element = validator.element;
75
+ if (element?.options)
76
+ options = element.options;
77
+ }
78
+ const type = field.type === 'signature'
79
+ ? 'signature'
80
+ : validator
81
+ ? (0, fields_client_1.getSchemaClientType)(validator)
82
+ : 'text';
83
+ const coerce = (value) => {
84
+ switch (type) {
85
+ case 'number': {
86
+ const n = parseInt(value);
87
+ return isNaN(n) ? 0 : n;
88
+ }
89
+ case 'date': {
90
+ const n = parseInt(value);
91
+ return isNaN(n) ? new Date() : new Date(n);
92
+ }
93
+ case 'checkbox': {
94
+ return !!value?.trim();
95
+ }
96
+ case 'multiselect': {
97
+ return value?.split('\n');
98
+ }
99
+ default:
100
+ return value;
101
+ }
102
+ };
103
+ return {
104
+ field: field.field,
105
+ shared: field.shared,
106
+ label: field.label,
107
+ source: field.source,
108
+ tooltip_label: field.tooltip_label,
109
+ signing_party_id: field.signing_party_id,
110
+ coerce,
111
+ type,
112
+ section,
113
+ validator,
114
+ prefiller,
115
+ options,
116
+ };
117
+ }
118
+ getFieldsForClientService(sourceDomains, derivationBase) {
119
+ const fields = this.getFields();
120
+ return fields
121
+ .map((field, i) => this.getFieldForClient(i, sourceDomains, derivationBase))
122
+ .filter((field) => field !== null);
123
+ }
124
+ getFieldsForSigningService() {
125
+ const fields = this.getFields();
126
+ return fields
127
+ .filter((field) => field.type !== 'image')
128
+ .map((field) => ({
129
+ field: field.field,
130
+ type: field.type,
131
+ x: field.x,
132
+ y: field.y,
133
+ w: field.w,
134
+ h: field.h,
135
+ align_h: (field.align_h ?? 'left'),
136
+ align_v: (field.align_v ?? 'top'),
137
+ page: field.page,
138
+ }))
139
+ .filter((field) => field !== null);
140
+ }
141
+ inferParams() {
142
+ const inferenceRegex = /params\[\s*(['"])(.*?)\1\s*\]/g;
143
+ const params = [];
144
+ let match;
145
+ for (const field of this.getFields()) {
146
+ const validatorStr = typeof field.validator === 'string' ? field.validator : '';
147
+ while ((match = inferenceRegex.exec(validatorStr)) !== null)
148
+ if (!params.includes(match[2]))
149
+ params.push(match[2]);
150
+ }
151
+ for (const field of this.getPhantomFields()) {
152
+ const validatorStr = typeof field.validator === 'string' ? field.validator : '';
153
+ while ((match = inferenceRegex.exec(validatorStr)) !== null)
154
+ if (!params.includes(match[2]))
155
+ params.push(match[2]);
156
+ }
157
+ return params;
158
+ }
159
+ parseValidator(fieldname, params = {}) {
160
+ const field = this.getFields().find((f) => f.field === fieldname);
161
+ if (!field)
162
+ return null;
163
+ const d = new Date();
164
+ const defaults = {
165
+ currentDate: d,
166
+ currentDateTimestamp: d.getTime(),
167
+ };
168
+ const validatorStr = typeof field.validator === 'string' ? field.validator : '';
169
+ const validator = this.populateParams(validatorStr, params);
170
+ const ret = `return ${validator}`;
171
+ const evaluator = new Function('z', 'params', ret);
172
+ return evaluator(zod_1.default, { ...params, ...defaults });
173
+ }
174
+ parsePrefiller(fieldname, _params = {}) {
175
+ const field = this.getFields().find((f) => f.field === fieldname);
176
+ if (!field || !field.default_value)
177
+ return null;
178
+ try {
179
+ const fn = eval(field.default_value);
180
+ return typeof fn === 'function' ? fn : null;
181
+ }
182
+ catch (e) {
183
+ console.error(`Failed to parse prefiller for field ${fieldname}`, e);
184
+ return null;
185
+ }
186
+ }
187
+ enumerateParams(s) {
188
+ const detectedParams = s.match(/#\{[^}]*\}/g) ?? [];
189
+ const params = detectedParams.map((dp) => {
190
+ const [fieldName, propertyTree] = dp
191
+ .replaceAll('#{', '')
192
+ .replaceAll('}', '')
193
+ .replaceAll(')', '')
194
+ .split('(');
195
+ const properties = propertyTree?.split('.') ?? [];
196
+ return [fieldName, ...properties];
197
+ });
198
+ return params?.reduce((acc, cur, i) => ((acc[detectedParams[i]] = cur), acc), {});
199
+ }
200
+ populateParams(s, params) {
201
+ const paramsReflection = this.enumerateParams(s);
202
+ const paramsValues = {};
203
+ for (const match in paramsReflection) {
204
+ const path = paramsReflection[match];
205
+ paramsValues[match] =
206
+ path.reduce((acc, cur) => acc?.[cur], params) ?? '';
207
+ }
208
+ let out = s;
209
+ for (const match in paramsValues) {
210
+ const replacement = JSON.stringify(paramsValues[match]);
211
+ out = out.replaceAll(match, replacement);
212
+ }
213
+ return out;
214
+ }
215
+ getSignatories() {
216
+ return this.formMetadata.subscribers;
217
+ }
218
+ getSubscribers() {
219
+ return this.formMetadata.subscribers;
220
+ }
221
+ getRequiredParties() {
222
+ return this.formMetadata.parties;
223
+ }
224
+ }
225
+ exports.FormMetadata = FormMetadata;
226
+ exports.DUMMY_FORM_METADATA = {
227
+ name: 'test-form',
228
+ label: 'Test Form',
229
+ schema_version: exports.SCHEMA_VERSION,
230
+ schema: {
231
+ blocks: [
232
+ {
233
+ block_type: 'header',
234
+ order: 0,
235
+ content: 'Student Information Form',
236
+ party_id: 'party-1',
237
+ },
238
+ {
239
+ block_type: 'paragraph',
240
+ order: 1,
241
+ content: 'Please fill in your personal details below.',
242
+ party_id: 'party-1',
243
+ },
244
+ {
245
+ block_type: 'form_field',
246
+ order: 2,
247
+ content: {
248
+ field: 'student.full_name',
249
+ type: 'text',
250
+ x: 100,
251
+ y: 100,
252
+ w: 200,
253
+ h: 20,
254
+ page: 1,
255
+ align_h: 'left',
256
+ align_v: 'top',
257
+ label: 'Full Name',
258
+ tooltip_label: 'Enter your full name',
259
+ shared: true,
260
+ source: 'manual',
261
+ default_value: '({ user }) => `${user?.first_name ?? ""} ${user?.last_name ?? ""}`',
262
+ validator: 'z.string().min(1, "Name is required")',
263
+ },
264
+ party_id: 'party-1',
265
+ },
266
+ {
267
+ block_type: 'form_field',
268
+ order: 3,
269
+ content: {
270
+ field: 'student.email',
271
+ type: 'text',
272
+ x: 100,
273
+ y: 130,
274
+ w: 200,
275
+ h: 20,
276
+ page: 1,
277
+ align_h: 'left',
278
+ align_v: 'top',
279
+ label: 'Email',
280
+ tooltip_label: 'Enter your email address',
281
+ shared: true,
282
+ source: 'prefill',
283
+ default_value: '({ user }) => user?.email ?? ""',
284
+ validator: 'z.string().email("Invalid email")',
285
+ },
286
+ party_id: 'party-1',
287
+ },
288
+ {
289
+ block_type: 'form_field',
290
+ order: 4,
291
+ content: {
292
+ field: 'student.signature',
293
+ type: 'signature',
294
+ x: 100,
295
+ y: 160,
296
+ w: 150,
297
+ h: 50,
298
+ page: 1,
299
+ align_h: 'left',
300
+ align_v: 'top',
301
+ label: 'Signature',
302
+ tooltip_label: 'Please sign here',
303
+ shared: true,
304
+ source: 'manual',
305
+ validator: 'z.string().min(1, "Signature is required")',
306
+ },
307
+ party_id: 'party-1',
308
+ },
309
+ {
310
+ block_type: 'form_phantom_field',
311
+ order: 5,
312
+ content: {
313
+ field: 'student.phone',
314
+ type: 'text',
315
+ label: 'Phone Number',
316
+ tooltip_label: 'Optional contact number',
317
+ shared: true,
318
+ source: 'manual',
319
+ validator: 'z.string().optional()',
320
+ },
321
+ party_id: 'party-1',
322
+ },
323
+ ],
324
+ },
325
+ parties: [
326
+ {
327
+ _id: 'party-1',
328
+ order: 1,
329
+ signatory_account: {
330
+ account_id: 'user-1',
331
+ name: 'John Doe',
332
+ email: 'john@example.com',
333
+ title: 'Student',
334
+ },
335
+ signed: false,
336
+ },
337
+ ],
338
+ subscribers: [
339
+ {
340
+ account_id: 'user-2',
341
+ name: 'Jane Smith',
342
+ email: 'jane@example.com',
343
+ title: 'Administrator',
344
+ },
345
+ ],
346
+ };
346
347
  //# sourceMappingURL=form-metadata.js.map