@ankhorage/contracts 1.18.0 → 1.18.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ankhorage/contracts
2
2
 
3
+ ## 1.18.1
4
+
5
+ ### Patch Changes
6
+
7
+ - fde5aeb: Add scanner workflow binding coverage to confirm existing generic contracts support runtime-aligned barcode lookup and conditional navigation flows without new domain-specific types.
8
+
3
9
  ## 1.18.0
4
10
 
5
11
  ### Minor Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ankhorage/contracts",
3
- "version": "1.18.0",
3
+ "version": "1.18.1",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@ankhorage/color-theory": "^0.0.7"
@@ -158,6 +158,128 @@ describe('component data-binding contracts', () => {
158
158
  expect(binding.target.kind).toBe('action');
159
159
  });
160
160
 
161
+ it('serializes scanner lookup and conditional navigation intent using existing generic bindings', () => {
162
+ const productLookupOperation = {
163
+ dataSourceId: 'nutrition-api',
164
+ endpointId: 'products',
165
+ operationId: 'products.lookupByBarcode',
166
+ } as const;
167
+
168
+ const bindings: ComponentDataBindingRegistry = {
169
+ scanner: {
170
+ componentId: 'scanner',
171
+ componentType: 'BarcodeScannerView',
172
+ events: {
173
+ barcodeScanned: [
174
+ {
175
+ target: {
176
+ kind: 'operation',
177
+ operation: productLookupOperation,
178
+ },
179
+ input: {
180
+ barcode: {
181
+ kind: 'source',
182
+ source: {
183
+ kind: 'event',
184
+ path: 'payload.value',
185
+ },
186
+ transforms: ['trim'],
187
+ },
188
+ },
189
+ when: {
190
+ source: {
191
+ kind: 'event',
192
+ path: 'payload.value',
193
+ },
194
+ operator: 'exists',
195
+ },
196
+ },
197
+ {
198
+ target: {
199
+ kind: 'action',
200
+ type: 'navigate',
201
+ },
202
+ input: {
203
+ route: {
204
+ kind: 'literal',
205
+ value: 'product-detail',
206
+ },
207
+ params: {
208
+ kind: 'object',
209
+ fields: {
210
+ barcode: {
211
+ kind: 'source',
212
+ source: {
213
+ kind: 'event',
214
+ path: 'payload.value',
215
+ },
216
+ transforms: ['trim'],
217
+ },
218
+ productId: {
219
+ kind: 'source',
220
+ source: {
221
+ kind: 'operation',
222
+ operation: productLookupOperation,
223
+ path: 'product.id',
224
+ },
225
+ },
226
+ },
227
+ },
228
+ },
229
+ when: {
230
+ source: {
231
+ kind: 'operation',
232
+ operation: productLookupOperation,
233
+ path: 'product.id',
234
+ },
235
+ operator: 'exists',
236
+ },
237
+ },
238
+ {
239
+ target: {
240
+ kind: 'action',
241
+ type: 'navigate',
242
+ },
243
+ input: {
244
+ route: {
245
+ kind: 'literal',
246
+ value: 'product-capture',
247
+ },
248
+ params: {
249
+ kind: 'object',
250
+ fields: {
251
+ barcode: {
252
+ kind: 'source',
253
+ source: {
254
+ kind: 'event',
255
+ path: 'payload.value',
256
+ },
257
+ transforms: ['trim'],
258
+ },
259
+ },
260
+ },
261
+ },
262
+ when: {
263
+ source: {
264
+ kind: 'operation',
265
+ operation: productLookupOperation,
266
+ path: 'product.id',
267
+ },
268
+ operator: 'notExists',
269
+ },
270
+ },
271
+ ],
272
+ },
273
+ },
274
+ };
275
+
276
+ assertSerializable(bindings);
277
+ expect(bindings.scanner?.events?.barcodeScanned).toHaveLength(3);
278
+ expect(bindings.scanner?.events?.barcodeScanned?.[0]?.target.kind).toBe('operation');
279
+ expect(bindings.scanner?.events?.barcodeScanned?.[1]?.when?.source.kind).toBe('operation');
280
+ expect(bindings.scanner?.events?.barcodeScanned?.[2]?.target.type).toBe('navigate');
281
+ });
282
+
161
283
  it('serializes component data-binding registries', () => {
162
284
  const bindings: ComponentDataBindingRegistry = {
163
285
  'submit-button': {