digital-products 2.1.1 → 2.3.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 (80) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +2 -0
  3. package/dist/api.js +7 -7
  4. package/dist/api.js.map +1 -1
  5. package/dist/app.js +6 -6
  6. package/dist/app.js.map +1 -1
  7. package/dist/client.d.ts +157 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +69 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/content.js +7 -7
  12. package/dist/content.js.map +1 -1
  13. package/dist/data.d.ts.map +1 -1
  14. package/dist/data.js +6 -6
  15. package/dist/data.js.map +1 -1
  16. package/dist/dataset.js +5 -5
  17. package/dist/dataset.js.map +1 -1
  18. package/dist/index.d.ts +92 -13
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +139 -15
  21. package/dist/index.js.map +1 -1
  22. package/dist/mcp.d.ts +1 -1
  23. package/dist/mcp.d.ts.map +1 -1
  24. package/dist/mcp.js +17 -10
  25. package/dist/mcp.js.map +1 -1
  26. package/dist/product.js +2 -2
  27. package/dist/product.js.map +1 -1
  28. package/dist/sdk.d.ts.map +1 -1
  29. package/dist/sdk.js +52 -16
  30. package/dist/sdk.js.map +1 -1
  31. package/dist/site.d.ts.map +1 -1
  32. package/dist/site.js +12 -8
  33. package/dist/site.js.map +1 -1
  34. package/dist/types.d.ts +830 -12
  35. package/dist/types.d.ts.map +1 -1
  36. package/dist/types.js +495 -2
  37. package/dist/types.js.map +1 -1
  38. package/dist/worker.d.ts +205 -0
  39. package/dist/worker.d.ts.map +1 -0
  40. package/dist/worker.js +356 -0
  41. package/dist/worker.js.map +1 -0
  42. package/package.json +20 -4
  43. package/src/api.ts +7 -7
  44. package/src/app.ts +6 -6
  45. package/src/client.ts +192 -0
  46. package/src/content.ts +7 -7
  47. package/src/data.ts +12 -7
  48. package/src/dataset.ts +5 -5
  49. package/src/index.ts +151 -15
  50. package/src/mcp.ts +18 -11
  51. package/src/product.ts +2 -2
  52. package/src/sdk.ts +54 -15
  53. package/src/site.ts +12 -8
  54. package/src/types.ts +821 -12
  55. package/src/worker.ts +525 -0
  56. package/test/product.test.ts +53 -198
  57. package/test/unified-types.test.ts +589 -0
  58. package/test/worker.test.ts +912 -0
  59. package/vitest.config.ts +42 -0
  60. package/wrangler.jsonc +36 -0
  61. package/.turbo/turbo-build.log +0 -5
  62. package/src/api.js +0 -128
  63. package/src/app.js +0 -106
  64. package/src/content.js +0 -77
  65. package/src/data.js +0 -106
  66. package/src/dataset.js +0 -49
  67. package/src/entities/ai.js +0 -858
  68. package/src/entities/content.js +0 -783
  69. package/src/entities/index.js +0 -88
  70. package/src/entities/interfaces.js +0 -929
  71. package/src/entities/lifecycle.js +0 -803
  72. package/src/entities/products.js +0 -797
  73. package/src/entities/web.js +0 -657
  74. package/src/index.js +0 -35
  75. package/src/mcp.js +0 -139
  76. package/src/product.js +0 -53
  77. package/src/registry.js +0 -31
  78. package/src/sdk.js +0 -127
  79. package/src/site.js +0 -112
  80. package/src/types.js +0 -4
@@ -0,0 +1,589 @@
1
+ /**
2
+ * Tests for unified type system consolidation
3
+ *
4
+ * TDD RED PHASE - These tests WILL FAIL because the implementation doesn't exist yet.
5
+ *
6
+ * Goal: Consolidate to ONLY use JSON-LD style with $id, $type and add Zod schemas.
7
+ * The old builder pattern types (id, type) should be rejected.
8
+ *
9
+ * @see https://schema.org.ai/Product
10
+ */
11
+
12
+ import { describe, it, expect } from 'vitest'
13
+ import {
14
+ // Core types (these exist as interfaces but need Zod schemas)
15
+ Product, ProductSchema, isProduct, createProduct,
16
+ App, AppSchema, isApp, createApp,
17
+ API, APISchema, isAPI, createAPI,
18
+ Site, SiteSchema, isSite, createSite,
19
+ // New types to add
20
+ Service, ServiceSchema, isService, createService,
21
+ Feature, FeatureSchema, isFeature, createFeature
22
+ } from '../src/index.js'
23
+
24
+ describe('Unified Product Type', () => {
25
+ const validProduct = {
26
+ $id: 'https://schema.org.ai/products/acme',
27
+ $type: 'https://schema.org.ai/Product' as const,
28
+ name: 'Acme Product',
29
+ description: 'A product',
30
+ status: 'active' as const
31
+ }
32
+
33
+ it('should use $id and $type (JSON-LD style)', () => {
34
+ expect(validProduct.$id).toBeDefined()
35
+ expect(validProduct.$type).toBe('https://schema.org.ai/Product')
36
+ })
37
+
38
+ it('should NOT use plain id and type fields', () => {
39
+ // This should fail - we want to enforce $id/$type
40
+ const oldStyle = { id: 'test', type: 'product', name: 'Test' }
41
+ const result = ProductSchema.safeParse(oldStyle)
42
+ expect(result.success).toBe(false)
43
+ })
44
+
45
+ it('should validate with Zod schema', () => {
46
+ const result = ProductSchema.safeParse(validProduct)
47
+ expect(result.success).toBe(true)
48
+ })
49
+
50
+ it('should reject invalid status', () => {
51
+ const invalid = { ...validProduct, status: 'invalid' }
52
+ const result = ProductSchema.safeParse(invalid)
53
+ expect(result.success).toBe(false)
54
+ })
55
+
56
+ it('isProduct type guard should work', () => {
57
+ expect(isProduct(validProduct)).toBe(true)
58
+ expect(isProduct({ id: 'old-style' })).toBe(false)
59
+ })
60
+
61
+ it('createProduct factory should create valid Product', () => {
62
+ const product = createProduct({
63
+ $id: 'https://schema.org.ai/products/new',
64
+ name: 'New Product',
65
+ description: 'A new product'
66
+ })
67
+ expect(product.$type).toBe('https://schema.org.ai/Product')
68
+ expect(product.status).toBe('active') // default
69
+ expect(isProduct(product)).toBe(true)
70
+ })
71
+ })
72
+
73
+ describe('Unified App Type', () => {
74
+ const validApp = {
75
+ $id: 'https://schema.org.ai/apps/dashboard',
76
+ $type: 'https://schema.org.ai/App' as const,
77
+ name: 'Dashboard',
78
+ description: 'Admin dashboard',
79
+ status: 'active' as const,
80
+ platform: 'web' as const,
81
+ url: 'https://dashboard.example.com'
82
+ }
83
+
84
+ it('should extend Product with $type override', () => {
85
+ expect(validApp.$type).toBe('https://schema.org.ai/App')
86
+ })
87
+
88
+ it('should have platform and url fields', () => {
89
+ expect(validApp.platform).toBeDefined()
90
+ expect(validApp.url).toBeDefined()
91
+ })
92
+
93
+ it('should validate platform enum', () => {
94
+ const platforms = ['web', 'mobile', 'desktop', 'api']
95
+ platforms.forEach(platform => {
96
+ const result = AppSchema.safeParse({ ...validApp, platform })
97
+ expect(result.success).toBe(true)
98
+ })
99
+ })
100
+
101
+ it('should reject invalid platform', () => {
102
+ const result = AppSchema.safeParse({ ...validApp, platform: 'invalid' })
103
+ expect(result.success).toBe(false)
104
+ })
105
+
106
+ it('isApp type guard should work', () => {
107
+ expect(isApp(validApp)).toBe(true)
108
+ expect(isApp({ type: 'app' })).toBe(false) // old style
109
+ })
110
+
111
+ it('createApp factory should work', () => {
112
+ const app = createApp({
113
+ $id: 'https://schema.org.ai/apps/new',
114
+ name: 'New App',
115
+ description: 'A new app',
116
+ platform: 'web',
117
+ url: 'https://new.app'
118
+ })
119
+ expect(app.$type).toBe('https://schema.org.ai/App')
120
+ expect(isApp(app)).toBe(true)
121
+ })
122
+ })
123
+
124
+ describe('Unified API Type', () => {
125
+ const validAPI = {
126
+ $id: 'https://schema.org.ai/apis/v1',
127
+ $type: 'https://schema.org.ai/API' as const,
128
+ name: 'API v1',
129
+ description: 'REST API',
130
+ status: 'active' as const,
131
+ baseUrl: 'https://api.example.com/v1',
132
+ version: '1.0.0',
133
+ authentication: 'bearer' as const
134
+ }
135
+
136
+ it('should extend Product with $type override', () => {
137
+ expect(validAPI.$type).toBe('https://schema.org.ai/API')
138
+ })
139
+
140
+ it('should have baseUrl, version, authentication', () => {
141
+ expect(validAPI.baseUrl).toBeDefined()
142
+ expect(validAPI.version).toBeDefined()
143
+ expect(validAPI.authentication).toBeDefined()
144
+ })
145
+
146
+ it('should validate authentication enum', () => {
147
+ const auths = ['bearer', 'api_key', 'oauth', 'none']
148
+ auths.forEach(auth => {
149
+ const result = APISchema.safeParse({ ...validAPI, authentication: auth })
150
+ expect(result.success).toBe(true)
151
+ })
152
+ })
153
+
154
+ it('isAPI type guard should work', () => {
155
+ expect(isAPI(validAPI)).toBe(true)
156
+ expect(isAPI({ type: 'api' })).toBe(false) // old style
157
+ })
158
+
159
+ it('createAPI factory should work', () => {
160
+ const api = createAPI({
161
+ $id: 'https://schema.org.ai/apis/new',
162
+ name: 'New API',
163
+ description: 'A new API',
164
+ baseUrl: 'https://api.new.com',
165
+ version: '1.0.0',
166
+ authentication: 'bearer'
167
+ })
168
+ expect(api.$type).toBe('https://schema.org.ai/API')
169
+ expect(isAPI(api)).toBe(true)
170
+ })
171
+ })
172
+
173
+ describe('Unified Site Type', () => {
174
+ const validSite = {
175
+ $id: 'https://schema.org.ai/sites/docs',
176
+ $type: 'https://schema.org.ai/Site' as const,
177
+ name: 'Docs',
178
+ description: 'Documentation site',
179
+ status: 'active' as const,
180
+ url: 'https://docs.example.com',
181
+ siteType: 'docs' as const
182
+ }
183
+
184
+ it('should extend Product with $type override', () => {
185
+ expect(validSite.$type).toBe('https://schema.org.ai/Site')
186
+ })
187
+
188
+ it('should have url and siteType', () => {
189
+ expect(validSite.url).toBeDefined()
190
+ expect(validSite.siteType).toBeDefined()
191
+ })
192
+
193
+ it('should validate siteType enum', () => {
194
+ const types = ['marketing', 'docs', 'blog', 'app']
195
+ types.forEach(siteType => {
196
+ const result = SiteSchema.safeParse({ ...validSite, siteType })
197
+ expect(result.success).toBe(true)
198
+ })
199
+ })
200
+
201
+ it('isSite type guard should work', () => {
202
+ expect(isSite(validSite)).toBe(true)
203
+ })
204
+
205
+ it('createSite factory should work', () => {
206
+ const site = createSite({
207
+ $id: 'https://schema.org.ai/sites/new',
208
+ name: 'New Site',
209
+ description: 'A new site',
210
+ url: 'https://new.site',
211
+ siteType: 'marketing'
212
+ })
213
+ expect(site.$type).toBe('https://schema.org.ai/Site')
214
+ expect(isSite(site)).toBe(true)
215
+ })
216
+ })
217
+
218
+ describe('Service Type', () => {
219
+ const validService = {
220
+ $id: 'https://schema.org.ai/services/auth',
221
+ $type: 'https://schema.org.ai/Service' as const,
222
+ name: 'Auth Service',
223
+ description: 'Authentication service',
224
+ status: 'active' as const,
225
+ endpoints: ['/login', '/logout', '/refresh']
226
+ }
227
+
228
+ it('should have $id, $type, name, description', () => {
229
+ expect(validService.$id).toBeDefined()
230
+ expect(validService.$type).toBe('https://schema.org.ai/Service')
231
+ })
232
+
233
+ it('should validate with Zod schema', () => {
234
+ const result = ServiceSchema.safeParse(validService)
235
+ expect(result.success).toBe(true)
236
+ })
237
+
238
+ it('endpoints should be optional', () => {
239
+ const noEndpoints = { ...validService, endpoints: undefined }
240
+ const result = ServiceSchema.safeParse(noEndpoints)
241
+ expect(result.success).toBe(true)
242
+ })
243
+
244
+ it('isService type guard should work', () => {
245
+ expect(isService(validService)).toBe(true)
246
+ })
247
+
248
+ it('createService factory should work', () => {
249
+ const service = createService({
250
+ $id: 'https://schema.org.ai/services/new',
251
+ name: 'New Service',
252
+ description: 'A new service'
253
+ })
254
+ expect(service.$type).toBe('https://schema.org.ai/Service')
255
+ expect(isService(service)).toBe(true)
256
+ })
257
+ })
258
+
259
+ describe('Feature Type', () => {
260
+ const validFeature = {
261
+ $id: 'https://schema.org.ai/features/dark-mode',
262
+ $type: 'https://schema.org.ai/Feature' as const,
263
+ name: 'Dark Mode',
264
+ description: 'Toggle dark theme',
265
+ productId: 'https://schema.org.ai/products/dashboard',
266
+ status: 'ga' as const
267
+ }
268
+
269
+ it('should have $id, $type, name, description', () => {
270
+ expect(validFeature.$id).toBeDefined()
271
+ expect(validFeature.$type).toBe('https://schema.org.ai/Feature')
272
+ })
273
+
274
+ it('should reference productId', () => {
275
+ expect(validFeature.productId).toBeDefined()
276
+ })
277
+
278
+ it('status should be: draft, beta, ga, deprecated', () => {
279
+ const statuses = ['draft', 'beta', 'ga', 'deprecated']
280
+ statuses.forEach(status => {
281
+ const result = FeatureSchema.safeParse({ ...validFeature, status })
282
+ expect(result.success).toBe(true)
283
+ })
284
+ })
285
+
286
+ it('isFeature type guard should work', () => {
287
+ expect(isFeature(validFeature)).toBe(true)
288
+ })
289
+
290
+ it('createFeature factory should work', () => {
291
+ const feature = createFeature({
292
+ $id: 'https://schema.org.ai/features/new',
293
+ name: 'New Feature',
294
+ description: 'A new feature',
295
+ productId: 'https://schema.org.ai/products/main'
296
+ })
297
+ expect(feature.$type).toBe('https://schema.org.ai/Feature')
298
+ expect(feature.status).toBe('draft') // default
299
+ expect(isFeature(feature)).toBe(true)
300
+ })
301
+ })
302
+
303
+ // Test coverage for existing Definition types - ensure old style is rejected
304
+ describe('Type Coverage - Consolidation', () => {
305
+ it('AppDefinition should be replaced by App with Zod', () => {
306
+ // Old style should not work
307
+ const oldStyle = {
308
+ id: 'app-1',
309
+ type: 'app',
310
+ name: 'Old Style App',
311
+ description: 'Uses old pattern',
312
+ version: '1.0.0'
313
+ }
314
+ const result = AppSchema.safeParse(oldStyle)
315
+ expect(result.success).toBe(false)
316
+ })
317
+
318
+ it('APIDefinition should be replaced by API with Zod', () => {
319
+ const oldStyle = {
320
+ id: 'api-1',
321
+ type: 'api',
322
+ name: 'Old Style API',
323
+ description: 'Uses old pattern',
324
+ version: '1.0.0'
325
+ }
326
+ const result = APISchema.safeParse(oldStyle)
327
+ expect(result.success).toBe(false)
328
+ })
329
+
330
+ it('SiteDefinition should be replaced by Site with Zod', () => {
331
+ const oldStyle = {
332
+ id: 'site-1',
333
+ type: 'site',
334
+ name: 'Old Style Site',
335
+ description: 'Uses old pattern',
336
+ version: '1.0.0'
337
+ }
338
+ const result = SiteSchema.safeParse(oldStyle)
339
+ expect(result.success).toBe(false)
340
+ })
341
+
342
+ it('DigitalProduct base type should be deprecated', () => {
343
+ // Old DigitalProduct uses id/name/description/version/status
344
+ // New Product uses $id/$type/name/description/status
345
+ const oldDigitalProduct = {
346
+ id: 'dp-1',
347
+ name: 'Old',
348
+ description: 'Old style',
349
+ version: '1.0.0',
350
+ status: 'active'
351
+ }
352
+ const result = ProductSchema.safeParse(oldDigitalProduct)
353
+ expect(result.success).toBe(false)
354
+ })
355
+ })
356
+
357
+ // Schema validation edge cases
358
+ describe('Schema Validation Edge Cases', () => {
359
+ describe('ProductSchema', () => {
360
+ it('should require $id', () => {
361
+ const missing = {
362
+ $type: 'https://schema.org.ai/Product' as const,
363
+ name: 'Test',
364
+ description: 'Test',
365
+ status: 'active' as const
366
+ }
367
+ const result = ProductSchema.safeParse(missing)
368
+ expect(result.success).toBe(false)
369
+ })
370
+
371
+ it('should require $type', () => {
372
+ const missing = {
373
+ $id: 'https://schema.org.ai/products/test',
374
+ name: 'Test',
375
+ description: 'Test',
376
+ status: 'active' as const
377
+ }
378
+ const result = ProductSchema.safeParse(missing)
379
+ expect(result.success).toBe(false)
380
+ })
381
+
382
+ it('should require name', () => {
383
+ const missing = {
384
+ $id: 'https://schema.org.ai/products/test',
385
+ $type: 'https://schema.org.ai/Product' as const,
386
+ description: 'Test',
387
+ status: 'active' as const
388
+ }
389
+ const result = ProductSchema.safeParse(missing)
390
+ expect(result.success).toBe(false)
391
+ })
392
+
393
+ it('should require description', () => {
394
+ const missing = {
395
+ $id: 'https://schema.org.ai/products/test',
396
+ $type: 'https://schema.org.ai/Product' as const,
397
+ name: 'Test',
398
+ status: 'active' as const
399
+ }
400
+ const result = ProductSchema.safeParse(missing)
401
+ expect(result.success).toBe(false)
402
+ })
403
+
404
+ it('should require status', () => {
405
+ const missing = {
406
+ $id: 'https://schema.org.ai/products/test',
407
+ $type: 'https://schema.org.ai/Product' as const,
408
+ name: 'Test',
409
+ description: 'Test'
410
+ }
411
+ const result = ProductSchema.safeParse(missing)
412
+ expect(result.success).toBe(false)
413
+ })
414
+ })
415
+
416
+ describe('AppSchema', () => {
417
+ it('should require platform', () => {
418
+ const missing = {
419
+ $id: 'https://schema.org.ai/apps/test',
420
+ $type: 'https://schema.org.ai/App' as const,
421
+ name: 'Test',
422
+ description: 'Test',
423
+ status: 'active' as const,
424
+ url: 'https://test.com'
425
+ }
426
+ const result = AppSchema.safeParse(missing)
427
+ expect(result.success).toBe(false)
428
+ })
429
+
430
+ it('should require url', () => {
431
+ const missing = {
432
+ $id: 'https://schema.org.ai/apps/test',
433
+ $type: 'https://schema.org.ai/App' as const,
434
+ name: 'Test',
435
+ description: 'Test',
436
+ status: 'active' as const,
437
+ platform: 'web' as const
438
+ }
439
+ const result = AppSchema.safeParse(missing)
440
+ expect(result.success).toBe(false)
441
+ })
442
+ })
443
+
444
+ describe('APISchema', () => {
445
+ it('should require baseUrl', () => {
446
+ const missing = {
447
+ $id: 'https://schema.org.ai/apis/test',
448
+ $type: 'https://schema.org.ai/API' as const,
449
+ name: 'Test',
450
+ description: 'Test',
451
+ status: 'active' as const,
452
+ version: '1.0.0',
453
+ authentication: 'bearer' as const
454
+ }
455
+ const result = APISchema.safeParse(missing)
456
+ expect(result.success).toBe(false)
457
+ })
458
+
459
+ it('should require version', () => {
460
+ const missing = {
461
+ $id: 'https://schema.org.ai/apis/test',
462
+ $type: 'https://schema.org.ai/API' as const,
463
+ name: 'Test',
464
+ description: 'Test',
465
+ status: 'active' as const,
466
+ baseUrl: 'https://api.test.com',
467
+ authentication: 'bearer' as const
468
+ }
469
+ const result = APISchema.safeParse(missing)
470
+ expect(result.success).toBe(false)
471
+ })
472
+
473
+ it('should require authentication', () => {
474
+ const missing = {
475
+ $id: 'https://schema.org.ai/apis/test',
476
+ $type: 'https://schema.org.ai/API' as const,
477
+ name: 'Test',
478
+ description: 'Test',
479
+ status: 'active' as const,
480
+ baseUrl: 'https://api.test.com',
481
+ version: '1.0.0'
482
+ }
483
+ const result = APISchema.safeParse(missing)
484
+ expect(result.success).toBe(false)
485
+ })
486
+ })
487
+
488
+ describe('SiteSchema', () => {
489
+ it('should require url', () => {
490
+ const missing = {
491
+ $id: 'https://schema.org.ai/sites/test',
492
+ $type: 'https://schema.org.ai/Site' as const,
493
+ name: 'Test',
494
+ description: 'Test',
495
+ status: 'active' as const,
496
+ siteType: 'docs' as const
497
+ }
498
+ const result = SiteSchema.safeParse(missing)
499
+ expect(result.success).toBe(false)
500
+ })
501
+
502
+ it('should require siteType', () => {
503
+ const missing = {
504
+ $id: 'https://schema.org.ai/sites/test',
505
+ $type: 'https://schema.org.ai/Site' as const,
506
+ name: 'Test',
507
+ description: 'Test',
508
+ status: 'active' as const,
509
+ url: 'https://test.com'
510
+ }
511
+ const result = SiteSchema.safeParse(missing)
512
+ expect(result.success).toBe(false)
513
+ })
514
+ })
515
+
516
+ describe('ServiceSchema', () => {
517
+ it('should allow empty endpoints array', () => {
518
+ const withEmpty = {
519
+ $id: 'https://schema.org.ai/services/test',
520
+ $type: 'https://schema.org.ai/Service' as const,
521
+ name: 'Test',
522
+ description: 'Test',
523
+ status: 'active' as const,
524
+ endpoints: []
525
+ }
526
+ const result = ServiceSchema.safeParse(withEmpty)
527
+ expect(result.success).toBe(true)
528
+ })
529
+ })
530
+
531
+ describe('FeatureSchema', () => {
532
+ it('should require productId', () => {
533
+ const missing = {
534
+ $id: 'https://schema.org.ai/features/test',
535
+ $type: 'https://schema.org.ai/Feature' as const,
536
+ name: 'Test',
537
+ description: 'Test',
538
+ status: 'draft' as const
539
+ }
540
+ const result = FeatureSchema.safeParse(missing)
541
+ expect(result.success).toBe(false)
542
+ })
543
+
544
+ it('should validate feature status enum', () => {
545
+ const invalidStatus = {
546
+ $id: 'https://schema.org.ai/features/test',
547
+ $type: 'https://schema.org.ai/Feature' as const,
548
+ name: 'Test',
549
+ description: 'Test',
550
+ productId: 'https://schema.org.ai/products/main',
551
+ status: 'active' // 'active' is not valid for Feature - should be draft/beta/ga/deprecated
552
+ }
553
+ const result = FeatureSchema.safeParse(invalidStatus)
554
+ expect(result.success).toBe(false)
555
+ })
556
+ })
557
+ })
558
+
559
+ // Type inference tests - ensure Zod infers correct TypeScript types
560
+ describe('Type Inference', () => {
561
+ it('ProductSchema.parse should return Product type', () => {
562
+ const input = {
563
+ $id: 'https://schema.org.ai/products/test',
564
+ $type: 'https://schema.org.ai/Product' as const,
565
+ name: 'Test',
566
+ description: 'Test',
567
+ status: 'active' as const
568
+ }
569
+ const result = ProductSchema.parse(input)
570
+ // TypeScript should infer result as Product type
571
+ const _typeCheck: typeof result.$type = 'https://schema.org.ai/Product'
572
+ expect(result.$type).toBe('https://schema.org.ai/Product')
573
+ })
574
+
575
+ it('AppSchema.parse should return App type', () => {
576
+ const input = {
577
+ $id: 'https://schema.org.ai/apps/test',
578
+ $type: 'https://schema.org.ai/App' as const,
579
+ name: 'Test',
580
+ description: 'Test',
581
+ status: 'active' as const,
582
+ platform: 'web' as const,
583
+ url: 'https://test.com'
584
+ }
585
+ const result = AppSchema.parse(input)
586
+ const _typeCheck: typeof result.$type = 'https://schema.org.ai/App'
587
+ expect(result.$type).toBe('https://schema.org.ai/App')
588
+ })
589
+ })