hvp-shared 3.4.0 → 3.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 (36) hide show
  1. package/dist/constants/catalog-item.constants.d.ts +63 -0
  2. package/dist/constants/catalog-item.constants.js +80 -0
  3. package/dist/constants/index.d.ts +4 -0
  4. package/dist/constants/index.js +4 -0
  5. package/dist/{inventory → constants}/qvet-catalog.d.ts +8 -58
  6. package/dist/{inventory → constants}/qvet-catalog.js +10 -133
  7. package/dist/constants/qvet-inventory.d.ts +28 -0
  8. package/dist/constants/qvet-inventory.js +56 -0
  9. package/dist/constants/qvet-warehouses.d.ts +6 -0
  10. package/dist/constants/qvet-warehouses.js +9 -0
  11. package/dist/contracts/catalog-item/index.d.ts +2 -0
  12. package/dist/{inventory → contracts/catalog-item}/index.js +2 -1
  13. package/dist/contracts/catalog-item/requests.d.ts +113 -0
  14. package/dist/contracts/catalog-item/requests.js +7 -0
  15. package/dist/contracts/catalog-item/responses.d.ts +132 -0
  16. package/dist/contracts/catalog-item/responses.js +7 -0
  17. package/dist/contracts/index.d.ts +1 -0
  18. package/dist/contracts/index.js +1 -0
  19. package/dist/index.d.ts +2 -1
  20. package/dist/index.js +2 -1
  21. package/dist/types/catalog-item.types.d.ts +104 -0
  22. package/dist/types/catalog-item.types.js +7 -0
  23. package/dist/types/index.d.ts +3 -0
  24. package/dist/types/index.js +3 -0
  25. package/dist/types/qvet.types.d.ts +21 -0
  26. package/dist/types/qvet.types.js +9 -0
  27. package/dist/types/sync-field.types.d.ts +23 -0
  28. package/dist/types/sync-field.types.js +9 -0
  29. package/dist/utils/qvet-catalog.helpers.d.ts +37 -0
  30. package/dist/utils/qvet-catalog.helpers.js +104 -0
  31. package/dist/utils/sync-field.helpers.d.ts +84 -0
  32. package/dist/utils/sync-field.helpers.js +117 -0
  33. package/dist/utils/sync-field.helpers.test.d.ts +1 -0
  34. package/dist/utils/sync-field.helpers.test.js +149 -0
  35. package/package.json +1 -1
  36. package/dist/inventory/index.d.ts +0 -1
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getValue = getValue;
4
+ exports.getQvetValue = getQvetValue;
5
+ exports.hasPending = hasPending;
6
+ exports.isDirty = isDirty;
7
+ exports.setPending = setPending;
8
+ exports.clearPending = clearPending;
9
+ exports.confirmSync = confirmSync;
10
+ exports.applySyncPreservePending = applySyncPreservePending;
11
+ /**
12
+ * Get the effective value (pending if exists, otherwise current)
13
+ *
14
+ * @example
15
+ * getValue({ value: "old", pending: "new" }) // "new"
16
+ * getValue({ value: "old", pending: undefined }) // "old"
17
+ */
18
+ function getValue(field) {
19
+ return field.pending ?? field.value;
20
+ }
21
+ /**
22
+ * Get the external system value (always the synced one, ignores pending)
23
+ *
24
+ * @example
25
+ * getQvetValue({ value: "old", pending: "new" }) // "old"
26
+ */
27
+ function getQvetValue(field) {
28
+ return field.value;
29
+ }
30
+ /**
31
+ * Check if field has a pending change
32
+ *
33
+ * @example
34
+ * hasPending({ value: "old", pending: "new" }) // true
35
+ * hasPending({ value: "old", pending: undefined }) // false
36
+ */
37
+ function hasPending(field) {
38
+ return field.pending !== undefined && field.pending !== null;
39
+ }
40
+ /**
41
+ * Check if pending value differs from current value
42
+ *
43
+ * @example
44
+ * isDirty({ value: "old", pending: "new" }) // true
45
+ * isDirty({ value: "old", pending: "old" }) // false (same value)
46
+ * isDirty({ value: "old", pending: undefined }) // false
47
+ */
48
+ function isDirty(field) {
49
+ return hasPending(field) && field.pending !== field.value;
50
+ }
51
+ /**
52
+ * Set a pending value. If newValue equals current value, clears pending instead.
53
+ *
54
+ * @example
55
+ * setPending({ value: "old", pending: undefined }, "new")
56
+ * // { value: "old", pending: "new" }
57
+ *
58
+ * setPending({ value: "old", pending: undefined }, "old")
59
+ * // { value: "old", pending: undefined } - no change needed
60
+ */
61
+ function setPending(field, newValue) {
62
+ if (newValue === field.value) {
63
+ return { value: field.value, pending: undefined };
64
+ }
65
+ return { value: field.value, pending: newValue };
66
+ }
67
+ /**
68
+ * Clear pending (revert to external system value)
69
+ *
70
+ * @example
71
+ * clearPending({ value: "old", pending: "new" })
72
+ * // { value: "old", pending: undefined }
73
+ */
74
+ function clearPending(field) {
75
+ return { value: field.value, pending: undefined };
76
+ }
77
+ /**
78
+ * Confirm sync from external system.
79
+ * Updates the value to the new external value and clears pending.
80
+ *
81
+ * @example
82
+ * // External system confirmed our change
83
+ * confirmSync({ value: "old", pending: "new" }, "new")
84
+ * // { value: "new", pending: undefined }
85
+ *
86
+ * // External system has different value
87
+ * confirmSync({ value: "old", pending: undefined }, "updated")
88
+ * // { value: "updated", pending: undefined }
89
+ */
90
+ function confirmSync(field, externalValue) {
91
+ return { value: externalValue, pending: undefined };
92
+ }
93
+ /**
94
+ * Apply sync from external system, preserving pending if it differs from new value.
95
+ * Use this when you want to keep local changes during a sync.
96
+ *
97
+ * @example
98
+ * // We have pending, external hasn't changed yet
99
+ * applySyncPreservePending({ value: "old", pending: "new" }, "old")
100
+ * // { value: "old", pending: "new" } - pending preserved
101
+ *
102
+ * // External confirmed our change
103
+ * applySyncPreservePending({ value: "old", pending: "new" }, "new")
104
+ * // { value: "new", pending: undefined } - pending cleared
105
+ *
106
+ * // External changed to something else (conflict scenario)
107
+ * applySyncPreservePending({ value: "old", pending: "new" }, "other")
108
+ * // { value: "other", pending: "new" } - pending preserved, value updated
109
+ */
110
+ function applySyncPreservePending(field, externalValue) {
111
+ // If pending equals new external value, the change was confirmed
112
+ if (field.pending === externalValue) {
113
+ return { value: externalValue, pending: undefined };
114
+ }
115
+ // Otherwise, update value but preserve pending
116
+ return { value: externalValue, pending: field.pending };
117
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const sync_field_types_1 = require("../types/sync-field.types");
4
+ const sync_field_helpers_1 = require("./sync-field.helpers");
5
+ describe('SyncField Helpers', () => {
6
+ describe('createSyncField', () => {
7
+ it('should create a clean sync field', () => {
8
+ const field = (0, sync_field_types_1.createSyncField)('hello');
9
+ expect(field).toEqual({ value: 'hello', pending: undefined });
10
+ });
11
+ it('should work with numbers', () => {
12
+ const field = (0, sync_field_types_1.createSyncField)(42);
13
+ expect(field).toEqual({ value: 42, pending: undefined });
14
+ });
15
+ });
16
+ describe('getValue', () => {
17
+ it('should return value when no pending', () => {
18
+ const field = { value: 'original', pending: undefined };
19
+ expect((0, sync_field_helpers_1.getValue)(field)).toBe('original');
20
+ });
21
+ it('should return pending when present', () => {
22
+ const field = { value: 'original', pending: 'modified' };
23
+ expect((0, sync_field_helpers_1.getValue)(field)).toBe('modified');
24
+ });
25
+ it('should work with numbers', () => {
26
+ const field = { value: 10, pending: 20 };
27
+ expect((0, sync_field_helpers_1.getValue)(field)).toBe(20);
28
+ });
29
+ });
30
+ describe('getQvetValue', () => {
31
+ it('should return value regardless of pending', () => {
32
+ const field = { value: 'original', pending: 'modified' };
33
+ expect((0, sync_field_helpers_1.getQvetValue)(field)).toBe('original');
34
+ });
35
+ it('should return value when no pending', () => {
36
+ const field = { value: 'original', pending: undefined };
37
+ expect((0, sync_field_helpers_1.getQvetValue)(field)).toBe('original');
38
+ });
39
+ });
40
+ describe('hasPending', () => {
41
+ it('should return false when pending is undefined', () => {
42
+ const field = { value: 'original', pending: undefined };
43
+ expect((0, sync_field_helpers_1.hasPending)(field)).toBe(false);
44
+ });
45
+ it('should return true when pending has value', () => {
46
+ const field = { value: 'original', pending: 'modified' };
47
+ expect((0, sync_field_helpers_1.hasPending)(field)).toBe(true);
48
+ });
49
+ it('should return false when pending is null', () => {
50
+ const field = { value: 'original', pending: null };
51
+ expect((0, sync_field_helpers_1.hasPending)(field)).toBe(false);
52
+ });
53
+ it('should return true for falsy pending values like 0', () => {
54
+ const field = { value: 10, pending: 0 };
55
+ expect((0, sync_field_helpers_1.hasPending)(field)).toBe(true);
56
+ });
57
+ it('should return true for empty string pending', () => {
58
+ const field = { value: 'original', pending: '' };
59
+ expect((0, sync_field_helpers_1.hasPending)(field)).toBe(true);
60
+ });
61
+ });
62
+ describe('isDirty', () => {
63
+ it('should return false when no pending', () => {
64
+ const field = { value: 'original', pending: undefined };
65
+ expect((0, sync_field_helpers_1.isDirty)(field)).toBe(false);
66
+ });
67
+ it('should return true when pending differs from value', () => {
68
+ const field = { value: 'original', pending: 'modified' };
69
+ expect((0, sync_field_helpers_1.isDirty)(field)).toBe(true);
70
+ });
71
+ it('should return false when pending equals value', () => {
72
+ const field = { value: 'same', pending: 'same' };
73
+ expect((0, sync_field_helpers_1.isDirty)(field)).toBe(false);
74
+ });
75
+ });
76
+ describe('setPending', () => {
77
+ it('should set pending when value differs', () => {
78
+ const field = { value: 'original', pending: undefined };
79
+ const result = (0, sync_field_helpers_1.setPending)(field, 'modified');
80
+ expect(result).toEqual({ value: 'original', pending: 'modified' });
81
+ });
82
+ it('should clear pending when new value equals current value', () => {
83
+ const field = { value: 'original', pending: 'modified' };
84
+ const result = (0, sync_field_helpers_1.setPending)(field, 'original');
85
+ expect(result).toEqual({ value: 'original', pending: undefined });
86
+ });
87
+ it('should replace existing pending', () => {
88
+ const field = { value: 'original', pending: 'first' };
89
+ const result = (0, sync_field_helpers_1.setPending)(field, 'second');
90
+ expect(result).toEqual({ value: 'original', pending: 'second' });
91
+ });
92
+ it('should work with numbers', () => {
93
+ const field = { value: 10, pending: undefined };
94
+ const result = (0, sync_field_helpers_1.setPending)(field, 20);
95
+ expect(result).toEqual({ value: 10, pending: 20 });
96
+ });
97
+ });
98
+ describe('clearPending', () => {
99
+ it('should remove pending', () => {
100
+ const field = { value: 'original', pending: 'modified' };
101
+ const result = (0, sync_field_helpers_1.clearPending)(field);
102
+ expect(result).toEqual({ value: 'original', pending: undefined });
103
+ });
104
+ it('should work when already clean', () => {
105
+ const field = { value: 'original', pending: undefined };
106
+ const result = (0, sync_field_helpers_1.clearPending)(field);
107
+ expect(result).toEqual({ value: 'original', pending: undefined });
108
+ });
109
+ });
110
+ describe('confirmSync', () => {
111
+ it('should update value and clear pending', () => {
112
+ const field = { value: 'old', pending: 'new' };
113
+ const result = (0, sync_field_helpers_1.confirmSync)(field, 'new');
114
+ expect(result).toEqual({ value: 'new', pending: undefined });
115
+ });
116
+ it('should update to external value even if different from pending', () => {
117
+ const field = { value: 'old', pending: 'expected' };
118
+ const result = (0, sync_field_helpers_1.confirmSync)(field, 'external');
119
+ expect(result).toEqual({ value: 'external', pending: undefined });
120
+ });
121
+ it('should work when no pending', () => {
122
+ const field = { value: 'old', pending: undefined };
123
+ const result = (0, sync_field_helpers_1.confirmSync)(field, 'updated');
124
+ expect(result).toEqual({ value: 'updated', pending: undefined });
125
+ });
126
+ });
127
+ describe('applySyncPreservePending', () => {
128
+ it('should preserve pending when external unchanged', () => {
129
+ const field = { value: 'old', pending: 'new' };
130
+ const result = (0, sync_field_helpers_1.applySyncPreservePending)(field, 'old');
131
+ expect(result).toEqual({ value: 'old', pending: 'new' });
132
+ });
133
+ it('should clear pending when external confirms our change', () => {
134
+ const field = { value: 'old', pending: 'new' };
135
+ const result = (0, sync_field_helpers_1.applySyncPreservePending)(field, 'new');
136
+ expect(result).toEqual({ value: 'new', pending: undefined });
137
+ });
138
+ it('should preserve pending and update value on conflict', () => {
139
+ const field = { value: 'old', pending: 'our-change' };
140
+ const result = (0, sync_field_helpers_1.applySyncPreservePending)(field, 'external-change');
141
+ expect(result).toEqual({ value: 'external-change', pending: 'our-change' });
142
+ });
143
+ it('should update value when no pending', () => {
144
+ const field = { value: 'old', pending: undefined };
145
+ const result = (0, sync_field_helpers_1.applySyncPreservePending)(field, 'updated');
146
+ expect(result).toEqual({ value: 'updated', pending: undefined });
147
+ });
148
+ });
149
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hvp-shared",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "description": "Shared types and utilities for HVP backend and frontend",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1 +0,0 @@
1
- export * from './qvet-catalog';