@servicetitan/dte-pdf-editor 1.45.0 → 1.47.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.
- package/README.md +15 -0
- package/dist/components/field-config-panel/field-config-panel.d.ts.map +1 -1
- package/dist/components/field-config-panel/field-config-panel.js +4 -2
- package/dist/components/field-config-panel/field-config-panel.js.map +1 -1
- package/dist/components/pdf-fields-overlay/pdf-fields-overlay.d.ts.map +1 -1
- package/dist/components/pdf-fields-overlay/pdf-fields-overlay.js +11 -1
- package/dist/components/pdf-fields-overlay/pdf-fields-overlay.js.map +1 -1
- package/dist/components/pdf-fields-overlay/pdf-overlay-field-calculated.d.ts +1 -0
- package/dist/components/pdf-fields-overlay/pdf-overlay-field-calculated.d.ts.map +1 -1
- package/dist/components/pdf-fields-overlay/pdf-overlay-field-calculated.js +14 -2
- package/dist/components/pdf-fields-overlay/pdf-overlay-field-calculated.js.map +1 -1
- package/dist/components/pdf-fields-overlay/pdf-overlay-field-fillable.d.ts.map +1 -1
- package/dist/components/pdf-fields-overlay/pdf-overlay-field-fillable.js +3 -0
- package/dist/components/pdf-fields-overlay/pdf-overlay-field-fillable.js.map +1 -1
- package/dist/components/pdf-fields-overlay/pdf-overlay-field.d.ts +1 -0
- package/dist/components/pdf-fields-overlay/pdf-overlay-field.d.ts.map +1 -1
- package/dist/components/pdf-fields-overlay/pdf-overlay-field.js +2 -2
- package/dist/components/pdf-fields-overlay/pdf-overlay-field.js.map +1 -1
- package/dist/components/pdf-view/pdf-view-calculated.d.ts +2 -1
- package/dist/components/pdf-view/pdf-view-calculated.d.ts.map +1 -1
- package/dist/components/pdf-view/pdf-view-calculated.js +5 -2
- package/dist/components/pdf-view/pdf-view-calculated.js.map +1 -1
- package/dist/components/pdf-view/pdf-view-fillable.d.ts +10 -2
- package/dist/components/pdf-view/pdf-view-fillable.d.ts.map +1 -1
- package/dist/components/pdf-view/pdf-view-fillable.js +16 -12
- package/dist/components/pdf-view/pdf-view-fillable.js.map +1 -1
- package/dist/components/pdf-view/pdf-view.d.ts +2 -2
- package/dist/components/pdf-view/pdf-view.d.ts.map +1 -1
- package/dist/components/pdf-view/pdf-view.js +4 -4
- package/dist/components/pdf-view/pdf-view.js.map +1 -1
- package/dist/interface/types.d.ts +2 -1
- package/dist/interface/types.d.ts.map +1 -1
- package/dist/interface/types.js.map +1 -1
- package/dist/utils/formula/expression.utils.d.ts +13 -0
- package/dist/utils/formula/expression.utils.d.ts.map +1 -1
- package/dist/utils/formula/expression.utils.js +42 -0
- package/dist/utils/formula/expression.utils.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/field-types/date-fields.test.ts +212 -0
- package/src/__tests__/field-types/display-condition-fields.test.ts +340 -0
- package/src/__tests__/field-types/e-sign-fields.test.ts +97 -0
- package/src/__tests__/field-types/fillable-fields.test.ts +180 -0
- package/src/__tests__/field-types/form-fields.test.ts +193 -0
- package/src/__tests__/field-types/formula-fields.test.ts +245 -0
- package/src/__tests__/field-types/merge-tag-fields.test.ts +208 -0
- package/src/components/field-config-panel/field-config-panel.tsx +11 -0
- package/src/components/pdf-fields-overlay/pdf-fields-overlay.tsx +12 -1
- package/src/components/pdf-fields-overlay/pdf-overlay-field-calculated.tsx +20 -4
- package/src/components/pdf-fields-overlay/pdf-overlay-field-fillable.tsx +10 -0
- package/src/components/pdf-fields-overlay/pdf-overlay-field.tsx +5 -1
- package/src/components/pdf-view/pdf-view-calculated.tsx +13 -3
- package/src/components/pdf-view/pdf-view-fillable.tsx +62 -21
- package/src/components/pdf-view/pdf-view.tsx +11 -10
- package/src/interface/types.ts +12 -10
- package/src/styles/generic.css +6 -0
- package/src/styles/inline-editable.css +1 -0
- package/src/utils/conditions/__tests__/evaluate.utils.test.ts +163 -0
- package/src/utils/conditions/__tests__/schema-data-points.utils.test.ts +149 -0
- package/src/utils/data-model/__tests__/extract-fields.utils.test.ts +154 -0
- package/src/utils/data-model/__tests__/resolve-values.utils.test.ts +60 -0
- package/src/utils/field/__tests__/field-background-color.utils.test.ts +26 -0
- package/src/utils/field/__tests__/field-placeholder-text.utils.test.ts +46 -0
- package/src/utils/formula/__tests__/dom.utils.test.ts +33 -0
- package/src/utils/formula/__tests__/evaluate-formula.utils.test.ts +202 -0
- package/src/utils/formula/__tests__/expression.utils.test.ts +119 -0
- package/src/utils/formula/__tests__/form-fields.utils.test.ts +274 -0
- package/src/utils/formula/__tests__/format-calculated-result.utils.test.ts +105 -0
- package/src/utils/formula/__tests__/render-formula.utils.test.ts +43 -0
- package/src/utils/formula/__tests__/validate-formula.utils.test.ts +168 -0
- package/src/utils/formula/expression.utils.ts +44 -0
- package/src/utils/path/__tests__/generate-e-sign-path.test.ts +26 -0
- package/src/utils/path/__tests__/generate-fillable-path.test.ts +17 -0
- package/src/utils/path/__tests__/parse-fillable-path.test.ts +25 -0
- package/src/utils/recipients/__tests__/map-colors.test.ts +40 -0
- package/src/utils/shared/__tests__/date.utils.test.ts +58 -0
- package/src/utils/shared/__tests__/number.utils.test.ts +48 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { parseFillablePathName } from '../parse-fillable-path';
|
|
2
|
+
|
|
3
|
+
describe('parseFillablePathName', () => {
|
|
4
|
+
const subject = (path: string | undefined) => parseFillablePathName(path);
|
|
5
|
+
|
|
6
|
+
test.each([
|
|
7
|
+
['fillable_signer1_fieldName', 'fieldName'],
|
|
8
|
+
['fillable_signer1_', ''],
|
|
9
|
+
['fillable_signer1_some_uuid_with_underscores', 'some'],
|
|
10
|
+
])('parses "%s" to "%s"', (path, expected) => {
|
|
11
|
+
expect(subject(path)).toBe(expected);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('returns empty string for undefined path', () => {
|
|
15
|
+
expect(subject(undefined)).toBe('');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('returns empty string for empty path', () => {
|
|
19
|
+
expect(subject('')).toBe('');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('returns empty string when path has fewer than 3 parts', () => {
|
|
23
|
+
expect(subject('fillable_signer1')).toBe('');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { RecipientInfo } from '../../../interface/types';
|
|
2
|
+
import { mapColorsToRecipients } from '../map-colors';
|
|
3
|
+
|
|
4
|
+
const buildRecipient = (id: number, name: string): RecipientInfo => ({
|
|
5
|
+
id,
|
|
6
|
+
name,
|
|
7
|
+
displayName: name,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
describe('mapColorsToRecipients', () => {
|
|
11
|
+
const subject = (recipients?: RecipientInfo[]) => mapColorsToRecipients(recipients);
|
|
12
|
+
|
|
13
|
+
test('returns empty object when recipients is undefined', () => {
|
|
14
|
+
expect(subject(undefined)).toEqual({});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('returns empty object when recipients is empty', () => {
|
|
18
|
+
expect(subject([])).toEqual({});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('maps each recipient name to a distinct color', () => {
|
|
22
|
+
const recipients = [
|
|
23
|
+
buildRecipient(1, 'recipient_a'),
|
|
24
|
+
buildRecipient(2, 'recipient_b'),
|
|
25
|
+
buildRecipient(3, 'recipient_c'),
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const result = subject(recipients);
|
|
29
|
+
|
|
30
|
+
expect(Object.keys(result)).toEqual(['recipient_a', 'recipient_b', 'recipient_c']);
|
|
31
|
+
expect(new Set(Object.values(result)).size).toBe(3);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('uses last recipient color when names collide', () => {
|
|
35
|
+
const result = subject([buildRecipient(1, 'duplicate'), buildRecipient(2, 'duplicate')]);
|
|
36
|
+
|
|
37
|
+
expect(Object.keys(result)).toEqual(['duplicate']);
|
|
38
|
+
expect(result.duplicate).toBeDefined();
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { dateToUtcZero, toDateInputValue } from '../date.utils';
|
|
2
|
+
|
|
3
|
+
describe('dateToUtcZero', () => {
|
|
4
|
+
const subject = (dateString: string) => dateToUtcZero(dateString);
|
|
5
|
+
|
|
6
|
+
test('converts YYYY-MM-DD string to UTC midnight ISO string', () => {
|
|
7
|
+
expect(subject('2024-01-15')).toBe('2024-01-15T00:00:00.000Z');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('handles single-digit month and day', () => {
|
|
11
|
+
expect(subject('2024-03-05')).toBe('2024-03-05T00:00:00.000Z');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('handles end of year dates', () => {
|
|
15
|
+
expect(subject('2024-12-31')).toBe('2024-12-31T00:00:00.000Z');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('handles leap year dates', () => {
|
|
19
|
+
expect(subject('2024-02-29')).toBe('2024-02-29T00:00:00.000Z');
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('toDateInputValue', () => {
|
|
24
|
+
const subject = (value: unknown) => toDateInputValue(value);
|
|
25
|
+
|
|
26
|
+
test.each([
|
|
27
|
+
['null', null],
|
|
28
|
+
['undefined', undefined],
|
|
29
|
+
['empty string', ''],
|
|
30
|
+
])('returns empty string for %s', (_, value) => {
|
|
31
|
+
expect(subject(value)).toBe('');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('returns ISO date portion for valid Date object', () => {
|
|
35
|
+
const date = new Date(Date.UTC(2024, 0, 15, 12, 0, 0));
|
|
36
|
+
expect(subject(date)).toBe('2024-01-15');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('returns empty string for invalid Date object', () => {
|
|
40
|
+
expect(subject(new Date('not-a-date'))).toBe('');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('returns first 10 characters of an ISO date string', () => {
|
|
44
|
+
expect(subject('2024-01-15T12:30:00.000Z')).toBe('2024-01-15');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('returns first 10 characters of a YYYY-MM-DD string as-is', () => {
|
|
48
|
+
expect(subject('2024-01-15')).toBe('2024-01-15');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test.each([
|
|
52
|
+
['number', 12345],
|
|
53
|
+
['boolean', true],
|
|
54
|
+
['object', { foo: 'bar' }],
|
|
55
|
+
])('returns empty string for unsupported %s value', (_, value) => {
|
|
56
|
+
expect(subject(value)).toBe('');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { isValidNumber } from '../number.utils';
|
|
2
|
+
|
|
3
|
+
describe('isValidNumber', () => {
|
|
4
|
+
const subject = (value: string | number) => isValidNumber(value);
|
|
5
|
+
|
|
6
|
+
describe('with numeric input', () => {
|
|
7
|
+
test.each([
|
|
8
|
+
[0, true],
|
|
9
|
+
[1, true],
|
|
10
|
+
[-1, true],
|
|
11
|
+
[3.14, true],
|
|
12
|
+
[Number.MAX_SAFE_INTEGER, true],
|
|
13
|
+
])('returns true for finite number %p', (value, expected) => {
|
|
14
|
+
expect(subject(value)).toBe(expected);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test.each([
|
|
18
|
+
[NaN, false],
|
|
19
|
+
[Infinity, false],
|
|
20
|
+
[-Infinity, false],
|
|
21
|
+
])('returns false for non-finite number %p', (value, expected) => {
|
|
22
|
+
expect(subject(value)).toBe(expected);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('with string input', () => {
|
|
27
|
+
test.each([
|
|
28
|
+
['0', true],
|
|
29
|
+
['1', true],
|
|
30
|
+
['-1', true],
|
|
31
|
+
['3.14', true],
|
|
32
|
+
[' 42 ', true],
|
|
33
|
+
['1e3', true],
|
|
34
|
+
])('returns true for parseable string %p', (value, expected) => {
|
|
35
|
+
expect(subject(value)).toBe(expected);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test.each([
|
|
39
|
+
['', false],
|
|
40
|
+
[' ', false],
|
|
41
|
+
['abc', false],
|
|
42
|
+
['1.2.3', false],
|
|
43
|
+
['NaN', false],
|
|
44
|
+
])('returns false for non-numeric string %p', (value, expected) => {
|
|
45
|
+
expect(subject(value)).toBe(expected);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
});
|