@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,332 @@
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.operations.ts
147
+ import {
148
+ defineCommand,
149
+ defineQuery
150
+ } from "@contractspec/lib.contracts/operations";
151
+ var OWNERS = ["@example.integration-hub"];
152
+ var CreateSyncConfigContract = defineCommand({
153
+ meta: {
154
+ key: "integration.syncConfig.create",
155
+ version: "1.0.0",
156
+ stability: "stable",
157
+ owners: [...OWNERS],
158
+ tags: ["integration", "sync", "config", "create"],
159
+ description: "Create a sync configuration.",
160
+ goal: "Define how data should be synchronized.",
161
+ context: "Sync setup."
162
+ },
163
+ io: { input: CreateSyncConfigInputModel, output: SyncConfigModel },
164
+ policy: { auth: "user" },
165
+ sideEffects: {
166
+ emits: [
167
+ {
168
+ key: "integration.syncConfig.created",
169
+ version: "1.0.0",
170
+ when: "Sync config created",
171
+ payload: SyncConfigModel
172
+ }
173
+ ],
174
+ audit: ["integration.syncConfig.created"]
175
+ },
176
+ acceptance: {
177
+ scenarios: [
178
+ {
179
+ key: "create-sync-happy-path",
180
+ given: ["User is authenticated"],
181
+ when: ["User creates sync config"],
182
+ then: ["Sync config is created", "SyncConfigCreated event is emitted"]
183
+ }
184
+ ],
185
+ examples: [
186
+ {
187
+ key: "create-contact-sync",
188
+ input: {
189
+ name: "Contacts Sync",
190
+ sourceConnectionId: "conn-1",
191
+ targetConnectionId: "conn-2"
192
+ },
193
+ output: { id: "sync-123", status: "active" }
194
+ }
195
+ ]
196
+ }
197
+ });
198
+ var AddFieldMappingContract = defineCommand({
199
+ meta: {
200
+ key: "integration.fieldMapping.add",
201
+ version: "1.0.0",
202
+ stability: "stable",
203
+ owners: [...OWNERS],
204
+ tags: ["integration", "mapping", "field"],
205
+ description: "Add a field mapping to a sync config.",
206
+ goal: "Map fields between systems.",
207
+ context: "Mapping configuration."
208
+ },
209
+ io: { input: AddFieldMappingInputModel, output: FieldMappingModel },
210
+ policy: { auth: "user" },
211
+ sideEffects: {
212
+ emits: [
213
+ {
214
+ key: "integration.fieldMapping.added",
215
+ version: "1.0.0",
216
+ when: "Mapping added",
217
+ payload: FieldMappingModel
218
+ }
219
+ ]
220
+ },
221
+ acceptance: {
222
+ scenarios: [
223
+ {
224
+ key: "add-mapping-happy-path",
225
+ given: ["Sync config exists"],
226
+ when: ["User adds field mapping"],
227
+ then: ["Mapping is added", "FieldMappingAdded event is emitted"]
228
+ }
229
+ ],
230
+ examples: [
231
+ {
232
+ key: "map-email",
233
+ input: {
234
+ syncConfigId: "sync-123",
235
+ sourceField: "email",
236
+ targetField: "user_email"
237
+ },
238
+ output: { id: "map-456", type: "string" }
239
+ }
240
+ ]
241
+ }
242
+ });
243
+ var TriggerSyncContract = defineCommand({
244
+ meta: {
245
+ key: "integration.sync.trigger",
246
+ version: "1.0.0",
247
+ stability: "stable",
248
+ owners: [...OWNERS],
249
+ tags: ["integration", "sync", "trigger"],
250
+ description: "Trigger a manual sync.",
251
+ goal: "Start data synchronization.",
252
+ context: "Manual sync or webhook trigger."
253
+ },
254
+ io: { input: TriggerSyncInputModel, output: SyncRunModel },
255
+ policy: { auth: "user" },
256
+ sideEffects: {
257
+ emits: [
258
+ {
259
+ key: "integration.sync.started",
260
+ version: "1.0.0",
261
+ when: "Sync starts",
262
+ payload: SyncRunModel
263
+ }
264
+ ],
265
+ audit: ["integration.sync.triggered"]
266
+ },
267
+ acceptance: {
268
+ scenarios: [
269
+ {
270
+ key: "trigger-sync-happy-path",
271
+ given: ["Sync config exists"],
272
+ when: ["User triggers sync"],
273
+ then: ["Sync run starts", "SyncStarted event is emitted"]
274
+ }
275
+ ],
276
+ examples: [
277
+ {
278
+ key: "manual-trigger",
279
+ input: { syncConfigId: "sync-123" },
280
+ output: { id: "run-789", status: "pending" }
281
+ }
282
+ ]
283
+ }
284
+ });
285
+ var ListSyncRunsContract = defineQuery({
286
+ meta: {
287
+ key: "integration.syncRun.list",
288
+ version: "1.0.0",
289
+ stability: "stable",
290
+ owners: [...OWNERS],
291
+ tags: ["integration", "sync", "run", "list"],
292
+ description: "List sync run history.",
293
+ goal: "View sync history and status.",
294
+ context: "Sync monitoring."
295
+ },
296
+ io: { input: ListSyncRunsInputModel, output: ListSyncRunsOutputModel },
297
+ policy: { auth: "user" },
298
+ acceptance: {
299
+ scenarios: [
300
+ {
301
+ key: "list-runs-happy-path",
302
+ given: ["User has access to syncs"],
303
+ when: ["User lists sync runs"],
304
+ then: ["List of runs is returned"]
305
+ }
306
+ ],
307
+ examples: [
308
+ {
309
+ key: "list-recent",
310
+ input: { limit: 10 },
311
+ output: { items: [], total: 50 }
312
+ }
313
+ ]
314
+ }
315
+ });
316
+ export {
317
+ TriggerSyncInputModel,
318
+ TriggerSyncContract,
319
+ SyncStatusEnum,
320
+ SyncRunModel,
321
+ SyncDirectionEnum,
322
+ SyncConfigModel,
323
+ MappingTypeEnum,
324
+ ListSyncRunsOutputModel,
325
+ ListSyncRunsInputModel,
326
+ ListSyncRunsContract,
327
+ FieldMappingModel,
328
+ CreateSyncConfigInputModel,
329
+ CreateSyncConfigContract,
330
+ AddFieldMappingInputModel,
331
+ AddFieldMappingContract
332
+ };
@@ -0,0 +1,26 @@
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
+ export {
23
+ SyncStatusEnum,
24
+ SyncDirectionEnum,
25
+ MappingTypeEnum
26
+ };
@@ -0,0 +1,321 @@
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.operations.ts
147
+ import {
148
+ defineCommand,
149
+ defineQuery
150
+ } from "@contractspec/lib.contracts/operations";
151
+ var OWNERS = ["@example.integration-hub"];
152
+ var CreateSyncConfigContract = defineCommand({
153
+ meta: {
154
+ key: "integration.syncConfig.create",
155
+ version: "1.0.0",
156
+ stability: "stable",
157
+ owners: [...OWNERS],
158
+ tags: ["integration", "sync", "config", "create"],
159
+ description: "Create a sync configuration.",
160
+ goal: "Define how data should be synchronized.",
161
+ context: "Sync setup."
162
+ },
163
+ io: { input: CreateSyncConfigInputModel, output: SyncConfigModel },
164
+ policy: { auth: "user" },
165
+ sideEffects: {
166
+ emits: [
167
+ {
168
+ key: "integration.syncConfig.created",
169
+ version: "1.0.0",
170
+ when: "Sync config created",
171
+ payload: SyncConfigModel
172
+ }
173
+ ],
174
+ audit: ["integration.syncConfig.created"]
175
+ },
176
+ acceptance: {
177
+ scenarios: [
178
+ {
179
+ key: "create-sync-happy-path",
180
+ given: ["User is authenticated"],
181
+ when: ["User creates sync config"],
182
+ then: ["Sync config is created", "SyncConfigCreated event is emitted"]
183
+ }
184
+ ],
185
+ examples: [
186
+ {
187
+ key: "create-contact-sync",
188
+ input: {
189
+ name: "Contacts Sync",
190
+ sourceConnectionId: "conn-1",
191
+ targetConnectionId: "conn-2"
192
+ },
193
+ output: { id: "sync-123", status: "active" }
194
+ }
195
+ ]
196
+ }
197
+ });
198
+ var AddFieldMappingContract = defineCommand({
199
+ meta: {
200
+ key: "integration.fieldMapping.add",
201
+ version: "1.0.0",
202
+ stability: "stable",
203
+ owners: [...OWNERS],
204
+ tags: ["integration", "mapping", "field"],
205
+ description: "Add a field mapping to a sync config.",
206
+ goal: "Map fields between systems.",
207
+ context: "Mapping configuration."
208
+ },
209
+ io: { input: AddFieldMappingInputModel, output: FieldMappingModel },
210
+ policy: { auth: "user" },
211
+ sideEffects: {
212
+ emits: [
213
+ {
214
+ key: "integration.fieldMapping.added",
215
+ version: "1.0.0",
216
+ when: "Mapping added",
217
+ payload: FieldMappingModel
218
+ }
219
+ ]
220
+ },
221
+ acceptance: {
222
+ scenarios: [
223
+ {
224
+ key: "add-mapping-happy-path",
225
+ given: ["Sync config exists"],
226
+ when: ["User adds field mapping"],
227
+ then: ["Mapping is added", "FieldMappingAdded event is emitted"]
228
+ }
229
+ ],
230
+ examples: [
231
+ {
232
+ key: "map-email",
233
+ input: {
234
+ syncConfigId: "sync-123",
235
+ sourceField: "email",
236
+ targetField: "user_email"
237
+ },
238
+ output: { id: "map-456", type: "string" }
239
+ }
240
+ ]
241
+ }
242
+ });
243
+ var TriggerSyncContract = defineCommand({
244
+ meta: {
245
+ key: "integration.sync.trigger",
246
+ version: "1.0.0",
247
+ stability: "stable",
248
+ owners: [...OWNERS],
249
+ tags: ["integration", "sync", "trigger"],
250
+ description: "Trigger a manual sync.",
251
+ goal: "Start data synchronization.",
252
+ context: "Manual sync or webhook trigger."
253
+ },
254
+ io: { input: TriggerSyncInputModel, output: SyncRunModel },
255
+ policy: { auth: "user" },
256
+ sideEffects: {
257
+ emits: [
258
+ {
259
+ key: "integration.sync.started",
260
+ version: "1.0.0",
261
+ when: "Sync starts",
262
+ payload: SyncRunModel
263
+ }
264
+ ],
265
+ audit: ["integration.sync.triggered"]
266
+ },
267
+ acceptance: {
268
+ scenarios: [
269
+ {
270
+ key: "trigger-sync-happy-path",
271
+ given: ["Sync config exists"],
272
+ when: ["User triggers sync"],
273
+ then: ["Sync run starts", "SyncStarted event is emitted"]
274
+ }
275
+ ],
276
+ examples: [
277
+ {
278
+ key: "manual-trigger",
279
+ input: { syncConfigId: "sync-123" },
280
+ output: { id: "run-789", status: "pending" }
281
+ }
282
+ ]
283
+ }
284
+ });
285
+ var ListSyncRunsContract = defineQuery({
286
+ meta: {
287
+ key: "integration.syncRun.list",
288
+ version: "1.0.0",
289
+ stability: "stable",
290
+ owners: [...OWNERS],
291
+ tags: ["integration", "sync", "run", "list"],
292
+ description: "List sync run history.",
293
+ goal: "View sync history and status.",
294
+ context: "Sync monitoring."
295
+ },
296
+ io: { input: ListSyncRunsInputModel, output: ListSyncRunsOutputModel },
297
+ policy: { auth: "user" },
298
+ acceptance: {
299
+ scenarios: [
300
+ {
301
+ key: "list-runs-happy-path",
302
+ given: ["User has access to syncs"],
303
+ when: ["User lists sync runs"],
304
+ then: ["List of runs is returned"]
305
+ }
306
+ ],
307
+ examples: [
308
+ {
309
+ key: "list-recent",
310
+ input: { limit: 10 },
311
+ output: { items: [], total: 50 }
312
+ }
313
+ ]
314
+ }
315
+ });
316
+ export {
317
+ TriggerSyncContract,
318
+ ListSyncRunsContract,
319
+ CreateSyncConfigContract,
320
+ AddFieldMappingContract
321
+ };