@contractspec/example.integration-hub 1.57.0 → 1.58.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 (190) hide show
  1. package/dist/browser/connection/connection.enum.js +12 -0
  2. package/dist/browser/connection/connection.operation.js +101 -0
  3. package/dist/browser/connection/connection.presentation.js +99 -0
  4. package/dist/browser/connection/connection.schema.js +48 -0
  5. package/dist/browser/connection/index.js +104 -0
  6. package/dist/browser/docs/index.js +104 -0
  7. package/dist/browser/docs/integration-hub.docblock.js +104 -0
  8. package/dist/browser/events.js +211 -0
  9. package/dist/browser/example.js +42 -0
  10. package/dist/browser/handlers/index.js +246 -0
  11. package/dist/browser/handlers/integration.handlers.js +246 -0
  12. package/dist/browser/index.js +1595 -0
  13. package/dist/browser/integration/index.js +92 -0
  14. package/dist/browser/integration/integration.enum.js +12 -0
  15. package/dist/browser/integration/integration.operations.js +89 -0
  16. package/dist/browser/integration/integration.presentation.js +117 -0
  17. package/dist/browser/integration/integration.schema.js +42 -0
  18. package/dist/browser/integration-hub.capability.js +40 -0
  19. package/dist/browser/integration-hub.feature.js +114 -0
  20. package/dist/browser/seeders/index.js +60 -0
  21. package/dist/browser/sync/index.js +332 -0
  22. package/dist/browser/sync/sync.enum.js +26 -0
  23. package/dist/browser/sync/sync.operations.js +321 -0
  24. package/dist/browser/sync/sync.presentation.js +298 -0
  25. package/dist/browser/sync/sync.schema.js +154 -0
  26. package/dist/browser/sync-engine/index.js +186 -0
  27. package/dist/browser/tests/operations.test-spec.js +85 -0
  28. package/dist/browser/ui/IntegrationDashboard.js +369 -0
  29. package/dist/browser/ui/hooks/index.js +57 -0
  30. package/dist/browser/ui/hooks/useIntegrationData.js +54 -0
  31. package/dist/browser/ui/index.js +644 -0
  32. package/dist/browser/ui/renderers/index.js +273 -0
  33. package/dist/browser/ui/renderers/integration.markdown.js +273 -0
  34. package/dist/connection/connection.enum.d.ts +1 -6
  35. package/dist/connection/connection.enum.d.ts.map +1 -1
  36. package/dist/connection/connection.enum.js +11 -15
  37. package/dist/connection/connection.operation.d.ts +78 -84
  38. package/dist/connection/connection.operation.d.ts.map +1 -1
  39. package/dist/connection/connection.operation.js +99 -60
  40. package/dist/connection/connection.presentation.d.ts +2 -7
  41. package/dist/connection/connection.presentation.d.ts.map +1 -1
  42. package/dist/connection/connection.presentation.js +96 -56
  43. package/dist/connection/connection.schema.d.ts +54 -59
  44. package/dist/connection/connection.schema.d.ts.map +1 -1
  45. package/dist/connection/connection.schema.js +46 -73
  46. package/dist/connection/index.d.ts +7 -4
  47. package/dist/connection/index.d.ts.map +1 -0
  48. package/dist/connection/index.js +104 -4
  49. package/dist/docs/index.d.ts +2 -1
  50. package/dist/docs/index.d.ts.map +1 -0
  51. package/dist/docs/index.js +105 -1
  52. package/dist/docs/integration-hub.docblock.d.ts +2 -1
  53. package/dist/docs/integration-hub.docblock.d.ts.map +1 -0
  54. package/dist/docs/integration-hub.docblock.js +45 -56
  55. package/dist/events.d.ts +137 -143
  56. package/dist/events.d.ts.map +1 -1
  57. package/dist/events.js +210 -287
  58. package/dist/example.d.ts +2 -6
  59. package/dist/example.d.ts.map +1 -1
  60. package/dist/example.js +41 -55
  61. package/dist/handlers/index.d.ts +2 -2
  62. package/dist/handlers/index.d.ts.map +1 -0
  63. package/dist/handlers/index.js +247 -3
  64. package/dist/handlers/integration.handlers.d.ts +114 -113
  65. package/dist/handlers/integration.handlers.d.ts.map +1 -1
  66. package/dist/handlers/integration.handlers.js +232 -267
  67. package/dist/index.d.ts +12 -19
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +1596 -20
  70. package/dist/integration/index.d.ts +7 -4
  71. package/dist/integration/index.d.ts.map +1 -0
  72. package/dist/integration/index.js +92 -4
  73. package/dist/integration/integration.enum.d.ts +1 -6
  74. package/dist/integration/integration.enum.d.ts.map +1 -1
  75. package/dist/integration/integration.enum.js +11 -15
  76. package/dist/integration/integration.operations.d.ts +74 -80
  77. package/dist/integration/integration.operations.d.ts.map +1 -1
  78. package/dist/integration/integration.operations.js +87 -54
  79. package/dist/integration/integration.presentation.d.ts +3 -8
  80. package/dist/integration/integration.presentation.d.ts.map +1 -1
  81. package/dist/integration/integration.presentation.js +114 -73
  82. package/dist/integration/integration.schema.d.ts +54 -59
  83. package/dist/integration/integration.schema.d.ts.map +1 -1
  84. package/dist/integration/integration.schema.js +40 -73
  85. package/dist/integration-hub.capability.d.ts +3 -8
  86. package/dist/integration-hub.capability.d.ts.map +1 -1
  87. package/dist/integration-hub.capability.js +41 -38
  88. package/dist/integration-hub.feature.d.ts +1 -6
  89. package/dist/integration-hub.feature.d.ts.map +1 -1
  90. package/dist/integration-hub.feature.js +113 -242
  91. package/dist/node/connection/connection.enum.js +12 -0
  92. package/dist/node/connection/connection.operation.js +101 -0
  93. package/dist/node/connection/connection.presentation.js +99 -0
  94. package/dist/node/connection/connection.schema.js +48 -0
  95. package/dist/node/connection/index.js +104 -0
  96. package/dist/node/docs/index.js +104 -0
  97. package/dist/node/docs/integration-hub.docblock.js +104 -0
  98. package/dist/node/events.js +211 -0
  99. package/dist/node/example.js +42 -0
  100. package/dist/node/handlers/index.js +246 -0
  101. package/dist/node/handlers/integration.handlers.js +246 -0
  102. package/dist/node/index.js +1595 -0
  103. package/dist/node/integration/index.js +92 -0
  104. package/dist/node/integration/integration.enum.js +12 -0
  105. package/dist/node/integration/integration.operations.js +89 -0
  106. package/dist/node/integration/integration.presentation.js +117 -0
  107. package/dist/node/integration/integration.schema.js +42 -0
  108. package/dist/node/integration-hub.capability.js +40 -0
  109. package/dist/node/integration-hub.feature.js +114 -0
  110. package/dist/node/seeders/index.js +60 -0
  111. package/dist/node/sync/index.js +332 -0
  112. package/dist/node/sync/sync.enum.js +26 -0
  113. package/dist/node/sync/sync.operations.js +321 -0
  114. package/dist/node/sync/sync.presentation.js +298 -0
  115. package/dist/node/sync/sync.schema.js +154 -0
  116. package/dist/node/sync-engine/index.js +186 -0
  117. package/dist/node/tests/operations.test-spec.js +85 -0
  118. package/dist/node/ui/IntegrationDashboard.js +369 -0
  119. package/dist/node/ui/hooks/index.js +57 -0
  120. package/dist/node/ui/hooks/useIntegrationData.js +54 -0
  121. package/dist/node/ui/index.js +644 -0
  122. package/dist/node/ui/renderers/index.js +273 -0
  123. package/dist/node/ui/renderers/integration.markdown.js +273 -0
  124. package/dist/seeders/index.d.ts +4 -8
  125. package/dist/seeders/index.d.ts.map +1 -1
  126. package/dist/seeders/index.js +54 -52
  127. package/dist/sync/index.d.ts +7 -4
  128. package/dist/sync/index.d.ts.map +1 -0
  129. package/dist/sync/index.js +332 -4
  130. package/dist/sync/sync.enum.d.ts +3 -8
  131. package/dist/sync/sync.enum.d.ts.map +1 -1
  132. package/dist/sync/sync.enum.js +23 -31
  133. package/dist/sync/sync.operations.d.ts +413 -419
  134. package/dist/sync/sync.operations.d.ts.map +1 -1
  135. package/dist/sync/sync.operations.js +316 -197
  136. package/dist/sync/sync.presentation.d.ts +6 -11
  137. package/dist/sync/sync.presentation.d.ts.map +1 -1
  138. package/dist/sync/sync.presentation.js +291 -160
  139. package/dist/sync/sync.schema.d.ts +317 -322
  140. package/dist/sync/sync.schema.d.ts.map +1 -1
  141. package/dist/sync/sync.schema.js +146 -295
  142. package/dist/sync-engine/index.d.ts +88 -91
  143. package/dist/sync-engine/index.d.ts.map +1 -1
  144. package/dist/sync-engine/index.js +181 -142
  145. package/dist/tests/operations.test-spec.d.ts +3 -8
  146. package/dist/tests/operations.test-spec.d.ts.map +1 -1
  147. package/dist/tests/operations.test-spec.js +82 -90
  148. package/dist/ui/IntegrationDashboard.d.ts +1 -6
  149. package/dist/ui/IntegrationDashboard.d.ts.map +1 -1
  150. package/dist/ui/IntegrationDashboard.js +365 -261
  151. package/dist/ui/hooks/index.d.ts +2 -2
  152. package/dist/ui/hooks/index.d.ts.map +1 -0
  153. package/dist/ui/hooks/index.js +57 -4
  154. package/dist/ui/hooks/useIntegrationData.d.ts +16 -20
  155. package/dist/ui/hooks/useIntegrationData.d.ts.map +1 -1
  156. package/dist/ui/hooks/useIntegrationData.js +51 -55
  157. package/dist/ui/index.d.ts +7 -6
  158. package/dist/ui/index.d.ts.map +1 -0
  159. package/dist/ui/index.js +644 -5
  160. package/dist/ui/renderers/index.d.ts +2 -2
  161. package/dist/ui/renderers/index.d.ts.map +1 -0
  162. package/dist/ui/renderers/index.js +274 -3
  163. package/dist/ui/renderers/integration.markdown.d.ts +13 -14
  164. package/dist/ui/renderers/integration.markdown.d.ts.map +1 -1
  165. package/dist/ui/renderers/integration.markdown.js +268 -264
  166. package/package.json +360 -71
  167. package/dist/connection/connection.enum.js.map +0 -1
  168. package/dist/connection/connection.operation.js.map +0 -1
  169. package/dist/connection/connection.presentation.js.map +0 -1
  170. package/dist/connection/connection.schema.js.map +0 -1
  171. package/dist/docs/integration-hub.docblock.js.map +0 -1
  172. package/dist/events.js.map +0 -1
  173. package/dist/example.js.map +0 -1
  174. package/dist/handlers/integration.handlers.js.map +0 -1
  175. package/dist/integration/integration.enum.js.map +0 -1
  176. package/dist/integration/integration.operations.js.map +0 -1
  177. package/dist/integration/integration.presentation.js.map +0 -1
  178. package/dist/integration/integration.schema.js.map +0 -1
  179. package/dist/integration-hub.capability.js.map +0 -1
  180. package/dist/integration-hub.feature.js.map +0 -1
  181. package/dist/seeders/index.js.map +0 -1
  182. package/dist/sync/sync.enum.js.map +0 -1
  183. package/dist/sync/sync.operations.js.map +0 -1
  184. package/dist/sync/sync.presentation.js.map +0 -1
  185. package/dist/sync/sync.schema.js.map +0 -1
  186. package/dist/sync-engine/index.js.map +0 -1
  187. package/dist/tests/operations.test-spec.js.map +0 -1
  188. package/dist/ui/IntegrationDashboard.js.map +0 -1
  189. package/dist/ui/hooks/useIntegrationData.js.map +0 -1
  190. package/dist/ui/renderers/integration.markdown.js.map +0 -1
@@ -0,0 +1,298 @@
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 { definePresentation, StabilityEnum } from "@contractspec/lib.contracts";
148
+ var SyncConfigListPresentation = definePresentation({
149
+ meta: {
150
+ key: "integration.syncConfig.list",
151
+ version: "1.0.0",
152
+ title: "Sync Config List",
153
+ description: "List of sync configurations",
154
+ domain: "integration",
155
+ owners: ["@integration-team"],
156
+ tags: ["integration", "sync", "config", "list"],
157
+ stability: StabilityEnum.Experimental,
158
+ goal: "Show users their current sync configurations.",
159
+ context: "Management view for data synchronization."
160
+ },
161
+ source: {
162
+ type: "component",
163
+ framework: "react",
164
+ componentKey: "SyncConfigList",
165
+ props: SyncConfigModel
166
+ },
167
+ targets: ["react", "markdown"],
168
+ policy: {
169
+ flags: ["integration.sync.enabled"]
170
+ }
171
+ });
172
+ var SyncConfigEditorPresentation = definePresentation({
173
+ meta: {
174
+ key: "integration.syncConfig.editor",
175
+ version: "1.0.0",
176
+ title: "Sync Config Editor",
177
+ description: "Editor for sync configuration settings",
178
+ domain: "integration",
179
+ owners: ["@integration-team"],
180
+ tags: ["integration", "sync", "config", "editor"],
181
+ stability: StabilityEnum.Experimental,
182
+ goal: "Allow users to configure schedule, filters, and settings for a sync.",
183
+ context: "Configuration interface for sync jobs."
184
+ },
185
+ source: {
186
+ type: "component",
187
+ framework: "react",
188
+ componentKey: "SyncConfigEditor",
189
+ props: SyncConfigModel
190
+ },
191
+ targets: ["react"],
192
+ policy: {
193
+ flags: ["integration.sync.enabled"]
194
+ }
195
+ });
196
+ var FieldMappingEditorPresentation = definePresentation({
197
+ meta: {
198
+ key: "integration.fieldMapping.editor",
199
+ version: "1.0.0",
200
+ title: "Field Mapping Editor",
201
+ description: "Visual field mapping editor",
202
+ domain: "integration",
203
+ owners: ["@integration-team"],
204
+ tags: ["integration", "field-mapping", "editor"],
205
+ stability: StabilityEnum.Experimental,
206
+ goal: "Allow users to map source fields to target fields visually.",
207
+ context: "Schema mapping tool for data consistency."
208
+ },
209
+ source: {
210
+ type: "component",
211
+ framework: "react",
212
+ componentKey: "FieldMappingEditor",
213
+ props: FieldMappingModel
214
+ },
215
+ targets: ["react"],
216
+ policy: {
217
+ flags: ["integration.sync.enabled"]
218
+ }
219
+ });
220
+ var SyncRunListPresentation = definePresentation({
221
+ meta: {
222
+ key: "integration.syncRun.viewList",
223
+ version: "1.0.0",
224
+ title: "Sync Run History",
225
+ description: "History of sync runs",
226
+ domain: "integration",
227
+ owners: ["@integration-team"],
228
+ tags: ["integration", "sync", "runs", "history"],
229
+ stability: StabilityEnum.Experimental,
230
+ goal: "Provide a historical log of all sync attempts and their results.",
231
+ context: "Audit and troubleshooting view for sync jobs."
232
+ },
233
+ source: {
234
+ type: "component",
235
+ framework: "react",
236
+ componentKey: "SyncRunList",
237
+ props: SyncRunModel
238
+ },
239
+ targets: ["react", "markdown"],
240
+ policy: {
241
+ flags: ["integration.sync.enabled"]
242
+ }
243
+ });
244
+ var SyncRunDetailPresentation = definePresentation({
245
+ meta: {
246
+ key: "integration.syncRun.detail",
247
+ version: "1.0.0",
248
+ title: "Sync Run Details",
249
+ description: "Detailed view of a sync run with logs",
250
+ domain: "integration",
251
+ owners: ["@integration-team"],
252
+ tags: ["integration", "sync", "run", "detail"],
253
+ stability: StabilityEnum.Experimental,
254
+ goal: "Show granular details and logs for a specific sync run.",
255
+ context: "Detailed troubleshooting view."
256
+ },
257
+ source: {
258
+ type: "component",
259
+ framework: "react",
260
+ componentKey: "SyncRunDetail",
261
+ props: SyncRunModel
262
+ },
263
+ targets: ["react", "markdown"],
264
+ policy: {
265
+ flags: ["integration.sync.enabled"]
266
+ }
267
+ });
268
+ var SyncActivityPresentation = definePresentation({
269
+ meta: {
270
+ key: "integration.sync.activity",
271
+ version: "1.0.0",
272
+ title: "Sync Activity Monitor",
273
+ description: "Real-time sync activity monitor",
274
+ domain: "integration",
275
+ owners: ["@integration-team"],
276
+ tags: ["integration", "sync", "activity", "realtime"],
277
+ stability: StabilityEnum.Experimental,
278
+ goal: "Monitor live data flow and sync performance.",
279
+ context: "Real-time operations monitor."
280
+ },
281
+ source: {
282
+ type: "component",
283
+ framework: "react",
284
+ componentKey: "SyncActivity"
285
+ },
286
+ targets: ["react", "markdown"],
287
+ policy: {
288
+ flags: ["integration.sync.enabled"]
289
+ }
290
+ });
291
+ export {
292
+ SyncRunListPresentation,
293
+ SyncRunDetailPresentation,
294
+ SyncConfigListPresentation,
295
+ SyncConfigEditorPresentation,
296
+ SyncActivityPresentation,
297
+ FieldMappingEditorPresentation
298
+ };
@@ -0,0 +1,154 @@
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
+ };
@@ -0,0 +1,186 @@
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
+ };