@contractspec/example.integration-hub 2.5.0 → 2.6.1

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 (48) hide show
  1. package/README.md +40 -0
  2. package/dist/docs/index.js +2 -0
  3. package/dist/docs/integration-hub.docblock.js +2 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +149 -0
  6. package/dist/mcp-example.d.ts +16 -0
  7. package/dist/mcp-example.js +151 -0
  8. package/dist/node/docs/index.js +2 -0
  9. package/dist/node/docs/integration-hub.docblock.js +2 -0
  10. package/dist/node/index.js +149 -0
  11. package/dist/node/mcp-example.js +150 -0
  12. package/dist/node/run-mcp.js +155 -0
  13. package/dist/run-mcp.d.ts +1 -0
  14. package/dist/run-mcp.js +156 -0
  15. package/package.json +34 -94
  16. package/dist/browser/connection/connection.enum.js +0 -12
  17. package/dist/browser/connection/connection.operation.js +0 -101
  18. package/dist/browser/connection/connection.presentation.js +0 -102
  19. package/dist/browser/connection/connection.schema.js +0 -48
  20. package/dist/browser/connection/index.js +0 -104
  21. package/dist/browser/docs/index.js +0 -104
  22. package/dist/browser/docs/integration-hub.docblock.js +0 -104
  23. package/dist/browser/events.js +0 -211
  24. package/dist/browser/example.js +0 -42
  25. package/dist/browser/handlers/index.js +0 -246
  26. package/dist/browser/handlers/integration.handlers.js +0 -246
  27. package/dist/browser/index.js +0 -1595
  28. package/dist/browser/integration/index.js +0 -92
  29. package/dist/browser/integration/integration.enum.js +0 -12
  30. package/dist/browser/integration/integration.operations.js +0 -89
  31. package/dist/browser/integration/integration.presentation.js +0 -120
  32. package/dist/browser/integration/integration.schema.js +0 -42
  33. package/dist/browser/integration-hub.capability.js +0 -43
  34. package/dist/browser/integration-hub.feature.js +0 -114
  35. package/dist/browser/seeders/index.js +0 -60
  36. package/dist/browser/sync/index.js +0 -332
  37. package/dist/browser/sync/sync.enum.js +0 -26
  38. package/dist/browser/sync/sync.operations.js +0 -321
  39. package/dist/browser/sync/sync.presentation.js +0 -301
  40. package/dist/browser/sync/sync.schema.js +0 -154
  41. package/dist/browser/sync-engine/index.js +0 -186
  42. package/dist/browser/tests/operations.test-spec.js +0 -85
  43. package/dist/browser/ui/IntegrationDashboard.js +0 -369
  44. package/dist/browser/ui/hooks/index.js +0 -57
  45. package/dist/browser/ui/hooks/useIntegrationData.js +0 -54
  46. package/dist/browser/ui/index.js +0 -644
  47. package/dist/browser/ui/renderers/index.js +0 -273
  48. package/dist/browser/ui/renderers/integration.markdown.js +0 -273
@@ -1,301 +0,0 @@
1
- // src/sync/sync.enum.ts
2
- import { defineEnum } from "@contractspec/lib.schema";
3
- var SyncDirectionEnum = defineEnum("SyncDirection", [
4
- "INBOUND",
5
- "OUTBOUND",
6
- "BIDIRECTIONAL"
7
- ]);
8
- var SyncStatusEnum = defineEnum("SyncStatus", [
9
- "PENDING",
10
- "RUNNING",
11
- "COMPLETED",
12
- "FAILED",
13
- "CANCELLED"
14
- ]);
15
- var MappingTypeEnum = defineEnum("MappingType", [
16
- "DIRECT",
17
- "TRANSFORM",
18
- "LOOKUP",
19
- "CONSTANT",
20
- "COMPUTED"
21
- ]);
22
-
23
- // src/sync/sync.schema.ts
24
- import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
25
- var FieldMappingModel = defineSchemaModel({
26
- name: "FieldMappingModel",
27
- fields: {
28
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
29
- sourceField: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
30
- targetField: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
31
- mappingType: { type: MappingTypeEnum, isOptional: false },
32
- transformExpression: {
33
- type: ScalarTypeEnum.String_unsecure(),
34
- isOptional: true
35
- },
36
- isRequired: { type: ScalarTypeEnum.Boolean(), isOptional: false }
37
- }
38
- });
39
- var SyncConfigModel = defineSchemaModel({
40
- name: "SyncConfigModel",
41
- fields: {
42
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
43
- integrationId: {
44
- type: ScalarTypeEnum.String_unsecure(),
45
- isOptional: false
46
- },
47
- connectionId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
48
- name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
49
- direction: { type: SyncDirectionEnum, isOptional: false },
50
- sourceObject: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
51
- targetObject: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
52
- scheduleEnabled: { type: ScalarTypeEnum.Boolean(), isOptional: false },
53
- scheduleCron: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
54
- isActive: { type: ScalarTypeEnum.Boolean(), isOptional: false },
55
- lastSyncAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },
56
- fieldMappings: { type: FieldMappingModel, isArray: true, isOptional: true }
57
- }
58
- });
59
- var SyncRunModel = defineSchemaModel({
60
- name: "SyncRunModel",
61
- fields: {
62
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
63
- syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
64
- status: { type: SyncStatusEnum, isOptional: false },
65
- direction: { type: SyncDirectionEnum, isOptional: false },
66
- trigger: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
67
- recordsProcessed: {
68
- type: ScalarTypeEnum.Int_unsecure(),
69
- isOptional: false
70
- },
71
- recordsCreated: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
72
- recordsUpdated: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
73
- recordsFailed: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
74
- errorMessage: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
75
- startedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },
76
- completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },
77
- createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
78
- }
79
- });
80
- var CreateSyncConfigInputModel = defineSchemaModel({
81
- name: "CreateSyncConfigInput",
82
- fields: {
83
- integrationId: {
84
- type: ScalarTypeEnum.String_unsecure(),
85
- isOptional: false
86
- },
87
- connectionId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
88
- name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
89
- direction: { type: SyncDirectionEnum, isOptional: false },
90
- sourceObject: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
91
- targetObject: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
92
- scheduleEnabled: { type: ScalarTypeEnum.Boolean(), isOptional: true },
93
- scheduleCron: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
94
- }
95
- });
96
- var AddFieldMappingInputModel = defineSchemaModel({
97
- name: "AddFieldMappingInput",
98
- fields: {
99
- syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
100
- sourceField: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
101
- targetField: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
102
- mappingType: { type: MappingTypeEnum, isOptional: false },
103
- transformExpression: {
104
- type: ScalarTypeEnum.String_unsecure(),
105
- isOptional: true
106
- },
107
- lookupConfig: { type: ScalarTypeEnum.JSON(), isOptional: true },
108
- constantValue: { type: ScalarTypeEnum.JSON(), isOptional: true },
109
- isRequired: { type: ScalarTypeEnum.Boolean(), isOptional: true },
110
- defaultValue: { type: ScalarTypeEnum.JSON(), isOptional: true }
111
- }
112
- });
113
- var TriggerSyncInputModel = defineSchemaModel({
114
- name: "TriggerSyncInput",
115
- fields: {
116
- syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
117
- direction: { type: SyncDirectionEnum, isOptional: true },
118
- fullSync: { type: ScalarTypeEnum.Boolean(), isOptional: true }
119
- }
120
- });
121
- var ListSyncRunsInputModel = defineSchemaModel({
122
- name: "ListSyncRunsInput",
123
- fields: {
124
- syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
125
- status: { type: SyncStatusEnum, isOptional: true },
126
- limit: {
127
- type: ScalarTypeEnum.Int_unsecure(),
128
- isOptional: true,
129
- defaultValue: 20
130
- },
131
- offset: {
132
- type: ScalarTypeEnum.Int_unsecure(),
133
- isOptional: true,
134
- defaultValue: 0
135
- }
136
- }
137
- });
138
- var ListSyncRunsOutputModel = defineSchemaModel({
139
- name: "ListSyncRunsOutput",
140
- fields: {
141
- runs: { type: SyncRunModel, isArray: true, isOptional: false },
142
- total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false }
143
- }
144
- });
145
-
146
- // src/sync/sync.presentation.ts
147
- import {
148
- definePresentation,
149
- StabilityEnum
150
- } from "@contractspec/lib.contracts-spec";
151
- var SyncConfigListPresentation = definePresentation({
152
- meta: {
153
- key: "integration.syncConfig.list",
154
- version: "1.0.0",
155
- title: "Sync Config List",
156
- description: "List of sync configurations",
157
- domain: "integration",
158
- owners: ["@integration-team"],
159
- tags: ["integration", "sync", "config", "list"],
160
- stability: StabilityEnum.Experimental,
161
- goal: "Show users their current sync configurations.",
162
- context: "Management view for data synchronization."
163
- },
164
- source: {
165
- type: "component",
166
- framework: "react",
167
- componentKey: "SyncConfigList",
168
- props: SyncConfigModel
169
- },
170
- targets: ["react", "markdown"],
171
- policy: {
172
- flags: ["integration.sync.enabled"]
173
- }
174
- });
175
- var SyncConfigEditorPresentation = definePresentation({
176
- meta: {
177
- key: "integration.syncConfig.editor",
178
- version: "1.0.0",
179
- title: "Sync Config Editor",
180
- description: "Editor for sync configuration settings",
181
- domain: "integration",
182
- owners: ["@integration-team"],
183
- tags: ["integration", "sync", "config", "editor"],
184
- stability: StabilityEnum.Experimental,
185
- goal: "Allow users to configure schedule, filters, and settings for a sync.",
186
- context: "Configuration interface for sync jobs."
187
- },
188
- source: {
189
- type: "component",
190
- framework: "react",
191
- componentKey: "SyncConfigEditor",
192
- props: SyncConfigModel
193
- },
194
- targets: ["react"],
195
- policy: {
196
- flags: ["integration.sync.enabled"]
197
- }
198
- });
199
- var FieldMappingEditorPresentation = definePresentation({
200
- meta: {
201
- key: "integration.fieldMapping.editor",
202
- version: "1.0.0",
203
- title: "Field Mapping Editor",
204
- description: "Visual field mapping editor",
205
- domain: "integration",
206
- owners: ["@integration-team"],
207
- tags: ["integration", "field-mapping", "editor"],
208
- stability: StabilityEnum.Experimental,
209
- goal: "Allow users to map source fields to target fields visually.",
210
- context: "Schema mapping tool for data consistency."
211
- },
212
- source: {
213
- type: "component",
214
- framework: "react",
215
- componentKey: "FieldMappingEditor",
216
- props: FieldMappingModel
217
- },
218
- targets: ["react"],
219
- policy: {
220
- flags: ["integration.sync.enabled"]
221
- }
222
- });
223
- var SyncRunListPresentation = definePresentation({
224
- meta: {
225
- key: "integration.syncRun.viewList",
226
- version: "1.0.0",
227
- title: "Sync Run History",
228
- description: "History of sync runs",
229
- domain: "integration",
230
- owners: ["@integration-team"],
231
- tags: ["integration", "sync", "runs", "history"],
232
- stability: StabilityEnum.Experimental,
233
- goal: "Provide a historical log of all sync attempts and their results.",
234
- context: "Audit and troubleshooting view for sync jobs."
235
- },
236
- source: {
237
- type: "component",
238
- framework: "react",
239
- componentKey: "SyncRunList",
240
- props: SyncRunModel
241
- },
242
- targets: ["react", "markdown"],
243
- policy: {
244
- flags: ["integration.sync.enabled"]
245
- }
246
- });
247
- var SyncRunDetailPresentation = definePresentation({
248
- meta: {
249
- key: "integration.syncRun.detail",
250
- version: "1.0.0",
251
- title: "Sync Run Details",
252
- description: "Detailed view of a sync run with logs",
253
- domain: "integration",
254
- owners: ["@integration-team"],
255
- tags: ["integration", "sync", "run", "detail"],
256
- stability: StabilityEnum.Experimental,
257
- goal: "Show granular details and logs for a specific sync run.",
258
- context: "Detailed troubleshooting view."
259
- },
260
- source: {
261
- type: "component",
262
- framework: "react",
263
- componentKey: "SyncRunDetail",
264
- props: SyncRunModel
265
- },
266
- targets: ["react", "markdown"],
267
- policy: {
268
- flags: ["integration.sync.enabled"]
269
- }
270
- });
271
- var SyncActivityPresentation = definePresentation({
272
- meta: {
273
- key: "integration.sync.activity",
274
- version: "1.0.0",
275
- title: "Sync Activity Monitor",
276
- description: "Real-time sync activity monitor",
277
- domain: "integration",
278
- owners: ["@integration-team"],
279
- tags: ["integration", "sync", "activity", "realtime"],
280
- stability: StabilityEnum.Experimental,
281
- goal: "Monitor live data flow and sync performance.",
282
- context: "Real-time operations monitor."
283
- },
284
- source: {
285
- type: "component",
286
- framework: "react",
287
- componentKey: "SyncActivity"
288
- },
289
- targets: ["react", "markdown"],
290
- policy: {
291
- flags: ["integration.sync.enabled"]
292
- }
293
- });
294
- export {
295
- SyncRunListPresentation,
296
- SyncRunDetailPresentation,
297
- SyncConfigListPresentation,
298
- SyncConfigEditorPresentation,
299
- SyncActivityPresentation,
300
- FieldMappingEditorPresentation
301
- };
@@ -1,154 +0,0 @@
1
- // src/sync/sync.enum.ts
2
- import { defineEnum } from "@contractspec/lib.schema";
3
- var SyncDirectionEnum = defineEnum("SyncDirection", [
4
- "INBOUND",
5
- "OUTBOUND",
6
- "BIDIRECTIONAL"
7
- ]);
8
- var SyncStatusEnum = defineEnum("SyncStatus", [
9
- "PENDING",
10
- "RUNNING",
11
- "COMPLETED",
12
- "FAILED",
13
- "CANCELLED"
14
- ]);
15
- var MappingTypeEnum = defineEnum("MappingType", [
16
- "DIRECT",
17
- "TRANSFORM",
18
- "LOOKUP",
19
- "CONSTANT",
20
- "COMPUTED"
21
- ]);
22
-
23
- // src/sync/sync.schema.ts
24
- import { defineSchemaModel, ScalarTypeEnum } from "@contractspec/lib.schema";
25
- var FieldMappingModel = defineSchemaModel({
26
- name: "FieldMappingModel",
27
- fields: {
28
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
29
- sourceField: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
30
- targetField: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
31
- mappingType: { type: MappingTypeEnum, isOptional: false },
32
- transformExpression: {
33
- type: ScalarTypeEnum.String_unsecure(),
34
- isOptional: true
35
- },
36
- isRequired: { type: ScalarTypeEnum.Boolean(), isOptional: false }
37
- }
38
- });
39
- var SyncConfigModel = defineSchemaModel({
40
- name: "SyncConfigModel",
41
- fields: {
42
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
43
- integrationId: {
44
- type: ScalarTypeEnum.String_unsecure(),
45
- isOptional: false
46
- },
47
- connectionId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
48
- name: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
49
- direction: { type: SyncDirectionEnum, isOptional: false },
50
- sourceObject: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
51
- targetObject: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
52
- scheduleEnabled: { type: ScalarTypeEnum.Boolean(), isOptional: false },
53
- scheduleCron: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
54
- isActive: { type: ScalarTypeEnum.Boolean(), isOptional: false },
55
- lastSyncAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },
56
- fieldMappings: { type: FieldMappingModel, isArray: true, isOptional: true }
57
- }
58
- });
59
- var SyncRunModel = defineSchemaModel({
60
- name: "SyncRunModel",
61
- fields: {
62
- id: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
63
- syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
64
- status: { type: SyncStatusEnum, isOptional: false },
65
- direction: { type: SyncDirectionEnum, isOptional: false },
66
- trigger: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
67
- recordsProcessed: {
68
- type: ScalarTypeEnum.Int_unsecure(),
69
- isOptional: false
70
- },
71
- recordsCreated: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
72
- recordsUpdated: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
73
- recordsFailed: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false },
74
- errorMessage: { type: ScalarTypeEnum.String_unsecure(), isOptional: true },
75
- startedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },
76
- completedAt: { type: ScalarTypeEnum.DateTime(), isOptional: true },
77
- createdAt: { type: ScalarTypeEnum.DateTime(), isOptional: false }
78
- }
79
- });
80
- var CreateSyncConfigInputModel = defineSchemaModel({
81
- name: "CreateSyncConfigInput",
82
- fields: {
83
- integrationId: {
84
- type: ScalarTypeEnum.String_unsecure(),
85
- isOptional: false
86
- },
87
- connectionId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
88
- name: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
89
- direction: { type: SyncDirectionEnum, isOptional: false },
90
- sourceObject: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
91
- targetObject: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
92
- scheduleEnabled: { type: ScalarTypeEnum.Boolean(), isOptional: true },
93
- scheduleCron: { type: ScalarTypeEnum.String_unsecure(), isOptional: true }
94
- }
95
- });
96
- var AddFieldMappingInputModel = defineSchemaModel({
97
- name: "AddFieldMappingInput",
98
- fields: {
99
- syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
100
- sourceField: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
101
- targetField: { type: ScalarTypeEnum.NonEmptyString(), isOptional: false },
102
- mappingType: { type: MappingTypeEnum, isOptional: false },
103
- transformExpression: {
104
- type: ScalarTypeEnum.String_unsecure(),
105
- isOptional: true
106
- },
107
- lookupConfig: { type: ScalarTypeEnum.JSON(), isOptional: true },
108
- constantValue: { type: ScalarTypeEnum.JSON(), isOptional: true },
109
- isRequired: { type: ScalarTypeEnum.Boolean(), isOptional: true },
110
- defaultValue: { type: ScalarTypeEnum.JSON(), isOptional: true }
111
- }
112
- });
113
- var TriggerSyncInputModel = defineSchemaModel({
114
- name: "TriggerSyncInput",
115
- fields: {
116
- syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
117
- direction: { type: SyncDirectionEnum, isOptional: true },
118
- fullSync: { type: ScalarTypeEnum.Boolean(), isOptional: true }
119
- }
120
- });
121
- var ListSyncRunsInputModel = defineSchemaModel({
122
- name: "ListSyncRunsInput",
123
- fields: {
124
- syncConfigId: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
125
- status: { type: SyncStatusEnum, isOptional: true },
126
- limit: {
127
- type: ScalarTypeEnum.Int_unsecure(),
128
- isOptional: true,
129
- defaultValue: 20
130
- },
131
- offset: {
132
- type: ScalarTypeEnum.Int_unsecure(),
133
- isOptional: true,
134
- defaultValue: 0
135
- }
136
- }
137
- });
138
- var ListSyncRunsOutputModel = defineSchemaModel({
139
- name: "ListSyncRunsOutput",
140
- fields: {
141
- runs: { type: SyncRunModel, isArray: true, isOptional: false },
142
- total: { type: ScalarTypeEnum.Int_unsecure(), isOptional: false }
143
- }
144
- });
145
- export {
146
- TriggerSyncInputModel,
147
- SyncRunModel,
148
- SyncConfigModel,
149
- ListSyncRunsOutputModel,
150
- ListSyncRunsInputModel,
151
- FieldMappingModel,
152
- CreateSyncConfigInputModel,
153
- AddFieldMappingInputModel
154
- };
@@ -1,186 +0,0 @@
1
- // src/sync-engine/index.ts
2
- class BasicFieldTransformer {
3
- transform(value, expression) {
4
- try {
5
- if (expression.startsWith("uppercase")) {
6
- return typeof value === "string" ? value.toUpperCase() : value;
7
- }
8
- if (expression.startsWith("lowercase")) {
9
- return typeof value === "string" ? value.toLowerCase() : value;
10
- }
11
- if (expression.startsWith("trim")) {
12
- return typeof value === "string" ? value.trim() : value;
13
- }
14
- if (expression.startsWith("default:")) {
15
- const defaultVal = expression.replace("default:", "");
16
- return value ?? JSON.parse(defaultVal);
17
- }
18
- if (expression.startsWith("concat:")) {
19
- const separator = expression.replace("concat:", "") || " ";
20
- if (Array.isArray(value)) {
21
- return value.join(separator);
22
- }
23
- return value;
24
- }
25
- if (expression.startsWith("split:")) {
26
- const separator = expression.replace("split:", "") || ",";
27
- if (typeof value === "string") {
28
- return value.split(separator);
29
- }
30
- return value;
31
- }
32
- if (expression.startsWith("number")) {
33
- return Number(value);
34
- }
35
- if (expression.startsWith("boolean")) {
36
- return Boolean(value);
37
- }
38
- if (expression.startsWith("string")) {
39
- return String(value);
40
- }
41
- return value;
42
- } catch {
43
- return value;
44
- }
45
- }
46
- }
47
-
48
- class BasicSyncEngine {
49
- transformer;
50
- constructor(transformer) {
51
- this.transformer = transformer ?? new BasicFieldTransformer;
52
- }
53
- async sync(_context) {
54
- const result = {
55
- success: true,
56
- recordsProcessed: 0,
57
- recordsCreated: 0,
58
- recordsUpdated: 0,
59
- recordsDeleted: 0,
60
- recordsFailed: 0,
61
- recordsSkipped: 0,
62
- errors: []
63
- };
64
- return result;
65
- }
66
- transformRecord(sourceRecord, mappings, _context) {
67
- const targetData = {};
68
- for (const mapping of mappings) {
69
- let value;
70
- let sourceValue;
71
- switch (mapping.mappingType) {
72
- case "DIRECT":
73
- value = this.getNestedValue(sourceRecord.data, mapping.sourceField);
74
- break;
75
- case "TRANSFORM":
76
- sourceValue = this.getNestedValue(sourceRecord.data, mapping.sourceField);
77
- value = mapping.transformExpression ? this.transformer.transform(sourceValue, mapping.transformExpression) : sourceValue;
78
- break;
79
- case "CONSTANT":
80
- value = mapping.constantValue;
81
- break;
82
- case "LOOKUP":
83
- value = this.getNestedValue(sourceRecord.data, mapping.sourceField);
84
- break;
85
- case "COMPUTED":
86
- value = mapping.transformExpression ? this.evaluateComputed(sourceRecord.data, mapping.transformExpression) : null;
87
- break;
88
- default:
89
- value = this.getNestedValue(sourceRecord.data, mapping.sourceField);
90
- }
91
- if (value === undefined || value === null) {
92
- value = mapping.defaultValue;
93
- }
94
- this.setNestedValue(targetData, mapping.targetField, value);
95
- }
96
- return {
97
- id: sourceRecord.id,
98
- data: targetData
99
- };
100
- }
101
- validateRecord(record, mappings) {
102
- const errors = [];
103
- for (const mapping of mappings) {
104
- if (mapping.isRequired) {
105
- const value = this.getNestedValue(record.data, mapping.targetField);
106
- if (value === undefined || value === null) {
107
- errors.push({
108
- recordId: record.id,
109
- field: mapping.targetField,
110
- message: `Required field ${mapping.targetField} is missing`,
111
- code: "REQUIRED_FIELD_MISSING"
112
- });
113
- }
114
- }
115
- }
116
- return {
117
- valid: errors.length === 0,
118
- errors
119
- };
120
- }
121
- getNestedValue(obj, path) {
122
- const parts = path.split(".");
123
- let current = obj;
124
- for (const part of parts) {
125
- if (current === null || current === undefined) {
126
- return;
127
- }
128
- current = current[part];
129
- }
130
- return current;
131
- }
132
- setNestedValue(obj, path, value) {
133
- const parts = path.split(".");
134
- let current = obj;
135
- for (let i = 0;i < parts.length - 1; i++) {
136
- const part = parts[i];
137
- if (part === undefined)
138
- continue;
139
- if (!(part in current)) {
140
- current[part] = {};
141
- }
142
- current = current[part];
143
- }
144
- const lastPart = parts[parts.length - 1];
145
- if (lastPart !== undefined) {
146
- current[lastPart] = value;
147
- }
148
- }
149
- evaluateComputed(data, expression) {
150
- try {
151
- const result = expression.replace(/\$\{([^}]+)\}/g, (_, path) => {
152
- const value = this.getNestedValue(data, path);
153
- return String(value ?? "");
154
- });
155
- return result;
156
- } catch {
157
- return null;
158
- }
159
- }
160
- }
161
- function createSyncEngine(transformer) {
162
- return new BasicSyncEngine(transformer);
163
- }
164
- function computeChecksum(data) {
165
- const str = JSON.stringify(data, Object.keys(data).sort());
166
- let hash = 0;
167
- for (let i = 0;i < str.length; i++) {
168
- const char = str.charCodeAt(i);
169
- hash = (hash << 5) - hash + char;
170
- hash = hash & hash;
171
- }
172
- return hash.toString(16);
173
- }
174
- function hasChanges(sourceChecksum, targetChecksum) {
175
- if (!sourceChecksum || !targetChecksum) {
176
- return true;
177
- }
178
- return sourceChecksum !== targetChecksum;
179
- }
180
- export {
181
- hasChanges,
182
- createSyncEngine,
183
- computeChecksum,
184
- BasicSyncEngine,
185
- BasicFieldTransformer
186
- };