@originals/sdk 1.2.0 → 1.4.2

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 (244) hide show
  1. package/package.json +1 -1
  2. package/src/did/DIDManager.ts +1 -1
  3. package/src/did/WebVHManager.ts +11 -2
  4. package/src/examples/create-module-original.ts +435 -0
  5. package/src/examples/full-lifecycle-flow.ts +514 -0
  6. package/src/examples/run.ts +59 -4
  7. package/src/index.ts +69 -3
  8. package/src/kinds/KindRegistry.ts +290 -0
  9. package/src/kinds/index.ts +74 -0
  10. package/src/kinds/types.ts +470 -0
  11. package/src/kinds/validators/AgentValidator.ts +257 -0
  12. package/src/kinds/validators/AppValidator.ts +211 -0
  13. package/src/kinds/validators/DatasetValidator.ts +242 -0
  14. package/src/kinds/validators/DocumentValidator.ts +311 -0
  15. package/src/kinds/validators/MediaValidator.ts +269 -0
  16. package/src/kinds/validators/ModuleValidator.ts +225 -0
  17. package/src/kinds/validators/base.ts +276 -0
  18. package/src/kinds/validators/index.ts +12 -0
  19. package/src/lifecycle/LifecycleManager.ts +909 -1
  20. package/src/resources/ResourceManager.ts +655 -0
  21. package/src/resources/index.ts +21 -0
  22. package/src/resources/types.ts +202 -0
  23. package/src/types/common.ts +1 -1
  24. package/src/vc/CredentialManager.ts +647 -2
  25. package/tests/integration/createTypedOriginal.test.ts +379 -0
  26. package/tests/performance/BatchOperations.perf.test.ts +2 -2
  27. package/tests/unit/kinds/KindRegistry.test.ts +329 -0
  28. package/tests/unit/kinds/types.test.ts +409 -0
  29. package/tests/unit/kinds/validators.test.ts +651 -0
  30. package/tests/unit/lifecycle/LifecycleManager.cleanapi.test.ts +441 -0
  31. package/tests/unit/resources/ResourceManager.test.ts +740 -0
  32. package/tests/unit/vc/CredentialManager.helpers.test.ts +527 -0
  33. package/.turbo/turbo-build.log +0 -1
  34. package/dist/adapters/FeeOracleMock.d.ts +0 -6
  35. package/dist/adapters/FeeOracleMock.js +0 -8
  36. package/dist/adapters/index.d.ts +0 -4
  37. package/dist/adapters/index.js +0 -4
  38. package/dist/adapters/providers/OrdHttpProvider.d.ts +0 -56
  39. package/dist/adapters/providers/OrdHttpProvider.js +0 -110
  40. package/dist/adapters/providers/OrdMockProvider.d.ts +0 -70
  41. package/dist/adapters/providers/OrdMockProvider.js +0 -75
  42. package/dist/adapters/types.d.ts +0 -71
  43. package/dist/adapters/types.js +0 -1
  44. package/dist/bitcoin/BitcoinManager.d.ts +0 -15
  45. package/dist/bitcoin/BitcoinManager.js +0 -262
  46. package/dist/bitcoin/BroadcastClient.d.ts +0 -30
  47. package/dist/bitcoin/BroadcastClient.js +0 -35
  48. package/dist/bitcoin/OrdinalsClient.d.ts +0 -21
  49. package/dist/bitcoin/OrdinalsClient.js +0 -105
  50. package/dist/bitcoin/PSBTBuilder.d.ts +0 -24
  51. package/dist/bitcoin/PSBTBuilder.js +0 -80
  52. package/dist/bitcoin/fee-calculation.d.ts +0 -14
  53. package/dist/bitcoin/fee-calculation.js +0 -31
  54. package/dist/bitcoin/providers/OrdNodeProvider.d.ts +0 -38
  55. package/dist/bitcoin/providers/OrdNodeProvider.js +0 -67
  56. package/dist/bitcoin/providers/OrdinalsProvider.d.ts +0 -33
  57. package/dist/bitcoin/providers/OrdinalsProvider.js +0 -50
  58. package/dist/bitcoin/providers/types.d.ts +0 -63
  59. package/dist/bitcoin/providers/types.js +0 -1
  60. package/dist/bitcoin/transactions/commit.d.ts +0 -89
  61. package/dist/bitcoin/transactions/commit.js +0 -311
  62. package/dist/bitcoin/transactions/index.d.ts +0 -7
  63. package/dist/bitcoin/transactions/index.js +0 -8
  64. package/dist/bitcoin/transfer.d.ts +0 -9
  65. package/dist/bitcoin/transfer.js +0 -26
  66. package/dist/bitcoin/utxo-selection.d.ts +0 -78
  67. package/dist/bitcoin/utxo-selection.js +0 -237
  68. package/dist/bitcoin/utxo.d.ts +0 -26
  69. package/dist/bitcoin/utxo.js +0 -78
  70. package/dist/contexts/credentials-v1.json +0 -195
  71. package/dist/contexts/credentials-v2-examples.json +0 -5
  72. package/dist/contexts/credentials-v2.json +0 -301
  73. package/dist/contexts/credentials.json +0 -195
  74. package/dist/contexts/data-integrity-v2.json +0 -81
  75. package/dist/contexts/dids.json +0 -57
  76. package/dist/contexts/ed255192020.json +0 -93
  77. package/dist/contexts/ordinals-plus.json +0 -23
  78. package/dist/contexts/originals.json +0 -22
  79. package/dist/core/OriginalsSDK.d.ts +0 -158
  80. package/dist/core/OriginalsSDK.js +0 -274
  81. package/dist/crypto/Multikey.d.ts +0 -30
  82. package/dist/crypto/Multikey.js +0 -149
  83. package/dist/crypto/Signer.d.ts +0 -21
  84. package/dist/crypto/Signer.js +0 -196
  85. package/dist/crypto/noble-init.d.ts +0 -18
  86. package/dist/crypto/noble-init.js +0 -106
  87. package/dist/did/BtcoDidResolver.d.ts +0 -57
  88. package/dist/did/BtcoDidResolver.js +0 -166
  89. package/dist/did/DIDManager.d.ts +0 -101
  90. package/dist/did/DIDManager.js +0 -493
  91. package/dist/did/Ed25519Verifier.d.ts +0 -30
  92. package/dist/did/Ed25519Verifier.js +0 -59
  93. package/dist/did/KeyManager.d.ts +0 -17
  94. package/dist/did/KeyManager.js +0 -207
  95. package/dist/did/WebVHManager.d.ts +0 -100
  96. package/dist/did/WebVHManager.js +0 -304
  97. package/dist/did/createBtcoDidDocument.d.ts +0 -10
  98. package/dist/did/createBtcoDidDocument.js +0 -42
  99. package/dist/did/providers/OrdinalsClientProviderAdapter.d.ts +0 -23
  100. package/dist/did/providers/OrdinalsClientProviderAdapter.js +0 -51
  101. package/dist/events/EventEmitter.d.ts +0 -115
  102. package/dist/events/EventEmitter.js +0 -198
  103. package/dist/events/index.d.ts +0 -7
  104. package/dist/events/index.js +0 -6
  105. package/dist/events/types.d.ts +0 -286
  106. package/dist/events/types.js +0 -9
  107. package/dist/examples/basic-usage.d.ts +0 -3
  108. package/dist/examples/basic-usage.js +0 -62
  109. package/dist/examples/run.d.ts +0 -1
  110. package/dist/examples/run.js +0 -4
  111. package/dist/index.d.ts +0 -39
  112. package/dist/index.js +0 -47
  113. package/dist/lifecycle/BatchOperations.d.ts +0 -147
  114. package/dist/lifecycle/BatchOperations.js +0 -251
  115. package/dist/lifecycle/LifecycleManager.d.ts +0 -116
  116. package/dist/lifecycle/LifecycleManager.js +0 -971
  117. package/dist/lifecycle/OriginalsAsset.d.ts +0 -164
  118. package/dist/lifecycle/OriginalsAsset.js +0 -380
  119. package/dist/lifecycle/ProvenanceQuery.d.ts +0 -126
  120. package/dist/lifecycle/ProvenanceQuery.js +0 -220
  121. package/dist/lifecycle/ResourceVersioning.d.ts +0 -73
  122. package/dist/lifecycle/ResourceVersioning.js +0 -127
  123. package/dist/migration/MigrationManager.d.ts +0 -86
  124. package/dist/migration/MigrationManager.js +0 -412
  125. package/dist/migration/audit/AuditLogger.d.ts +0 -51
  126. package/dist/migration/audit/AuditLogger.js +0 -156
  127. package/dist/migration/checkpoint/CheckpointManager.d.ts +0 -31
  128. package/dist/migration/checkpoint/CheckpointManager.js +0 -96
  129. package/dist/migration/checkpoint/CheckpointStorage.d.ts +0 -26
  130. package/dist/migration/checkpoint/CheckpointStorage.js +0 -89
  131. package/dist/migration/index.d.ts +0 -22
  132. package/dist/migration/index.js +0 -27
  133. package/dist/migration/operations/BaseMigration.d.ts +0 -48
  134. package/dist/migration/operations/BaseMigration.js +0 -83
  135. package/dist/migration/operations/PeerToBtcoMigration.d.ts +0 -25
  136. package/dist/migration/operations/PeerToBtcoMigration.js +0 -67
  137. package/dist/migration/operations/PeerToWebvhMigration.d.ts +0 -19
  138. package/dist/migration/operations/PeerToWebvhMigration.js +0 -46
  139. package/dist/migration/operations/WebvhToBtcoMigration.d.ts +0 -25
  140. package/dist/migration/operations/WebvhToBtcoMigration.js +0 -67
  141. package/dist/migration/rollback/RollbackManager.d.ts +0 -29
  142. package/dist/migration/rollback/RollbackManager.js +0 -146
  143. package/dist/migration/state/StateMachine.d.ts +0 -25
  144. package/dist/migration/state/StateMachine.js +0 -76
  145. package/dist/migration/state/StateTracker.d.ts +0 -36
  146. package/dist/migration/state/StateTracker.js +0 -123
  147. package/dist/migration/types.d.ts +0 -306
  148. package/dist/migration/types.js +0 -33
  149. package/dist/migration/validation/BitcoinValidator.d.ts +0 -13
  150. package/dist/migration/validation/BitcoinValidator.js +0 -83
  151. package/dist/migration/validation/CredentialValidator.d.ts +0 -13
  152. package/dist/migration/validation/CredentialValidator.js +0 -46
  153. package/dist/migration/validation/DIDCompatibilityValidator.d.ts +0 -16
  154. package/dist/migration/validation/DIDCompatibilityValidator.js +0 -127
  155. package/dist/migration/validation/LifecycleValidator.d.ts +0 -10
  156. package/dist/migration/validation/LifecycleValidator.js +0 -52
  157. package/dist/migration/validation/StorageValidator.d.ts +0 -10
  158. package/dist/migration/validation/StorageValidator.js +0 -65
  159. package/dist/migration/validation/ValidationPipeline.d.ts +0 -29
  160. package/dist/migration/validation/ValidationPipeline.js +0 -180
  161. package/dist/storage/LocalStorageAdapter.d.ts +0 -11
  162. package/dist/storage/LocalStorageAdapter.js +0 -53
  163. package/dist/storage/MemoryStorageAdapter.d.ts +0 -6
  164. package/dist/storage/MemoryStorageAdapter.js +0 -21
  165. package/dist/storage/StorageAdapter.d.ts +0 -16
  166. package/dist/storage/StorageAdapter.js +0 -1
  167. package/dist/storage/index.d.ts +0 -2
  168. package/dist/storage/index.js +0 -2
  169. package/dist/types/bitcoin.d.ts +0 -84
  170. package/dist/types/bitcoin.js +0 -1
  171. package/dist/types/common.d.ts +0 -82
  172. package/dist/types/common.js +0 -1
  173. package/dist/types/credentials.d.ts +0 -75
  174. package/dist/types/credentials.js +0 -1
  175. package/dist/types/did.d.ts +0 -26
  176. package/dist/types/did.js +0 -1
  177. package/dist/types/index.d.ts +0 -5
  178. package/dist/types/index.js +0 -5
  179. package/dist/types/network.d.ts +0 -78
  180. package/dist/types/network.js +0 -145
  181. package/dist/utils/EventLogger.d.ts +0 -71
  182. package/dist/utils/EventLogger.js +0 -232
  183. package/dist/utils/Logger.d.ts +0 -106
  184. package/dist/utils/Logger.js +0 -257
  185. package/dist/utils/MetricsCollector.d.ts +0 -110
  186. package/dist/utils/MetricsCollector.js +0 -264
  187. package/dist/utils/bitcoin-address.d.ts +0 -38
  188. package/dist/utils/bitcoin-address.js +0 -113
  189. package/dist/utils/cbor.d.ts +0 -2
  190. package/dist/utils/cbor.js +0 -9
  191. package/dist/utils/encoding.d.ts +0 -37
  192. package/dist/utils/encoding.js +0 -120
  193. package/dist/utils/hash.d.ts +0 -1
  194. package/dist/utils/hash.js +0 -5
  195. package/dist/utils/retry.d.ts +0 -10
  196. package/dist/utils/retry.js +0 -35
  197. package/dist/utils/satoshi-validation.d.ts +0 -60
  198. package/dist/utils/satoshi-validation.js +0 -156
  199. package/dist/utils/serialization.d.ts +0 -14
  200. package/dist/utils/serialization.js +0 -76
  201. package/dist/utils/telemetry.d.ts +0 -17
  202. package/dist/utils/telemetry.js +0 -24
  203. package/dist/utils/validation.d.ts +0 -5
  204. package/dist/utils/validation.js +0 -98
  205. package/dist/vc/CredentialManager.d.ts +0 -22
  206. package/dist/vc/CredentialManager.js +0 -227
  207. package/dist/vc/Issuer.d.ts +0 -27
  208. package/dist/vc/Issuer.js +0 -70
  209. package/dist/vc/Verifier.d.ts +0 -16
  210. package/dist/vc/Verifier.js +0 -50
  211. package/dist/vc/cryptosuites/bbs.d.ts +0 -44
  212. package/dist/vc/cryptosuites/bbs.js +0 -213
  213. package/dist/vc/cryptosuites/bbsSimple.d.ts +0 -9
  214. package/dist/vc/cryptosuites/bbsSimple.js +0 -12
  215. package/dist/vc/cryptosuites/eddsa.d.ts +0 -30
  216. package/dist/vc/cryptosuites/eddsa.js +0 -81
  217. package/dist/vc/documentLoader.d.ts +0 -16
  218. package/dist/vc/documentLoader.js +0 -59
  219. package/dist/vc/proofs/data-integrity.d.ts +0 -21
  220. package/dist/vc/proofs/data-integrity.js +0 -15
  221. package/dist/vc/utils/jsonld.d.ts +0 -2
  222. package/dist/vc/utils/jsonld.js +0 -15
  223. package/test/logs/did_webvh_QmNTn9Kkp8dQ75WrF9xqJ2kuDp9QhKc3aPiERRMj8XoTBN_example_com.jsonl +0 -1
  224. package/test/logs/did_webvh_QmNu4MNr8Lr5txx5gYNhuhZDchXsZEu3hJXKYuphpWTPDp_example_com_users_etc_passwd.jsonl +0 -1
  225. package/test/logs/did_webvh_QmR9MrGZACzjKETA8SBRNCKG11HxU85c4bVR2qN5eDCfsD_example_com.jsonl +0 -1
  226. package/test/logs/did_webvh_QmUc5suaqRM2P4nrXxZwqYMfqzhdMqjuL7oJaJbEpCQVCd_example_com_users_etc_passwd.jsonl +0 -1
  227. package/test/logs/did_webvh_QmUkiB2RCV2VZ1RTXsCebWN25Eiy9TLvpzDWAJNjhgvB4X_example_com_etc_passwd.jsonl +0 -1
  228. package/test/logs/did_webvh_QmUoRTe8UMwpAQXZSAW7pjAgZK1tq2X3C6Kfxq3UXGcaGy_example_com_secret.jsonl +0 -1
  229. package/test/logs/did_webvh_QmWWot3chx1t6KwTmcE5i2FeDZ5JMkQw3qXycsKDVmJ9Be_example_com_users_alice.jsonl +0 -1
  230. package/test/logs/did_webvh_QmWvVgALL5kjZdpgR7KZay7J8UiiUr834kkRmWeFAxjAuC_example_com_users_etc_passwd.jsonl +0 -1
  231. package/test/logs/did_webvh_QmWwaRQHUZAFcKihFC6xR6tRTTrQhHPTku6azf1egWbpy1_example_com_users_alice.jsonl +0 -1
  232. package/test/logs/did_webvh_QmXJLtkz23r7AozbtXsZMKWnVU6rd38CkVtjdWuATU3Yp6_example_com_users_alice123_profile.jsonl +0 -1
  233. package/test/logs/did_webvh_QmYsce448po14oDE1wXbyaP6wY9HQgHSKLwdezn1k577SF_example_com_my_org_user_name_test_123.jsonl +0 -1
  234. package/test/logs/did_webvh_QmZBeNzzqajxdfwcDUPZ4P8C5YSXyRztrAwmPiKuKUxmAK_example_com.jsonl +0 -1
  235. package/test/logs/did_webvh_QmZhJsqxizwVbRtqCUkmE6XQunSxtxMt3gbTYadVBNAaEq_example_com.jsonl +0 -1
  236. package/test/logs/did_webvh_QmZk7NHU2D57RzzbMq4tWW9gBa9AqtVTWfiRM6RFdwGVj2_example_com.jsonl +0 -1
  237. package/test/logs/did_webvh_QmZshSXp9w8ovH62zGGBS1b5pGGPsuYiu1VQ935sga2hWF_example_com_level1_level2.jsonl +0 -1
  238. package/test/logs/did_webvh_QmbWAmw7HQL7vKJyCsctZihXf1rmT4sGvggKCPKWcUWjw1_example_com.jsonl +0 -1
  239. package/test/logs/did_webvh_QmbdLUMbYs3juR39TLB6hhrFWLcNg45ybUzeBJCS1MhCh1_example_com_C_Windows_System32.jsonl +0 -1
  240. package/test/logs/did_webvh_QmcaQ1Ma4gkSbae85aCm8Mv4rvdT2Sb2RR3JzYwrm5XBq8_example_com_etc_passwd.jsonl +0 -1
  241. package/test/logs/did_webvh_QmcbA7WQhsBqZSoDpKJHjV8Q5o53h8vmgJhQfo6rqTY5ho_example_com.jsonl +0 -1
  242. package/test/logs/did_webvh_Qmdy8uWr2gkUJrXsThynAug3DASTWwb3onEj89LKmMGZYB_example_com.jsonl +0 -1
  243. package/tests/e2e/README.md +0 -97
  244. package/tests/e2e/example.spec.ts +0 -78
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Tests for KindRegistry
3
+ */
4
+
5
+ import { describe, expect, it, beforeEach } from 'bun:test';
6
+ import {
7
+ OriginalKind,
8
+ KindRegistry,
9
+ type AppManifest,
10
+ type ModuleManifest,
11
+ type ValidationResult,
12
+ BaseKindValidator,
13
+ ValidationUtils,
14
+ type OriginalManifest,
15
+ } from '../../../src/kinds';
16
+
17
+ // Helper to create a minimal valid resource
18
+ const createResource = (id: string, type = 'code', contentType = 'application/javascript') => ({
19
+ id,
20
+ type,
21
+ contentType,
22
+ hash: 'abcdef1234567890',
23
+ });
24
+
25
+ describe('KindRegistry', () => {
26
+ describe('getInstance', () => {
27
+ it('should return a singleton instance', () => {
28
+ const instance1 = KindRegistry.getInstance();
29
+ const instance2 = KindRegistry.getInstance();
30
+
31
+ expect(instance1).toBe(instance2);
32
+ });
33
+
34
+ it('should have all default validators registered', () => {
35
+ const registry = KindRegistry.getInstance();
36
+
37
+ expect(registry.hasKind(OriginalKind.App)).toBe(true);
38
+ expect(registry.hasKind(OriginalKind.Agent)).toBe(true);
39
+ expect(registry.hasKind(OriginalKind.Module)).toBe(true);
40
+ expect(registry.hasKind(OriginalKind.Dataset)).toBe(true);
41
+ expect(registry.hasKind(OriginalKind.Media)).toBe(true);
42
+ expect(registry.hasKind(OriginalKind.Document)).toBe(true);
43
+ });
44
+ });
45
+
46
+ describe('getRegisteredKinds', () => {
47
+ it('should return all registered kinds', () => {
48
+ const registry = KindRegistry.getInstance();
49
+ const kinds = registry.getRegisteredKinds();
50
+
51
+ expect(kinds.length).toBe(6);
52
+ expect(kinds).toContain(OriginalKind.App);
53
+ expect(kinds).toContain(OriginalKind.Agent);
54
+ expect(kinds).toContain(OriginalKind.Module);
55
+ expect(kinds).toContain(OriginalKind.Dataset);
56
+ expect(kinds).toContain(OriginalKind.Media);
57
+ expect(kinds).toContain(OriginalKind.Document);
58
+ });
59
+ });
60
+
61
+ describe('validate', () => {
62
+ it('should validate a valid App manifest', () => {
63
+ const registry = KindRegistry.getInstance();
64
+ const manifest: AppManifest = {
65
+ kind: OriginalKind.App,
66
+ name: 'test-app',
67
+ version: '1.0.0',
68
+ resources: [createResource('index.js')],
69
+ metadata: {
70
+ runtime: 'node',
71
+ entrypoint: 'index.js',
72
+ }
73
+ };
74
+
75
+ const result = registry.validate(manifest);
76
+ expect(result.isValid).toBe(true);
77
+ });
78
+
79
+ it('should fail for missing kind', () => {
80
+ const registry = KindRegistry.getInstance();
81
+ const manifest = {
82
+ name: 'test-app',
83
+ version: '1.0.0',
84
+ resources: [createResource('index.js')],
85
+ } as any;
86
+
87
+ const result = registry.validate(manifest);
88
+ expect(result.isValid).toBe(false);
89
+ expect(result.errors.some(e => e.code === 'MISSING_KIND')).toBe(true);
90
+ });
91
+
92
+ it('should fail for unknown kind', () => {
93
+ const registry = KindRegistry.getInstance();
94
+ const manifest = {
95
+ kind: 'originals:kind:unknown' as any,
96
+ name: 'test',
97
+ version: '1.0.0',
98
+ resources: [createResource('file.js')],
99
+ metadata: {},
100
+ } as any;
101
+
102
+ const result = registry.validate(manifest);
103
+ expect(result.isValid).toBe(false);
104
+ expect(result.errors.some(e => e.code === 'UNKNOWN_KIND')).toBe(true);
105
+ });
106
+
107
+ it('should treat warnings as errors in strict mode', () => {
108
+ const registry = KindRegistry.getInstance();
109
+ const manifest: AppManifest = {
110
+ kind: OriginalKind.App,
111
+ name: 'test-app',
112
+ version: '1.0.0',
113
+ resources: [createResource('index.js')],
114
+ metadata: {
115
+ runtime: 'node',
116
+ entrypoint: 'index.js',
117
+ // No runtimeVersion - will generate warning
118
+ }
119
+ };
120
+
121
+ // Without strict mode - should pass
122
+ const normalResult = registry.validate(manifest);
123
+ expect(normalResult.isValid).toBe(true);
124
+ expect(normalResult.warnings.length).toBeGreaterThan(0);
125
+
126
+ // With strict mode - should fail
127
+ const strictResult = registry.validate(manifest, { strictMode: true });
128
+ expect(strictResult.isValid).toBe(false);
129
+ });
130
+ });
131
+
132
+ describe('validateOrThrow', () => {
133
+ it('should not throw for valid manifest', () => {
134
+ const registry = KindRegistry.getInstance();
135
+ const manifest: ModuleManifest = {
136
+ kind: OriginalKind.Module,
137
+ name: 'test-module',
138
+ version: '1.0.0',
139
+ resources: [createResource('index.js')],
140
+ metadata: {
141
+ format: 'esm',
142
+ main: 'index.js',
143
+ }
144
+ };
145
+
146
+ expect(() => registry.validateOrThrow(manifest)).not.toThrow();
147
+ });
148
+
149
+ it('should throw for invalid manifest', () => {
150
+ const registry = KindRegistry.getInstance();
151
+ const manifest = {
152
+ kind: OriginalKind.Module,
153
+ name: '', // invalid empty name
154
+ version: '1.0.0',
155
+ resources: [createResource('index.js')],
156
+ metadata: {
157
+ format: 'esm',
158
+ main: 'index.js',
159
+ }
160
+ } as ModuleManifest;
161
+
162
+ expect(() => registry.validateOrThrow(manifest)).toThrow('Manifest validation failed');
163
+ });
164
+
165
+ it('should skip validation when skipValidation is true', () => {
166
+ const registry = KindRegistry.getInstance();
167
+ const invalidManifest = {
168
+ kind: OriginalKind.Module,
169
+ name: '', // invalid
170
+ version: 'invalid', // invalid
171
+ resources: [], // invalid
172
+ metadata: {} as any
173
+ } as ModuleManifest;
174
+
175
+ expect(() => registry.validateOrThrow(invalidManifest, { skipValidation: true })).not.toThrow();
176
+ });
177
+ });
178
+
179
+ describe('registerValidator', () => {
180
+ it('should allow registering custom validators', () => {
181
+ const registry = KindRegistry.getInstance();
182
+
183
+ // Create a custom validator
184
+ class CustomAppValidator extends BaseKindValidator<OriginalKind.App> {
185
+ readonly kind = OriginalKind.App;
186
+
187
+ protected validateKind(manifest: OriginalManifest<OriginalKind.App>): ValidationResult {
188
+ // Custom validation that always adds a warning
189
+ return ValidationUtils.success([
190
+ ValidationUtils.warning('CUSTOM_WARNING', 'Custom validator was used')
191
+ ]);
192
+ }
193
+ }
194
+
195
+ // Register the custom validator
196
+ registry.registerValidator(OriginalKind.App, new CustomAppValidator());
197
+
198
+ // Validate a manifest
199
+ const manifest: AppManifest = {
200
+ kind: OriginalKind.App,
201
+ name: 'test-app',
202
+ version: '1.0.0',
203
+ resources: [createResource('index.js')],
204
+ metadata: {
205
+ runtime: 'node',
206
+ entrypoint: 'index.js',
207
+ }
208
+ };
209
+
210
+ const result = registry.validate(manifest);
211
+ expect(result.warnings.some(w => w.code === 'CUSTOM_WARNING')).toBe(true);
212
+ });
213
+ });
214
+
215
+ describe('static helpers', () => {
216
+ describe('isValidKind', () => {
217
+ it('should return true for valid kinds', () => {
218
+ expect(KindRegistry.isValidKind(OriginalKind.App)).toBe(true);
219
+ expect(KindRegistry.isValidKind(OriginalKind.Module)).toBe(true);
220
+ expect(KindRegistry.isValidKind('originals:kind:app')).toBe(true);
221
+ });
222
+
223
+ it('should return false for invalid kinds', () => {
224
+ expect(KindRegistry.isValidKind('invalid')).toBe(false);
225
+ expect(KindRegistry.isValidKind('originals:kind:unknown')).toBe(false);
226
+ expect(KindRegistry.isValidKind(null)).toBe(false);
227
+ expect(KindRegistry.isValidKind(undefined)).toBe(false);
228
+ expect(KindRegistry.isValidKind(123)).toBe(false);
229
+ });
230
+ });
231
+
232
+ describe('parseKind', () => {
233
+ it('should parse full kind URIs', () => {
234
+ expect(KindRegistry.parseKind('originals:kind:app')).toBe(OriginalKind.App);
235
+ expect(KindRegistry.parseKind('originals:kind:module')).toBe(OriginalKind.Module);
236
+ });
237
+
238
+ it('should parse short names', () => {
239
+ expect(KindRegistry.parseKind('app')).toBe(OriginalKind.App);
240
+ expect(KindRegistry.parseKind('module')).toBe(OriginalKind.Module);
241
+ expect(KindRegistry.parseKind('dataset')).toBe(OriginalKind.Dataset);
242
+ expect(KindRegistry.parseKind('agent')).toBe(OriginalKind.Agent);
243
+ expect(KindRegistry.parseKind('media')).toBe(OriginalKind.Media);
244
+ expect(KindRegistry.parseKind('document')).toBe(OriginalKind.Document);
245
+ });
246
+
247
+ it('should be case-insensitive for short names', () => {
248
+ expect(KindRegistry.parseKind('APP')).toBe(OriginalKind.App);
249
+ expect(KindRegistry.parseKind('Module')).toBe(OriginalKind.Module);
250
+ expect(KindRegistry.parseKind('DATASET')).toBe(OriginalKind.Dataset);
251
+ });
252
+
253
+ it('should return null for unknown kinds', () => {
254
+ expect(KindRegistry.parseKind('unknown')).toBe(null);
255
+ expect(KindRegistry.parseKind('')).toBe(null);
256
+ });
257
+ });
258
+
259
+ describe('getShortName', () => {
260
+ it('should extract short name from kind URI', () => {
261
+ expect(KindRegistry.getShortName(OriginalKind.App)).toBe('app');
262
+ expect(KindRegistry.getShortName(OriginalKind.Module)).toBe('module');
263
+ expect(KindRegistry.getShortName(OriginalKind.Dataset)).toBe('dataset');
264
+ });
265
+ });
266
+
267
+ describe('getDisplayName', () => {
268
+ it('should return capitalized display name', () => {
269
+ expect(KindRegistry.getDisplayName(OriginalKind.App)).toBe('App');
270
+ expect(KindRegistry.getDisplayName(OriginalKind.Module)).toBe('Module');
271
+ expect(KindRegistry.getDisplayName(OriginalKind.Dataset)).toBe('Dataset');
272
+ });
273
+ });
274
+
275
+ describe('createTemplate', () => {
276
+ it('should create App template', () => {
277
+ const template = KindRegistry.createTemplate(OriginalKind.App, 'my-app', '1.0.0');
278
+
279
+ expect(template.kind).toBe(OriginalKind.App);
280
+ expect(template.name).toBe('my-app');
281
+ expect(template.version).toBe('1.0.0');
282
+ expect((template.metadata as any)?.runtime).toBe('node');
283
+ expect((template.metadata as any)?.entrypoint).toBe('index.js');
284
+ });
285
+
286
+ it('should create Module template', () => {
287
+ const template = KindRegistry.createTemplate(OriginalKind.Module, 'my-module');
288
+
289
+ expect(template.kind).toBe(OriginalKind.Module);
290
+ expect((template.metadata as any)?.format).toBe('esm');
291
+ expect((template.metadata as any)?.main).toBe('index.js');
292
+ });
293
+
294
+ it('should create Dataset template', () => {
295
+ const template = KindRegistry.createTemplate(OriginalKind.Dataset, 'my-dataset');
296
+
297
+ expect(template.kind).toBe(OriginalKind.Dataset);
298
+ expect((template.metadata as any)?.format).toBe('json');
299
+ });
300
+
301
+ it('should create Agent template', () => {
302
+ const template = KindRegistry.createTemplate(OriginalKind.Agent, 'my-agent');
303
+
304
+ expect(template.kind).toBe(OriginalKind.Agent);
305
+ expect((template.metadata as any)?.capabilities).toEqual([]);
306
+ });
307
+
308
+ it('should create Media template', () => {
309
+ const template = KindRegistry.createTemplate(OriginalKind.Media, 'my-media');
310
+
311
+ expect(template.kind).toBe(OriginalKind.Media);
312
+ expect((template.metadata as any)?.mediaType).toBe('image');
313
+ });
314
+
315
+ it('should create Document template', () => {
316
+ const template = KindRegistry.createTemplate(OriginalKind.Document, 'my-doc');
317
+
318
+ expect(template.kind).toBe(OriginalKind.Document);
319
+ expect((template.metadata as any)?.format).toBe('markdown');
320
+ });
321
+
322
+ it('should use default version if not provided', () => {
323
+ const template = KindRegistry.createTemplate(OriginalKind.App, 'my-app');
324
+ expect(template.version).toBe('1.0.0');
325
+ });
326
+ });
327
+ });
328
+ });
329
+