@originals/sdk 1.4.2 → 1.4.3

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 (212) hide show
  1. package/package.json +4 -1
  2. package/.eslintrc.json +0 -33
  3. package/src/adapters/FeeOracleMock.ts +0 -9
  4. package/src/adapters/index.ts +0 -5
  5. package/src/adapters/providers/OrdHttpProvider.ts +0 -126
  6. package/src/adapters/providers/OrdMockProvider.ts +0 -101
  7. package/src/adapters/types.ts +0 -66
  8. package/src/bitcoin/BitcoinManager.ts +0 -330
  9. package/src/bitcoin/BroadcastClient.ts +0 -54
  10. package/src/bitcoin/OrdinalsClient.ts +0 -119
  11. package/src/bitcoin/PSBTBuilder.ts +0 -106
  12. package/src/bitcoin/fee-calculation.ts +0 -38
  13. package/src/bitcoin/providers/OrdNodeProvider.ts +0 -92
  14. package/src/bitcoin/providers/OrdinalsProvider.ts +0 -56
  15. package/src/bitcoin/providers/types.ts +0 -59
  16. package/src/bitcoin/transactions/commit.ts +0 -465
  17. package/src/bitcoin/transactions/index.ts +0 -13
  18. package/src/bitcoin/transfer.ts +0 -43
  19. package/src/bitcoin/utxo-selection.ts +0 -322
  20. package/src/bitcoin/utxo.ts +0 -113
  21. package/src/contexts/credentials-v1.json +0 -237
  22. package/src/contexts/credentials-v2-examples.json +0 -5
  23. package/src/contexts/credentials-v2.json +0 -340
  24. package/src/contexts/credentials.json +0 -237
  25. package/src/contexts/data-integrity-v2.json +0 -81
  26. package/src/contexts/dids.json +0 -58
  27. package/src/contexts/ed255192020.json +0 -93
  28. package/src/contexts/ordinals-plus.json +0 -23
  29. package/src/contexts/originals.json +0 -22
  30. package/src/core/OriginalsSDK.ts +0 -416
  31. package/src/crypto/Multikey.ts +0 -194
  32. package/src/crypto/Signer.ts +0 -254
  33. package/src/crypto/noble-init.ts +0 -121
  34. package/src/did/BtcoDidResolver.ts +0 -227
  35. package/src/did/DIDManager.ts +0 -694
  36. package/src/did/Ed25519Verifier.ts +0 -68
  37. package/src/did/KeyManager.ts +0 -236
  38. package/src/did/WebVHManager.ts +0 -498
  39. package/src/did/createBtcoDidDocument.ts +0 -59
  40. package/src/did/providers/OrdinalsClientProviderAdapter.ts +0 -68
  41. package/src/events/EventEmitter.ts +0 -222
  42. package/src/events/index.ts +0 -19
  43. package/src/events/types.ts +0 -331
  44. package/src/examples/basic-usage.ts +0 -78
  45. package/src/examples/create-module-original.ts +0 -435
  46. package/src/examples/full-lifecycle-flow.ts +0 -514
  47. package/src/examples/run.ts +0 -60
  48. package/src/index.ts +0 -150
  49. package/src/kinds/KindRegistry.ts +0 -290
  50. package/src/kinds/index.ts +0 -74
  51. package/src/kinds/types.ts +0 -470
  52. package/src/kinds/validators/AgentValidator.ts +0 -257
  53. package/src/kinds/validators/AppValidator.ts +0 -211
  54. package/src/kinds/validators/DatasetValidator.ts +0 -242
  55. package/src/kinds/validators/DocumentValidator.ts +0 -311
  56. package/src/kinds/validators/MediaValidator.ts +0 -269
  57. package/src/kinds/validators/ModuleValidator.ts +0 -225
  58. package/src/kinds/validators/base.ts +0 -276
  59. package/src/kinds/validators/index.ts +0 -12
  60. package/src/lifecycle/BatchOperations.ts +0 -373
  61. package/src/lifecycle/LifecycleManager.ts +0 -2126
  62. package/src/lifecycle/OriginalsAsset.ts +0 -524
  63. package/src/lifecycle/ProvenanceQuery.ts +0 -280
  64. package/src/lifecycle/ResourceVersioning.ts +0 -163
  65. package/src/migration/MigrationManager.ts +0 -527
  66. package/src/migration/audit/AuditLogger.ts +0 -176
  67. package/src/migration/checkpoint/CheckpointManager.ts +0 -112
  68. package/src/migration/checkpoint/CheckpointStorage.ts +0 -101
  69. package/src/migration/index.ts +0 -33
  70. package/src/migration/operations/BaseMigration.ts +0 -126
  71. package/src/migration/operations/PeerToBtcoMigration.ts +0 -105
  72. package/src/migration/operations/PeerToWebvhMigration.ts +0 -62
  73. package/src/migration/operations/WebvhToBtcoMigration.ts +0 -105
  74. package/src/migration/rollback/RollbackManager.ts +0 -170
  75. package/src/migration/state/StateMachine.ts +0 -92
  76. package/src/migration/state/StateTracker.ts +0 -156
  77. package/src/migration/types.ts +0 -344
  78. package/src/migration/validation/BitcoinValidator.ts +0 -107
  79. package/src/migration/validation/CredentialValidator.ts +0 -62
  80. package/src/migration/validation/DIDCompatibilityValidator.ts +0 -151
  81. package/src/migration/validation/LifecycleValidator.ts +0 -64
  82. package/src/migration/validation/StorageValidator.ts +0 -79
  83. package/src/migration/validation/ValidationPipeline.ts +0 -213
  84. package/src/resources/ResourceManager.ts +0 -655
  85. package/src/resources/index.ts +0 -21
  86. package/src/resources/types.ts +0 -202
  87. package/src/storage/LocalStorageAdapter.ts +0 -61
  88. package/src/storage/MemoryStorageAdapter.ts +0 -29
  89. package/src/storage/StorageAdapter.ts +0 -25
  90. package/src/storage/index.ts +0 -3
  91. package/src/types/bitcoin.ts +0 -98
  92. package/src/types/common.ts +0 -92
  93. package/src/types/credentials.ts +0 -88
  94. package/src/types/did.ts +0 -31
  95. package/src/types/external-shims.d.ts +0 -53
  96. package/src/types/index.ts +0 -7
  97. package/src/types/network.ts +0 -175
  98. package/src/utils/EventLogger.ts +0 -298
  99. package/src/utils/Logger.ts +0 -322
  100. package/src/utils/MetricsCollector.ts +0 -358
  101. package/src/utils/bitcoin-address.ts +0 -130
  102. package/src/utils/cbor.ts +0 -12
  103. package/src/utils/encoding.ts +0 -127
  104. package/src/utils/hash.ts +0 -6
  105. package/src/utils/retry.ts +0 -46
  106. package/src/utils/satoshi-validation.ts +0 -196
  107. package/src/utils/serialization.ts +0 -96
  108. package/src/utils/telemetry.ts +0 -40
  109. package/src/utils/validation.ts +0 -119
  110. package/src/vc/CredentialManager.ts +0 -918
  111. package/src/vc/Issuer.ts +0 -100
  112. package/src/vc/Verifier.ts +0 -47
  113. package/src/vc/cryptosuites/bbs.ts +0 -253
  114. package/src/vc/cryptosuites/bbsSimple.ts +0 -21
  115. package/src/vc/cryptosuites/eddsa.ts +0 -99
  116. package/src/vc/documentLoader.ts +0 -67
  117. package/src/vc/proofs/data-integrity.ts +0 -33
  118. package/src/vc/utils/jsonld.ts +0 -18
  119. package/tests/__mocks__/bbs-signatures.js +0 -17
  120. package/tests/__mocks__/mf-base58.js +0 -24
  121. package/tests/fixtures/did-documents.ts +0 -247
  122. package/tests/index.test.ts +0 -21
  123. package/tests/integration/BatchOperations.test.ts +0 -531
  124. package/tests/integration/CompleteLifecycle.e2e.test.ts +0 -735
  125. package/tests/integration/CredentialManager.test.ts +0 -42
  126. package/tests/integration/DIDManager.test.ts +0 -41
  127. package/tests/integration/DidPeerToWebVhFlow.test.ts +0 -351
  128. package/tests/integration/Events.test.ts +0 -435
  129. package/tests/integration/Lifecycle.transfer.btco.integration.test.ts +0 -25
  130. package/tests/integration/LifecycleManager.test.ts +0 -21
  131. package/tests/integration/MultikeyFlow.test.ts +0 -52
  132. package/tests/integration/TelemetryIntegration.test.ts +0 -395
  133. package/tests/integration/WebVhPublish.test.ts +0 -48
  134. package/tests/integration/createTypedOriginal.test.ts +0 -379
  135. package/tests/integration/migration/peer-to-webvh.test.ts +0 -172
  136. package/tests/manual/test-commit-creation.ts +0 -323
  137. package/tests/mocks/MockKeyStore.ts +0 -38
  138. package/tests/mocks/adapters/MemoryStorageAdapter.ts +0 -24
  139. package/tests/mocks/adapters/MockFeeOracle.ts +0 -11
  140. package/tests/mocks/adapters/MockOrdinalsProvider.ts +0 -76
  141. package/tests/mocks/adapters/OrdMockProvider.test.ts +0 -176
  142. package/tests/mocks/adapters/index.ts +0 -6
  143. package/tests/performance/BatchOperations.perf.test.ts +0 -403
  144. package/tests/performance/logging.perf.test.ts +0 -336
  145. package/tests/sdk.test.ts +0 -43
  146. package/tests/security/bitcoin-penetration-tests.test.ts +0 -622
  147. package/tests/setup.bun.ts +0 -69
  148. package/tests/setup.jest.ts +0 -23
  149. package/tests/stress/batch-operations-stress.test.ts +0 -571
  150. package/tests/unit/adapters/FeeOracleMock.test.ts +0 -40
  151. package/tests/unit/bitcoin/BitcoinManager.test.ts +0 -293
  152. package/tests/unit/bitcoin/BroadcastClient.test.ts +0 -52
  153. package/tests/unit/bitcoin/OrdNodeProvider.test.ts +0 -53
  154. package/tests/unit/bitcoin/OrdinalsClient.test.ts +0 -381
  155. package/tests/unit/bitcoin/OrdinalsClientProvider.test.ts +0 -102
  156. package/tests/unit/bitcoin/PSBTBuilder.test.ts +0 -84
  157. package/tests/unit/bitcoin/fee-calculation.test.ts +0 -261
  158. package/tests/unit/bitcoin/transactions/commit.test.ts +0 -649
  159. package/tests/unit/bitcoin/transfer.test.ts +0 -31
  160. package/tests/unit/bitcoin/utxo-selection-new.test.ts +0 -502
  161. package/tests/unit/bitcoin/utxo.more.test.ts +0 -39
  162. package/tests/unit/bitcoin/utxo.selection.test.ts +0 -38
  163. package/tests/unit/core/OriginalsSDK.test.ts +0 -152
  164. package/tests/unit/crypto/Multikey.test.ts +0 -206
  165. package/tests/unit/crypto/Signer.test.ts +0 -408
  166. package/tests/unit/did/BtcoDidResolver.test.ts +0 -611
  167. package/tests/unit/did/DIDManager.more.test.ts +0 -43
  168. package/tests/unit/did/DIDManager.test.ts +0 -185
  169. package/tests/unit/did/Ed25519Verifier.test.ts +0 -160
  170. package/tests/unit/did/KeyManager.test.ts +0 -452
  171. package/tests/unit/did/OrdinalsClientProviderAdapter.test.ts +0 -45
  172. package/tests/unit/did/WebVHManager.test.ts +0 -435
  173. package/tests/unit/did/createBtcoDidDocument.test.ts +0 -67
  174. package/tests/unit/did/providers/OrdinalsClientProviderAdapter.test.ts +0 -159
  175. package/tests/unit/events/EventEmitter.test.ts +0 -407
  176. package/tests/unit/kinds/KindRegistry.test.ts +0 -329
  177. package/tests/unit/kinds/types.test.ts +0 -409
  178. package/tests/unit/kinds/validators.test.ts +0 -651
  179. package/tests/unit/lifecycle/BatchOperations.test.ts +0 -527
  180. package/tests/unit/lifecycle/LifecycleManager.cleanapi.test.ts +0 -441
  181. package/tests/unit/lifecycle/LifecycleManager.keymanagement.test.ts +0 -312
  182. package/tests/unit/lifecycle/LifecycleManager.prov.test.ts +0 -18
  183. package/tests/unit/lifecycle/LifecycleManager.test.ts +0 -213
  184. package/tests/unit/lifecycle/LifecycleManager.transfer.unit.test.ts +0 -30
  185. package/tests/unit/lifecycle/OriginalsAsset.test.ts +0 -176
  186. package/tests/unit/lifecycle/ProvenanceQuery.test.ts +0 -577
  187. package/tests/unit/lifecycle/ResourceVersioning.test.ts +0 -651
  188. package/tests/unit/resources/ResourceManager.test.ts +0 -740
  189. package/tests/unit/storage/MemoryStorageAdapter.test.ts +0 -93
  190. package/tests/unit/types/network.test.ts +0 -255
  191. package/tests/unit/utils/EventIntegration.test.ts +0 -384
  192. package/tests/unit/utils/Logger.test.ts +0 -473
  193. package/tests/unit/utils/MetricsCollector.test.ts +0 -358
  194. package/tests/unit/utils/bitcoin-address.test.ts +0 -250
  195. package/tests/unit/utils/cbor.test.ts +0 -35
  196. package/tests/unit/utils/encoding.test.ts +0 -318
  197. package/tests/unit/utils/hash.test.ts +0 -12
  198. package/tests/unit/utils/retry.test.ts +0 -100
  199. package/tests/unit/utils/satoshi-validation.test.ts +0 -354
  200. package/tests/unit/utils/serialization.test.ts +0 -124
  201. package/tests/unit/utils/telemetry.test.ts +0 -52
  202. package/tests/unit/utils/validation.test.ts +0 -141
  203. package/tests/unit/vc/CredentialManager.helpers.test.ts +0 -527
  204. package/tests/unit/vc/CredentialManager.test.ts +0 -487
  205. package/tests/unit/vc/Issuer.test.ts +0 -107
  206. package/tests/unit/vc/Verifier.test.ts +0 -525
  207. package/tests/unit/vc/bbs.test.ts +0 -282
  208. package/tests/unit/vc/cryptosuites/eddsa.test.ts +0 -398
  209. package/tests/unit/vc/documentLoader.test.ts +0 -121
  210. package/tests/unit/vc/proofs/data-integrity.test.ts +0 -24
  211. package/tsconfig.json +0 -31
  212. package/tsconfig.test.json +0 -15
@@ -1,211 +0,0 @@
1
- /**
2
- * App Kind Validator
3
- *
4
- * Validates manifests for executable applications with runtime and entrypoint.
5
- */
6
-
7
- import { OriginalKind, type OriginalManifest, type ValidationResult, type AppMetadata } from '../types';
8
- import { BaseKindValidator, ValidationUtils } from './base';
9
-
10
- /**
11
- * Valid runtime environments
12
- */
13
- const VALID_RUNTIMES = [
14
- 'node', 'deno', 'bun', 'browser', 'electron',
15
- 'react-native', 'python', 'ruby', 'go', 'rust',
16
- 'java', 'dotnet', 'wasm',
17
- ];
18
-
19
- /**
20
- * Valid platforms
21
- */
22
- const VALID_PLATFORMS = ['linux', 'darwin', 'windows', 'web'];
23
-
24
- /**
25
- * Validator for App Originals
26
- */
27
- export class AppValidator extends BaseKindValidator<OriginalKind.App> {
28
- readonly kind = OriginalKind.App;
29
-
30
- protected validateKind(manifest: OriginalManifest<OriginalKind.App>): ValidationResult {
31
- const errors: ValidationResult['errors'] = [];
32
- const warnings: ValidationResult['warnings'] = [];
33
- const metadata = manifest.metadata as AppMetadata;
34
-
35
- // Validate metadata exists
36
- if (!metadata || typeof metadata !== 'object') {
37
- return ValidationUtils.failure([
38
- ValidationUtils.error('MISSING_METADATA', 'App manifest must have metadata', 'metadata'),
39
- ]);
40
- }
41
-
42
- // Validate runtime (required)
43
- if (!metadata.runtime || typeof metadata.runtime !== 'string') {
44
- errors.push(ValidationUtils.error(
45
- 'MISSING_RUNTIME',
46
- 'App must specify a runtime environment',
47
- 'metadata.runtime',
48
- ));
49
- } else if (!VALID_RUNTIMES.includes(metadata.runtime.toLowerCase())) {
50
- warnings.push(ValidationUtils.warning(
51
- 'UNKNOWN_RUNTIME',
52
- `Runtime "${metadata.runtime}" is not a commonly recognized runtime`,
53
- 'metadata.runtime',
54
- `Consider using one of: ${VALID_RUNTIMES.join(', ')}`,
55
- ));
56
- }
57
-
58
- // Validate entrypoint (required)
59
- if (!metadata.entrypoint || typeof metadata.entrypoint !== 'string') {
60
- errors.push(ValidationUtils.error(
61
- 'MISSING_ENTRYPOINT',
62
- 'App must specify an entrypoint',
63
- 'metadata.entrypoint',
64
- ));
65
- } else {
66
- // Check if entrypoint references an existing resource
67
- if (!ValidationUtils.resourceExists(metadata.entrypoint, manifest.resources)) {
68
- // It might be a path within a resource, so just warn
69
- warnings.push(ValidationUtils.warning(
70
- 'ENTRYPOINT_NOT_RESOURCE',
71
- `Entrypoint "${metadata.entrypoint}" does not match a resource ID`,
72
- 'metadata.entrypoint',
73
- 'Ensure the entrypoint is a valid resource ID or path within a resource',
74
- ));
75
- }
76
- }
77
-
78
- // Validate platforms if specified
79
- if (metadata.platforms) {
80
- if (!Array.isArray(metadata.platforms)) {
81
- errors.push(ValidationUtils.error(
82
- 'INVALID_PLATFORMS',
83
- 'Platforms must be an array',
84
- 'metadata.platforms',
85
- ));
86
- } else {
87
- for (const platform of metadata.platforms) {
88
- if (!VALID_PLATFORMS.includes(platform)) {
89
- errors.push(ValidationUtils.error(
90
- 'INVALID_PLATFORM',
91
- `Invalid platform: "${platform}"`,
92
- 'metadata.platforms',
93
- platform,
94
- ));
95
- }
96
- }
97
- }
98
- }
99
-
100
- // Validate permissions if specified
101
- if (metadata.permissions) {
102
- if (!Array.isArray(metadata.permissions)) {
103
- errors.push(ValidationUtils.error(
104
- 'INVALID_PERMISSIONS',
105
- 'Permissions must be an array of strings',
106
- 'metadata.permissions',
107
- ));
108
- } else {
109
- for (let i = 0; i < metadata.permissions.length; i++) {
110
- if (typeof metadata.permissions[i] !== 'string') {
111
- errors.push(ValidationUtils.error(
112
- 'INVALID_PERMISSION',
113
- `Permission at index ${i} must be a string`,
114
- `metadata.permissions[${i}]`,
115
- ));
116
- }
117
- }
118
- }
119
- }
120
-
121
- // Validate env if specified
122
- if (metadata.env) {
123
- if (typeof metadata.env !== 'object' || Array.isArray(metadata.env)) {
124
- errors.push(ValidationUtils.error(
125
- 'INVALID_ENV',
126
- 'Env must be an object',
127
- 'metadata.env',
128
- ));
129
- } else {
130
- for (const [key, value] of Object.entries(metadata.env)) {
131
- if (!/^[A-Z][A-Z0-9_]*$/.test(key)) {
132
- warnings.push(ValidationUtils.warning(
133
- 'ENV_VAR_NAMING',
134
- `Environment variable "${key}" should use SCREAMING_SNAKE_CASE`,
135
- `metadata.env.${key}`,
136
- ));
137
- }
138
- if (typeof value !== 'object' || value === null) {
139
- errors.push(ValidationUtils.error(
140
- 'INVALID_ENV_VALUE',
141
- `Env variable "${key}" must have an object value`,
142
- `metadata.env.${key}`,
143
- ));
144
- }
145
- }
146
- }
147
- }
148
-
149
- // Validate icons if specified
150
- if (metadata.icons) {
151
- if (typeof metadata.icons !== 'object' || Array.isArray(metadata.icons)) {
152
- errors.push(ValidationUtils.error(
153
- 'INVALID_ICONS',
154
- 'Icons must be an object mapping sizes to resource IDs',
155
- 'metadata.icons',
156
- ));
157
- } else {
158
- for (const [size, resourceId] of Object.entries(metadata.icons)) {
159
- if (!/^\d+x\d+$/.test(size) && !/^\d+$/.test(size)) {
160
- warnings.push(ValidationUtils.warning(
161
- 'ICON_SIZE_FORMAT',
162
- `Icon size "${size}" should be in format "WxH" or just "N"`,
163
- `metadata.icons.${size}`,
164
- ));
165
- }
166
- }
167
- }
168
- }
169
-
170
- // Validate commands if specified
171
- if (metadata.commands) {
172
- if (typeof metadata.commands !== 'object' || Array.isArray(metadata.commands)) {
173
- errors.push(ValidationUtils.error(
174
- 'INVALID_COMMANDS',
175
- 'Commands must be an object',
176
- 'metadata.commands',
177
- ));
178
- } else {
179
- for (const [name, cmd] of Object.entries(metadata.commands)) {
180
- if (!cmd || typeof cmd !== 'object') {
181
- errors.push(ValidationUtils.error(
182
- 'INVALID_COMMAND',
183
- `Command "${name}" must be an object`,
184
- `metadata.commands.${name}`,
185
- ));
186
- } else if (!cmd.description || typeof cmd.description !== 'string') {
187
- warnings.push(ValidationUtils.warning(
188
- 'MISSING_COMMAND_DESC',
189
- `Command "${name}" should have a description`,
190
- `metadata.commands.${name}.description`,
191
- ));
192
- }
193
- }
194
- }
195
- }
196
-
197
- // Suggest adding runtime version
198
- if (!metadata.runtimeVersion && !metadata.minRuntimeVersion) {
199
- warnings.push(ValidationUtils.warning(
200
- 'MISSING_RUNTIME_VERSION',
201
- 'Consider specifying runtimeVersion or minRuntimeVersion for compatibility',
202
- 'metadata.runtimeVersion',
203
- ));
204
- }
205
-
206
- return errors.length > 0
207
- ? ValidationUtils.failure(errors, warnings)
208
- : ValidationUtils.success(warnings);
209
- }
210
- }
211
-
@@ -1,242 +0,0 @@
1
- /**
2
- * Dataset Kind Validator
3
- *
4
- * Validates manifests for structured data collections with schema definitions.
5
- */
6
-
7
- import { OriginalKind, type OriginalManifest, type ValidationResult, type DatasetMetadata } from '../types';
8
- import { BaseKindValidator, ValidationUtils } from './base';
9
-
10
- /**
11
- * Common data formats
12
- */
13
- const KNOWN_FORMATS = [
14
- 'csv', 'json', 'jsonl', 'ndjson', 'parquet', 'avro', 'orc',
15
- 'xml', 'yaml', 'toml', 'tsv', 'excel', 'sqlite', 'arrow',
16
- ];
17
-
18
- /**
19
- * Valid privacy classifications
20
- */
21
- const VALID_PRIVACY = ['public', 'internal', 'confidential', 'restricted'];
22
-
23
- /**
24
- * Valid update frequencies
25
- */
26
- const VALID_UPDATE_FREQUENCIES = ['realtime', 'hourly', 'daily', 'weekly', 'monthly', 'static'];
27
-
28
- /**
29
- * Validator for Dataset Originals
30
- */
31
- export class DatasetValidator extends BaseKindValidator<OriginalKind.Dataset> {
32
- readonly kind = OriginalKind.Dataset;
33
-
34
- protected validateKind(manifest: OriginalManifest<OriginalKind.Dataset>): ValidationResult {
35
- const errors: ValidationResult['errors'] = [];
36
- const warnings: ValidationResult['warnings'] = [];
37
- const metadata = manifest.metadata as DatasetMetadata;
38
-
39
- // Validate metadata exists
40
- if (!metadata || typeof metadata !== 'object') {
41
- return ValidationUtils.failure([
42
- ValidationUtils.error('MISSING_METADATA', 'Dataset manifest must have metadata', 'metadata'),
43
- ]);
44
- }
45
-
46
- // Validate schema (required)
47
- if (!metadata.schema) {
48
- errors.push(ValidationUtils.error(
49
- 'MISSING_SCHEMA',
50
- 'Dataset must have a schema definition',
51
- 'metadata.schema',
52
- ));
53
- } else if (typeof metadata.schema !== 'object' && typeof metadata.schema !== 'string') {
54
- errors.push(ValidationUtils.error(
55
- 'INVALID_SCHEMA',
56
- 'Schema must be an object (JSON Schema) or string (URL)',
57
- 'metadata.schema',
58
- ));
59
- } else if (typeof metadata.schema === 'string') {
60
- // If it's a URL, validate it
61
- if (!ValidationUtils.isValidURL(metadata.schema)) {
62
- errors.push(ValidationUtils.error(
63
- 'INVALID_SCHEMA_URL',
64
- 'Schema URL is not a valid URL',
65
- 'metadata.schema',
66
- metadata.schema,
67
- ));
68
- }
69
- }
70
-
71
- // Validate format (required)
72
- if (!metadata.format || typeof metadata.format !== 'string') {
73
- errors.push(ValidationUtils.error(
74
- 'MISSING_FORMAT',
75
- 'Dataset must specify a data format',
76
- 'metadata.format',
77
- ));
78
- } else {
79
- const normalizedFormat = metadata.format.toLowerCase();
80
- if (!KNOWN_FORMATS.includes(normalizedFormat)) {
81
- warnings.push(ValidationUtils.warning(
82
- 'UNKNOWN_FORMAT',
83
- `Data format "${metadata.format}" is not a commonly recognized format`,
84
- 'metadata.format',
85
- `Consider using one of: ${KNOWN_FORMATS.join(', ')}`,
86
- ));
87
- }
88
- }
89
-
90
- // Validate recordCount if specified
91
- if (metadata.recordCount !== undefined) {
92
- if (typeof metadata.recordCount !== 'number' || metadata.recordCount < 0 || !Number.isInteger(metadata.recordCount)) {
93
- errors.push(ValidationUtils.error(
94
- 'INVALID_RECORD_COUNT',
95
- 'Record count must be a non-negative integer',
96
- 'metadata.recordCount',
97
- metadata.recordCount,
98
- ));
99
- }
100
- } else {
101
- warnings.push(ValidationUtils.warning(
102
- 'MISSING_RECORD_COUNT',
103
- 'Consider specifying recordCount for better discoverability',
104
- 'metadata.recordCount',
105
- ));
106
- }
107
-
108
- // Validate columns if specified
109
- if (metadata.columns) {
110
- if (!Array.isArray(metadata.columns)) {
111
- errors.push(ValidationUtils.error(
112
- 'INVALID_COLUMNS',
113
- 'Columns must be an array',
114
- 'metadata.columns',
115
- ));
116
- } else {
117
- const columnNames = new Set<string>();
118
-
119
- for (let i = 0; i < metadata.columns.length; i++) {
120
- const column = metadata.columns[i];
121
- const columnPath = `metadata.columns[${i}]`;
122
-
123
- if (!column || typeof column !== 'object') {
124
- errors.push(ValidationUtils.error(
125
- 'INVALID_COLUMN',
126
- `Column at index ${i} must be an object`,
127
- columnPath,
128
- ));
129
- continue;
130
- }
131
-
132
- if (!column.name || typeof column.name !== 'string') {
133
- errors.push(ValidationUtils.error(
134
- 'MISSING_COLUMN_NAME',
135
- `Column at index ${i} must have a name`,
136
- `${columnPath}.name`,
137
- ));
138
- } else {
139
- if (columnNames.has(column.name)) {
140
- errors.push(ValidationUtils.error(
141
- 'DUPLICATE_COLUMN',
142
- `Duplicate column name: "${column.name}"`,
143
- `${columnPath}.name`,
144
- ));
145
- }
146
- columnNames.add(column.name);
147
- }
148
-
149
- if (!column.type || typeof column.type !== 'string') {
150
- errors.push(ValidationUtils.error(
151
- 'MISSING_COLUMN_TYPE',
152
- `Column "${column.name || i}" must have a type`,
153
- `${columnPath}.type`,
154
- ));
155
- }
156
- }
157
- }
158
- }
159
-
160
- // Validate source if specified
161
- if (metadata.source) {
162
- if (typeof metadata.source !== 'object') {
163
- errors.push(ValidationUtils.error(
164
- 'INVALID_SOURCE',
165
- 'Source must be an object',
166
- 'metadata.source',
167
- ));
168
- }
169
- }
170
-
171
- // Validate statistics if specified
172
- if (metadata.statistics) {
173
- if (typeof metadata.statistics !== 'object') {
174
- errors.push(ValidationUtils.error(
175
- 'INVALID_STATISTICS',
176
- 'Statistics must be an object',
177
- 'metadata.statistics',
178
- ));
179
- } else {
180
- if (metadata.statistics.sizeBytes !== undefined &&
181
- (typeof metadata.statistics.sizeBytes !== 'number' || metadata.statistics.sizeBytes < 0)) {
182
- errors.push(ValidationUtils.error(
183
- 'INVALID_SIZE_BYTES',
184
- 'sizeBytes must be a non-negative number',
185
- 'metadata.statistics.sizeBytes',
186
- ));
187
- }
188
- }
189
- }
190
-
191
- // Validate privacy if specified
192
- if (metadata.privacy) {
193
- if (!VALID_PRIVACY.includes(metadata.privacy)) {
194
- errors.push(ValidationUtils.error(
195
- 'INVALID_PRIVACY',
196
- `Privacy must be one of: ${VALID_PRIVACY.join(', ')}`,
197
- 'metadata.privacy',
198
- metadata.privacy,
199
- ));
200
- }
201
- } else {
202
- warnings.push(ValidationUtils.warning(
203
- 'MISSING_PRIVACY',
204
- 'Consider specifying a privacy classification for the dataset',
205
- 'metadata.privacy',
206
- ));
207
- }
208
-
209
- // Validate updateFrequency if specified
210
- if (metadata.updateFrequency) {
211
- if (!VALID_UPDATE_FREQUENCIES.includes(metadata.updateFrequency)) {
212
- errors.push(ValidationUtils.error(
213
- 'INVALID_UPDATE_FREQUENCY',
214
- `Update frequency must be one of: ${VALID_UPDATE_FREQUENCIES.join(', ')}`,
215
- 'metadata.updateFrequency',
216
- metadata.updateFrequency,
217
- ));
218
- }
219
- }
220
-
221
- // Check that at least one data resource exists
222
- const dataResources = manifest.resources.filter(r =>
223
- r.type === 'data' ||
224
- r.contentType.includes('csv') ||
225
- r.contentType.includes('json') ||
226
- r.contentType.includes('parquet') ||
227
- r.contentType.includes('octet-stream')
228
- );
229
- if (dataResources.length === 0) {
230
- warnings.push(ValidationUtils.warning(
231
- 'NO_DATA_RESOURCES',
232
- 'No data resources found. Ensure resources have appropriate types',
233
- 'resources',
234
- ));
235
- }
236
-
237
- return errors.length > 0
238
- ? ValidationUtils.failure(errors, warnings)
239
- : ValidationUtils.success(warnings);
240
- }
241
- }
242
-