@cmdoss/memwal-sdk 0.6.2 → 0.8.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.
- package/ARCHITECTURE.md +547 -547
- package/BENCHMARKS.md +238 -238
- package/README.md +310 -181
- package/dist/ai-sdk/tools.d.ts +2 -2
- package/dist/ai-sdk/tools.js +2 -2
- package/dist/client/ClientMemoryManager.js +2 -2
- package/dist/client/ClientMemoryManager.js.map +1 -1
- package/dist/client/PersonalDataWallet.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.d.ts +29 -1
- package/dist/client/SimplePDWClient.d.ts.map +1 -1
- package/dist/client/SimplePDWClient.js +45 -13
- package/dist/client/SimplePDWClient.js.map +1 -1
- package/dist/client/namespaces/EmbeddingsNamespace.d.ts +1 -1
- package/dist/client/namespaces/EmbeddingsNamespace.js +1 -1
- package/dist/client/namespaces/MemoryNamespace.d.ts +31 -0
- package/dist/client/namespaces/MemoryNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/MemoryNamespace.js +272 -39
- package/dist/client/namespaces/MemoryNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/AINamespace.d.ts +2 -2
- package/dist/client/namespaces/consolidated/AINamespace.js +2 -2
- package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts +12 -2
- package/dist/client/namespaces/consolidated/BlockchainNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/BlockchainNamespace.js +62 -4
- package/dist/client/namespaces/consolidated/BlockchainNamespace.js.map +1 -1
- package/dist/client/namespaces/consolidated/StorageNamespace.d.ts +67 -2
- package/dist/client/namespaces/consolidated/StorageNamespace.d.ts.map +1 -1
- package/dist/client/namespaces/consolidated/StorageNamespace.js +549 -16
- package/dist/client/namespaces/consolidated/StorageNamespace.js.map +1 -1
- package/dist/config/ConfigurationHelper.js +61 -61
- package/dist/config/defaults.js +2 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/graph/GraphService.js +21 -21
- package/dist/graph/GraphService.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/seal/EncryptionService.d.ts +9 -5
- package/dist/infrastructure/seal/EncryptionService.d.ts.map +1 -1
- package/dist/infrastructure/seal/EncryptionService.js +37 -15
- package/dist/infrastructure/seal/EncryptionService.js.map +1 -1
- package/dist/infrastructure/seal/SealService.d.ts +13 -5
- package/dist/infrastructure/seal/SealService.d.ts.map +1 -1
- package/dist/infrastructure/seal/SealService.js +36 -34
- package/dist/infrastructure/seal/SealService.js.map +1 -1
- package/dist/langchain/createPDWRAG.js +30 -30
- package/dist/retrieval/MemoryDecryptionPipeline.d.ts.map +1 -1
- package/dist/retrieval/MemoryDecryptionPipeline.js +2 -1
- package/dist/retrieval/MemoryDecryptionPipeline.js.map +1 -1
- package/dist/retrieval/MemoryRetrievalService.d.ts +31 -0
- package/dist/retrieval/MemoryRetrievalService.d.ts.map +1 -1
- package/dist/retrieval/MemoryRetrievalService.js +44 -4
- package/dist/retrieval/MemoryRetrievalService.js.map +1 -1
- package/dist/services/CapabilityService.d.ts.map +1 -1
- package/dist/services/CapabilityService.js +30 -14
- package/dist/services/CapabilityService.js.map +1 -1
- package/dist/services/CrossContextPermissionService.d.ts.map +1 -1
- package/dist/services/CrossContextPermissionService.js +9 -7
- package/dist/services/CrossContextPermissionService.js.map +1 -1
- package/dist/services/EmbeddingService.d.ts +28 -1
- package/dist/services/EmbeddingService.d.ts.map +1 -1
- package/dist/services/EmbeddingService.js +54 -0
- package/dist/services/EmbeddingService.js.map +1 -1
- package/dist/services/EncryptionService.d.ts.map +1 -1
- package/dist/services/EncryptionService.js +6 -5
- package/dist/services/EncryptionService.js.map +1 -1
- package/dist/services/GeminiAIService.js +309 -309
- package/dist/services/IndexManager.d.ts +5 -1
- package/dist/services/IndexManager.d.ts.map +1 -1
- package/dist/services/IndexManager.js +17 -40
- package/dist/services/IndexManager.js.map +1 -1
- package/dist/services/QueryService.js +1 -1
- package/dist/services/QueryService.js.map +1 -1
- package/dist/services/StorageService.d.ts +11 -0
- package/dist/services/StorageService.d.ts.map +1 -1
- package/dist/services/StorageService.js +73 -10
- package/dist/services/StorageService.js.map +1 -1
- package/dist/services/TransactionService.d.ts +20 -0
- package/dist/services/TransactionService.d.ts.map +1 -1
- package/dist/services/TransactionService.js +43 -0
- package/dist/services/TransactionService.js.map +1 -1
- package/dist/services/ViewService.js +2 -2
- package/dist/services/ViewService.js.map +1 -1
- package/dist/services/storage/QuiltBatchManager.d.ts +101 -1
- package/dist/services/storage/QuiltBatchManager.d.ts.map +1 -1
- package/dist/services/storage/QuiltBatchManager.js +410 -20
- package/dist/services/storage/QuiltBatchManager.js.map +1 -1
- package/dist/services/storage/index.d.ts +1 -1
- package/dist/services/storage/index.d.ts.map +1 -1
- package/dist/services/storage/index.js.map +1 -1
- package/dist/utils/LRUCache.d.ts +106 -0
- package/dist/utils/LRUCache.d.ts.map +1 -0
- package/dist/utils/LRUCache.js +281 -0
- package/dist/utils/LRUCache.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/memoryIndexOnChain.d.ts +212 -0
- package/dist/utils/memoryIndexOnChain.d.ts.map +1 -0
- package/dist/utils/memoryIndexOnChain.js +312 -0
- package/dist/utils/memoryIndexOnChain.js.map +1 -0
- package/dist/utils/rebuildIndexNode.d.ts +29 -0
- package/dist/utils/rebuildIndexNode.d.ts.map +1 -1
- package/dist/utils/rebuildIndexNode.js +366 -98
- package/dist/utils/rebuildIndexNode.js.map +1 -1
- package/dist/vector/HnswWasmService.d.ts +20 -5
- package/dist/vector/HnswWasmService.d.ts.map +1 -1
- package/dist/vector/HnswWasmService.js +73 -40
- package/dist/vector/HnswWasmService.js.map +1 -1
- package/dist/vector/IHnswService.d.ts +10 -1
- package/dist/vector/IHnswService.d.ts.map +1 -1
- package/dist/vector/IHnswService.js.map +1 -1
- package/dist/vector/NodeHnswService.d.ts +16 -0
- package/dist/vector/NodeHnswService.d.ts.map +1 -1
- package/dist/vector/NodeHnswService.js +84 -5
- package/dist/vector/NodeHnswService.js.map +1 -1
- package/dist/vector/createHnswService.d.ts +1 -1
- package/dist/vector/createHnswService.js +1 -1
- package/dist/vector/index.d.ts +1 -1
- package/dist/vector/index.js +1 -1
- package/package.json +157 -157
- package/src/access/PermissionService.ts +635 -635
- package/src/aggregation/AggregationService.ts +389 -389
- package/src/ai-sdk/PDWVectorStore.ts +715 -715
- package/src/ai-sdk/index.ts +65 -65
- package/src/ai-sdk/tools.ts +460 -460
- package/src/ai-sdk/types.ts +404 -404
- package/src/batch/BatchManager.ts +597 -597
- package/src/batch/BatchingService.ts +429 -429
- package/src/batch/MemoryProcessingCache.ts +492 -492
- package/src/batch/index.ts +30 -30
- package/src/browser.ts +200 -200
- package/src/client/ClientMemoryManager.ts +987 -987
- package/src/client/PersonalDataWallet.ts +345 -345
- package/src/client/SimplePDWClient.ts +1289 -1222
- package/src/client/factory.ts +154 -154
- package/src/client/namespaces/AnalyticsNamespace.ts +377 -377
- package/src/client/namespaces/BatchNamespace.ts +356 -356
- package/src/client/namespaces/CacheNamespace.ts +123 -123
- package/src/client/namespaces/CapabilityNamespace.ts +217 -217
- package/src/client/namespaces/ClassifyNamespace.ts +169 -169
- package/src/client/namespaces/ContextNamespace.ts +297 -297
- package/src/client/namespaces/EmbeddingsNamespace.ts +99 -99
- package/src/client/namespaces/EncryptionNamespace.ts +221 -221
- package/src/client/namespaces/GraphNamespace.ts +468 -468
- package/src/client/namespaces/IndexNamespace.ts +361 -361
- package/src/client/namespaces/MemoryNamespace.ts +1422 -1135
- package/src/client/namespaces/PermissionsNamespace.ts +254 -254
- package/src/client/namespaces/PipelineNamespace.ts +220 -220
- package/src/client/namespaces/SearchNamespace.ts +1049 -1049
- package/src/client/namespaces/StorageNamespace.ts +458 -458
- package/src/client/namespaces/TxNamespace.ts +260 -260
- package/src/client/namespaces/WalletNamespace.ts +243 -243
- package/src/client/namespaces/consolidated/AINamespace.ts +449 -449
- package/src/client/namespaces/consolidated/BlockchainNamespace.ts +607 -546
- package/src/client/namespaces/consolidated/SecurityNamespace.ts +648 -648
- package/src/client/namespaces/consolidated/StorageNamespace.ts +1141 -497
- package/src/client/namespaces/consolidated/index.ts +39 -39
- package/src/client/signers/KeypairSigner.ts +108 -108
- package/src/client/signers/UnifiedSigner.ts +110 -110
- package/src/client/signers/WalletAdapterSigner.ts +159 -159
- package/src/client/signers/index.ts +26 -26
- package/src/config/ConfigurationHelper.ts +412 -412
- package/src/config/defaults.ts +51 -51
- package/src/config/index.ts +8 -8
- package/src/config/validation.ts +70 -70
- package/src/core/index.ts +14 -14
- package/src/core/interfaces/IService.ts +307 -307
- package/src/core/interfaces/index.ts +8 -8
- package/src/core/types/capability.ts +297 -297
- package/src/core/types/index.ts +870 -870
- package/src/core/types/wallet.ts +270 -270
- package/src/core/types.ts +9 -9
- package/src/core/wallet.ts +222 -222
- package/src/embedding/index.ts +19 -19
- package/src/embedding/types.ts +357 -357
- package/src/errors/index.ts +602 -602
- package/src/errors/recovery.ts +461 -461
- package/src/errors/validation.ts +567 -567
- package/src/generated/pdw/capability.ts +319 -319
- package/src/graph/GraphService.ts +887 -887
- package/src/graph/KnowledgeGraphManager.ts +728 -728
- package/src/graph/index.ts +25 -25
- package/src/index.ts +498 -474
- package/src/infrastructure/index.ts +22 -22
- package/src/infrastructure/seal/EncryptionService.ts +628 -603
- package/src/infrastructure/seal/SealService.ts +613 -615
- package/src/infrastructure/seal/index.ts +9 -9
- package/src/infrastructure/sui/BlockchainManager.ts +627 -627
- package/src/infrastructure/sui/SuiService.ts +888 -888
- package/src/infrastructure/sui/index.ts +9 -9
- package/src/infrastructure/walrus/StorageManager.ts +604 -604
- package/src/infrastructure/walrus/WalrusStorageService.ts +612 -612
- package/src/infrastructure/walrus/index.ts +9 -9
- package/src/langchain/PDWEmbeddings.ts +145 -145
- package/src/langchain/PDWVectorStore.ts +456 -456
- package/src/langchain/createPDWRAG.ts +303 -303
- package/src/langchain/index.ts +47 -47
- package/src/permissions/ConsentRepository.browser.ts +249 -249
- package/src/permissions/ConsentRepository.ts +364 -364
- package/src/pipeline/MemoryPipeline.ts +862 -862
- package/src/pipeline/PipelineManager.ts +683 -683
- package/src/pipeline/index.ts +26 -26
- package/src/retrieval/AdvancedSearchService.ts +629 -629
- package/src/retrieval/MemoryAnalyticsService.ts +711 -711
- package/src/retrieval/MemoryDecryptionPipeline.ts +825 -824
- package/src/retrieval/MemoryRetrievalService.ts +904 -830
- package/src/retrieval/index.ts +42 -42
- package/src/services/BatchService.ts +352 -352
- package/src/services/CapabilityService.ts +464 -448
- package/src/services/ClassifierService.ts +465 -465
- package/src/services/CrossContextPermissionService.ts +486 -484
- package/src/services/EmbeddingService.ts +771 -706
- package/src/services/EncryptionService.ts +712 -711
- package/src/services/GeminiAIService.ts +753 -753
- package/src/services/IndexManager.ts +977 -1004
- package/src/services/MemoryIndexService.ts +1003 -1003
- package/src/services/MemoryService.ts +369 -369
- package/src/services/QueryService.ts +890 -890
- package/src/services/StorageService.ts +1182 -1111
- package/src/services/TransactionService.ts +838 -790
- package/src/services/VectorService.ts +462 -462
- package/src/services/ViewService.ts +484 -484
- package/src/services/index.ts +25 -25
- package/src/services/storage/BlobAttributesManager.ts +333 -333
- package/src/services/storage/KnowledgeGraphManager.ts +425 -425
- package/src/services/storage/MemorySearchManager.ts +387 -387
- package/src/services/storage/QuiltBatchManager.ts +1130 -660
- package/src/services/storage/WalrusMetadataManager.ts +268 -268
- package/src/services/storage/WalrusStorageManager.ts +287 -287
- package/src/services/storage/index.ts +57 -52
- package/src/types/index.ts +13 -13
- package/src/utils/LRUCache.ts +378 -0
- package/src/utils/index.ts +76 -68
- package/src/utils/memoryIndexOnChain.ts +507 -0
- package/src/utils/rebuildIndex.ts +290 -290
- package/src/utils/rebuildIndexNode.ts +771 -424
- package/src/vector/BrowserHnswIndexService.ts +758 -758
- package/src/vector/HnswWasmService.ts +731 -679
- package/src/vector/IHnswService.ts +233 -224
- package/src/vector/NodeHnswService.ts +833 -735
- package/src/vector/VectorManager.ts +478 -478
- package/src/vector/createHnswService.ts +135 -135
- package/src/vector/index.ts +56 -56
- package/src/wallet/ContextWalletService.ts +656 -656
- package/src/wallet/MainWalletService.ts +317 -317
package/src/errors/validation.ts
CHANGED
|
@@ -1,568 +1,568 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validation Utilities for Personal Data Wallet SDK
|
|
3
|
-
*
|
|
4
|
-
* Provides input validation, type checking, and data sanitization
|
|
5
|
-
* with automatic error throwing using the error handling system.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
ValidationError,
|
|
10
|
-
InvalidParameterError,
|
|
11
|
-
MissingParameterError,
|
|
12
|
-
ConfigurationError,
|
|
13
|
-
} from './index';
|
|
14
|
-
|
|
15
|
-
// ==================== TYPE GUARDS ====================
|
|
16
|
-
|
|
17
|
-
export function isString(value: any): value is string {
|
|
18
|
-
return typeof value === 'string';
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function isNumber(value: any): value is number {
|
|
22
|
-
return typeof value === 'number' && !isNaN(value);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function isBoolean(value: any): value is boolean {
|
|
26
|
-
return typeof value === 'boolean';
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function isObject(value: any): value is Record<string, any> {
|
|
30
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function isArray(value: any): value is any[] {
|
|
34
|
-
return Array.isArray(value);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function isUint8Array(value: any): value is Uint8Array {
|
|
38
|
-
return value instanceof Uint8Array;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function isValidAddress(address: string): boolean {
|
|
42
|
-
// Sui address validation - should start with 0x and be 64 characters total
|
|
43
|
-
return /^0x[a-fA-F0-9]{64}$/.test(address);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function isValidObjectId(objectId: string): boolean {
|
|
47
|
-
// Sui object ID validation
|
|
48
|
-
return /^0x[a-fA-F0-9]{64}$/.test(objectId);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function isValidPackageId(packageId: string): boolean {
|
|
52
|
-
// Same format as object ID
|
|
53
|
-
return isValidObjectId(packageId);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function isValidBlobId(blobId: string): boolean {
|
|
57
|
-
// Walrus blob ID validation - alphanumeric string
|
|
58
|
-
return /^[a-zA-Z0-9_-]{1,64}$/.test(blobId);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function isValidCategory(category: string): boolean {
|
|
62
|
-
// Memory category validation
|
|
63
|
-
const validCategories = [
|
|
64
|
-
'personal', 'work', 'learning', 'health', 'finance',
|
|
65
|
-
'travel', 'relationships', 'hobbies', 'goals', 'general'
|
|
66
|
-
];
|
|
67
|
-
return validCategories.includes(category.toLowerCase());
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function isValidImportance(importance: number): boolean {
|
|
71
|
-
return isNumber(importance) && importance >= 1 && importance <= 10;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// ==================== VALIDATION FUNCTIONS ====================
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Validate required parameter exists and is not null/undefined
|
|
78
|
-
*/
|
|
79
|
-
export function validateRequired<T>(
|
|
80
|
-
value: T | null | undefined,
|
|
81
|
-
parameterName: string
|
|
82
|
-
): T {
|
|
83
|
-
if (value === null || value === undefined) {
|
|
84
|
-
throw new MissingParameterError(parameterName);
|
|
85
|
-
}
|
|
86
|
-
return value;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Validate parameter is a non-empty string
|
|
91
|
-
*/
|
|
92
|
-
export function validateString(
|
|
93
|
-
value: any,
|
|
94
|
-
parameterName: string,
|
|
95
|
-
options?: {
|
|
96
|
-
required?: boolean;
|
|
97
|
-
minLength?: number;
|
|
98
|
-
maxLength?: number;
|
|
99
|
-
pattern?: RegExp;
|
|
100
|
-
}
|
|
101
|
-
): string {
|
|
102
|
-
if (options?.required !== false) {
|
|
103
|
-
validateRequired(value, parameterName);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (value === null || value === undefined) {
|
|
107
|
-
if (options?.required === false) {
|
|
108
|
-
return '';
|
|
109
|
-
}
|
|
110
|
-
throw new MissingParameterError(parameterName);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (!isString(value)) {
|
|
114
|
-
throw new InvalidParameterError(parameterName, 'string', value);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (options?.minLength && value.length < options.minLength) {
|
|
118
|
-
throw new ValidationError(
|
|
119
|
-
`Parameter '${parameterName}' must be at least ${options.minLength} characters long`,
|
|
120
|
-
parameterName,
|
|
121
|
-
value
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (options?.maxLength && value.length > options.maxLength) {
|
|
126
|
-
throw new ValidationError(
|
|
127
|
-
`Parameter '${parameterName}' must be no more than ${options.maxLength} characters long`,
|
|
128
|
-
parameterName,
|
|
129
|
-
value
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (options?.pattern && !options.pattern.test(value)) {
|
|
134
|
-
throw new ValidationError(
|
|
135
|
-
`Parameter '${parameterName}' does not match required pattern`,
|
|
136
|
-
parameterName,
|
|
137
|
-
value
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return value;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Validate parameter is a valid number
|
|
146
|
-
*/
|
|
147
|
-
export function validateNumber(
|
|
148
|
-
value: any,
|
|
149
|
-
parameterName: string,
|
|
150
|
-
options?: {
|
|
151
|
-
required?: boolean;
|
|
152
|
-
min?: number;
|
|
153
|
-
max?: number;
|
|
154
|
-
integer?: boolean;
|
|
155
|
-
}
|
|
156
|
-
): number {
|
|
157
|
-
if (options?.required !== false) {
|
|
158
|
-
validateRequired(value, parameterName);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
if (value === null || value === undefined) {
|
|
162
|
-
if (options?.required === false) {
|
|
163
|
-
return 0;
|
|
164
|
-
}
|
|
165
|
-
throw new MissingParameterError(parameterName);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (!isNumber(value)) {
|
|
169
|
-
throw new InvalidParameterError(parameterName, 'number', value);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (options?.integer && !Number.isInteger(value)) {
|
|
173
|
-
throw new ValidationError(
|
|
174
|
-
`Parameter '${parameterName}' must be an integer`,
|
|
175
|
-
parameterName,
|
|
176
|
-
value
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (options?.min !== undefined && value < options.min) {
|
|
181
|
-
throw new ValidationError(
|
|
182
|
-
`Parameter '${parameterName}' must be at least ${options.min}`,
|
|
183
|
-
parameterName,
|
|
184
|
-
value
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (options?.max !== undefined && value > options.max) {
|
|
189
|
-
throw new ValidationError(
|
|
190
|
-
`Parameter '${parameterName}' must be no more than ${options.max}`,
|
|
191
|
-
parameterName,
|
|
192
|
-
value
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return value;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Validate parameter is a boolean
|
|
201
|
-
*/
|
|
202
|
-
export function validateBoolean(
|
|
203
|
-
value: any,
|
|
204
|
-
parameterName: string,
|
|
205
|
-
required = true
|
|
206
|
-
): boolean {
|
|
207
|
-
if (required) {
|
|
208
|
-
validateRequired(value, parameterName);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (value === null || value === undefined) {
|
|
212
|
-
if (!required) {
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
throw new MissingParameterError(parameterName);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (!isBoolean(value)) {
|
|
219
|
-
throw new InvalidParameterError(parameterName, 'boolean', value);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
return value;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Validate parameter is an object
|
|
227
|
-
*/
|
|
228
|
-
export function validateObject<T extends Record<string, any>>(
|
|
229
|
-
value: any,
|
|
230
|
-
parameterName: string,
|
|
231
|
-
required = true
|
|
232
|
-
): T {
|
|
233
|
-
if (required) {
|
|
234
|
-
validateRequired(value, parameterName);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (value === null || value === undefined) {
|
|
238
|
-
if (!required) {
|
|
239
|
-
return {} as T;
|
|
240
|
-
}
|
|
241
|
-
throw new MissingParameterError(parameterName);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (!isObject(value)) {
|
|
245
|
-
throw new InvalidParameterError(parameterName, 'object', value);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return value as T;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Validate parameter is an array
|
|
253
|
-
*/
|
|
254
|
-
export function validateArray<T>(
|
|
255
|
-
value: any,
|
|
256
|
-
parameterName: string,
|
|
257
|
-
options?: {
|
|
258
|
-
required?: boolean;
|
|
259
|
-
minLength?: number;
|
|
260
|
-
maxLength?: number;
|
|
261
|
-
itemValidator?: (item: any, index: number) => T;
|
|
262
|
-
}
|
|
263
|
-
): T[] {
|
|
264
|
-
if (options?.required !== false) {
|
|
265
|
-
validateRequired(value, parameterName);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (value === null || value === undefined) {
|
|
269
|
-
if (options?.required === false) {
|
|
270
|
-
return [];
|
|
271
|
-
}
|
|
272
|
-
throw new MissingParameterError(parameterName);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (!isArray(value)) {
|
|
276
|
-
throw new InvalidParameterError(parameterName, 'array', value);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
if (options?.minLength && value.length < options.minLength) {
|
|
280
|
-
throw new ValidationError(
|
|
281
|
-
`Parameter '${parameterName}' must have at least ${options.minLength} items`,
|
|
282
|
-
parameterName,
|
|
283
|
-
value
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
if (options?.maxLength && value.length > options.maxLength) {
|
|
288
|
-
throw new ValidationError(
|
|
289
|
-
`Parameter '${parameterName}' must have no more than ${options.maxLength} items`,
|
|
290
|
-
parameterName,
|
|
291
|
-
value
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
if (options?.itemValidator) {
|
|
296
|
-
return value.map((item, index) => {
|
|
297
|
-
try {
|
|
298
|
-
return options.itemValidator!(item, index);
|
|
299
|
-
} catch (error) {
|
|
300
|
-
throw new ValidationError(
|
|
301
|
-
`Invalid item at index ${index} in ${parameterName}: ${error instanceof Error ? error.message : 'unknown error'}`,
|
|
302
|
-
`${parameterName}[${index}]`,
|
|
303
|
-
item
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
return value;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// ==================== DOMAIN-SPECIFIC VALIDATORS ====================
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Validate Sui address format
|
|
316
|
-
*/
|
|
317
|
-
export function validateSuiAddress(
|
|
318
|
-
address: any,
|
|
319
|
-
parameterName: string,
|
|
320
|
-
required = true
|
|
321
|
-
): string {
|
|
322
|
-
const addressStr = validateString(address, parameterName, { required });
|
|
323
|
-
|
|
324
|
-
if (!addressStr && !required) {
|
|
325
|
-
return '';
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
if (!isValidAddress(addressStr)) {
|
|
329
|
-
throw new ValidationError(
|
|
330
|
-
`Parameter '${parameterName}' must be a valid Sui address (0x followed by 64 hex characters)`,
|
|
331
|
-
parameterName,
|
|
332
|
-
address
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
return addressStr;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Validate Sui object ID format
|
|
341
|
-
*/
|
|
342
|
-
export function validateObjectId(
|
|
343
|
-
objectId: any,
|
|
344
|
-
parameterName: string,
|
|
345
|
-
required = true
|
|
346
|
-
): string {
|
|
347
|
-
const idStr = validateString(objectId, parameterName, { required });
|
|
348
|
-
|
|
349
|
-
if (!idStr && !required) {
|
|
350
|
-
return '';
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (!isValidObjectId(idStr)) {
|
|
354
|
-
throw new ValidationError(
|
|
355
|
-
`Parameter '${parameterName}' must be a valid Sui object ID (0x followed by 64 hex characters)`,
|
|
356
|
-
parameterName,
|
|
357
|
-
objectId
|
|
358
|
-
);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
return idStr;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
/**
|
|
365
|
-
* Validate memory category
|
|
366
|
-
*/
|
|
367
|
-
export function validateMemoryCategory(
|
|
368
|
-
category: any,
|
|
369
|
-
parameterName = 'category',
|
|
370
|
-
required = true
|
|
371
|
-
): string {
|
|
372
|
-
const categoryStr = validateString(category, parameterName, { required });
|
|
373
|
-
|
|
374
|
-
if (!categoryStr && !required) {
|
|
375
|
-
return 'general';
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
if (!isValidCategory(categoryStr)) {
|
|
379
|
-
throw new ValidationError(
|
|
380
|
-
`Parameter '${parameterName}' must be a valid memory category`,
|
|
381
|
-
parameterName,
|
|
382
|
-
category
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
return categoryStr.toLowerCase();
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Validate memory importance (1-10)
|
|
391
|
-
*/
|
|
392
|
-
export function validateMemoryImportance(
|
|
393
|
-
importance: any,
|
|
394
|
-
parameterName = 'importance',
|
|
395
|
-
required = false
|
|
396
|
-
): number {
|
|
397
|
-
if (!required && (importance === null || importance === undefined)) {
|
|
398
|
-
return 5; // Default importance
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
const importanceNum = validateNumber(importance, parameterName, {
|
|
402
|
-
required,
|
|
403
|
-
min: 1,
|
|
404
|
-
max: 10,
|
|
405
|
-
integer: true,
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
return importanceNum;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* Validate Walrus blob ID format
|
|
413
|
-
*/
|
|
414
|
-
export function validateBlobId(
|
|
415
|
-
blobId: any,
|
|
416
|
-
parameterName: string,
|
|
417
|
-
required = true
|
|
418
|
-
): string {
|
|
419
|
-
const blobIdStr = validateString(blobId, parameterName, { required });
|
|
420
|
-
|
|
421
|
-
if (!blobIdStr && !required) {
|
|
422
|
-
return '';
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
if (!isValidBlobId(blobIdStr)) {
|
|
426
|
-
throw new ValidationError(
|
|
427
|
-
`Parameter '${parameterName}' must be a valid Walrus blob ID`,
|
|
428
|
-
parameterName,
|
|
429
|
-
blobId
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
return blobIdStr;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* Validate access level
|
|
438
|
-
*/
|
|
439
|
-
export function validateAccessLevel(
|
|
440
|
-
accessLevel: any,
|
|
441
|
-
parameterName = 'accessLevel',
|
|
442
|
-
required = true
|
|
443
|
-
): 'read' | 'write' {
|
|
444
|
-
const levelStr = validateString(accessLevel, parameterName, { required });
|
|
445
|
-
|
|
446
|
-
if (!levelStr && !required) {
|
|
447
|
-
return 'read';
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
if (levelStr !== 'read' && levelStr !== 'write') {
|
|
451
|
-
throw new ValidationError(
|
|
452
|
-
`Parameter '${parameterName}' must be either 'read' or 'write'`,
|
|
453
|
-
parameterName,
|
|
454
|
-
accessLevel
|
|
455
|
-
);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
return levelStr;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
// ==================== CONFIGURATION VALIDATORS ====================
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* Validate PDW SDK configuration
|
|
465
|
-
*/
|
|
466
|
-
export function validatePDWConfig(config: any): void {
|
|
467
|
-
if (!isObject(config)) {
|
|
468
|
-
throw new ConfigurationError('Configuration must be an object');
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
// Validate package ID if provided
|
|
472
|
-
if (config.packageId !== undefined) {
|
|
473
|
-
validateObjectId(config.packageId, 'packageId');
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
// Validate encryption config if provided
|
|
477
|
-
if (config.encryptionConfig !== undefined) {
|
|
478
|
-
validateEncryptionConfig(config.encryptionConfig);
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// Validate storage config if provided
|
|
482
|
-
if (config.storageConfig !== undefined) {
|
|
483
|
-
validateStorageConfig(config.storageConfig);
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Validate encryption configuration
|
|
489
|
-
*/
|
|
490
|
-
export function validateEncryptionConfig(config: any): void {
|
|
491
|
-
validateObject(config, 'encryptionConfig');
|
|
492
|
-
|
|
493
|
-
if (config.enabled !== undefined) {
|
|
494
|
-
validateBoolean(config.enabled, 'encryptionConfig.enabled');
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
if (config.keyServers !== undefined) {
|
|
498
|
-
validateArray(config.keyServers, 'encryptionConfig.keyServers', {
|
|
499
|
-
itemValidator: (server) => validateString(server, 'keyServer'),
|
|
500
|
-
});
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Validate storage configuration
|
|
506
|
-
*/
|
|
507
|
-
export function validateStorageConfig(config: any): void {
|
|
508
|
-
validateObject(config, 'storageConfig');
|
|
509
|
-
|
|
510
|
-
if (config.provider !== undefined) {
|
|
511
|
-
const provider = validateString(config.provider, 'storageConfig.provider');
|
|
512
|
-
if (provider !== 'walrus' && provider !== 'local') {
|
|
513
|
-
throw new ValidationError(
|
|
514
|
-
'storageConfig.provider must be either "walrus" or "local"',
|
|
515
|
-
'storageConfig.provider',
|
|
516
|
-
provider
|
|
517
|
-
);
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
if (config.cacheEnabled !== undefined) {
|
|
522
|
-
validateBoolean(config.cacheEnabled, 'storageConfig.cacheEnabled');
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
if (config.encryptionEnabled !== undefined) {
|
|
526
|
-
validateBoolean(config.encryptionEnabled, 'storageConfig.encryptionEnabled');
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
// ==================== UTILITY FUNCTIONS ====================
|
|
531
|
-
|
|
532
|
-
/**
|
|
533
|
-
* Sanitize user input to prevent common issues
|
|
534
|
-
*/
|
|
535
|
-
export function sanitizeString(input: string): string {
|
|
536
|
-
return input
|
|
537
|
-
.trim()
|
|
538
|
-
.replace(/\0/g, '') // Remove null bytes
|
|
539
|
-
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, ''); // Remove control characters
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
/**
|
|
543
|
-
* Validate and normalize Sui address
|
|
544
|
-
*/
|
|
545
|
-
export function normalizeSuiAddress(address: string): string {
|
|
546
|
-
const validated = validateSuiAddress(address, 'address');
|
|
547
|
-
return validated.toLowerCase();
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
/**
|
|
551
|
-
* Create validation wrapper for functions
|
|
552
|
-
*/
|
|
553
|
-
export function withValidation<T extends any[], R>(
|
|
554
|
-
fn: (...args: T) => R,
|
|
555
|
-
validators: Array<(arg: any, index: number) => any>
|
|
556
|
-
): (...args: T) => R {
|
|
557
|
-
return (...args: T): R => {
|
|
558
|
-
// Apply validators to arguments
|
|
559
|
-
const validatedArgs = args.map((arg, index) => {
|
|
560
|
-
if (validators[index]) {
|
|
561
|
-
return validators[index](arg, index);
|
|
562
|
-
}
|
|
563
|
-
return arg;
|
|
564
|
-
}) as T;
|
|
565
|
-
|
|
566
|
-
return fn(...validatedArgs);
|
|
567
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* Validation Utilities for Personal Data Wallet SDK
|
|
3
|
+
*
|
|
4
|
+
* Provides input validation, type checking, and data sanitization
|
|
5
|
+
* with automatic error throwing using the error handling system.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
ValidationError,
|
|
10
|
+
InvalidParameterError,
|
|
11
|
+
MissingParameterError,
|
|
12
|
+
ConfigurationError,
|
|
13
|
+
} from './index';
|
|
14
|
+
|
|
15
|
+
// ==================== TYPE GUARDS ====================
|
|
16
|
+
|
|
17
|
+
export function isString(value: any): value is string {
|
|
18
|
+
return typeof value === 'string';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function isNumber(value: any): value is number {
|
|
22
|
+
return typeof value === 'number' && !isNaN(value);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function isBoolean(value: any): value is boolean {
|
|
26
|
+
return typeof value === 'boolean';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function isObject(value: any): value is Record<string, any> {
|
|
30
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function isArray(value: any): value is any[] {
|
|
34
|
+
return Array.isArray(value);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function isUint8Array(value: any): value is Uint8Array {
|
|
38
|
+
return value instanceof Uint8Array;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function isValidAddress(address: string): boolean {
|
|
42
|
+
// Sui address validation - should start with 0x and be 64 characters total
|
|
43
|
+
return /^0x[a-fA-F0-9]{64}$/.test(address);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function isValidObjectId(objectId: string): boolean {
|
|
47
|
+
// Sui object ID validation
|
|
48
|
+
return /^0x[a-fA-F0-9]{64}$/.test(objectId);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function isValidPackageId(packageId: string): boolean {
|
|
52
|
+
// Same format as object ID
|
|
53
|
+
return isValidObjectId(packageId);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function isValidBlobId(blobId: string): boolean {
|
|
57
|
+
// Walrus blob ID validation - alphanumeric string
|
|
58
|
+
return /^[a-zA-Z0-9_-]{1,64}$/.test(blobId);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function isValidCategory(category: string): boolean {
|
|
62
|
+
// Memory category validation
|
|
63
|
+
const validCategories = [
|
|
64
|
+
'personal', 'work', 'learning', 'health', 'finance',
|
|
65
|
+
'travel', 'relationships', 'hobbies', 'goals', 'general'
|
|
66
|
+
];
|
|
67
|
+
return validCategories.includes(category.toLowerCase());
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function isValidImportance(importance: number): boolean {
|
|
71
|
+
return isNumber(importance) && importance >= 1 && importance <= 10;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ==================== VALIDATION FUNCTIONS ====================
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validate required parameter exists and is not null/undefined
|
|
78
|
+
*/
|
|
79
|
+
export function validateRequired<T>(
|
|
80
|
+
value: T | null | undefined,
|
|
81
|
+
parameterName: string
|
|
82
|
+
): T {
|
|
83
|
+
if (value === null || value === undefined) {
|
|
84
|
+
throw new MissingParameterError(parameterName);
|
|
85
|
+
}
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Validate parameter is a non-empty string
|
|
91
|
+
*/
|
|
92
|
+
export function validateString(
|
|
93
|
+
value: any,
|
|
94
|
+
parameterName: string,
|
|
95
|
+
options?: {
|
|
96
|
+
required?: boolean;
|
|
97
|
+
minLength?: number;
|
|
98
|
+
maxLength?: number;
|
|
99
|
+
pattern?: RegExp;
|
|
100
|
+
}
|
|
101
|
+
): string {
|
|
102
|
+
if (options?.required !== false) {
|
|
103
|
+
validateRequired(value, parameterName);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (value === null || value === undefined) {
|
|
107
|
+
if (options?.required === false) {
|
|
108
|
+
return '';
|
|
109
|
+
}
|
|
110
|
+
throw new MissingParameterError(parameterName);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (!isString(value)) {
|
|
114
|
+
throw new InvalidParameterError(parameterName, 'string', value);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (options?.minLength && value.length < options.minLength) {
|
|
118
|
+
throw new ValidationError(
|
|
119
|
+
`Parameter '${parameterName}' must be at least ${options.minLength} characters long`,
|
|
120
|
+
parameterName,
|
|
121
|
+
value
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (options?.maxLength && value.length > options.maxLength) {
|
|
126
|
+
throw new ValidationError(
|
|
127
|
+
`Parameter '${parameterName}' must be no more than ${options.maxLength} characters long`,
|
|
128
|
+
parameterName,
|
|
129
|
+
value
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (options?.pattern && !options.pattern.test(value)) {
|
|
134
|
+
throw new ValidationError(
|
|
135
|
+
`Parameter '${parameterName}' does not match required pattern`,
|
|
136
|
+
parameterName,
|
|
137
|
+
value
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Validate parameter is a valid number
|
|
146
|
+
*/
|
|
147
|
+
export function validateNumber(
|
|
148
|
+
value: any,
|
|
149
|
+
parameterName: string,
|
|
150
|
+
options?: {
|
|
151
|
+
required?: boolean;
|
|
152
|
+
min?: number;
|
|
153
|
+
max?: number;
|
|
154
|
+
integer?: boolean;
|
|
155
|
+
}
|
|
156
|
+
): number {
|
|
157
|
+
if (options?.required !== false) {
|
|
158
|
+
validateRequired(value, parameterName);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (value === null || value === undefined) {
|
|
162
|
+
if (options?.required === false) {
|
|
163
|
+
return 0;
|
|
164
|
+
}
|
|
165
|
+
throw new MissingParameterError(parameterName);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (!isNumber(value)) {
|
|
169
|
+
throw new InvalidParameterError(parameterName, 'number', value);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (options?.integer && !Number.isInteger(value)) {
|
|
173
|
+
throw new ValidationError(
|
|
174
|
+
`Parameter '${parameterName}' must be an integer`,
|
|
175
|
+
parameterName,
|
|
176
|
+
value
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (options?.min !== undefined && value < options.min) {
|
|
181
|
+
throw new ValidationError(
|
|
182
|
+
`Parameter '${parameterName}' must be at least ${options.min}`,
|
|
183
|
+
parameterName,
|
|
184
|
+
value
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (options?.max !== undefined && value > options.max) {
|
|
189
|
+
throw new ValidationError(
|
|
190
|
+
`Parameter '${parameterName}' must be no more than ${options.max}`,
|
|
191
|
+
parameterName,
|
|
192
|
+
value
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Validate parameter is a boolean
|
|
201
|
+
*/
|
|
202
|
+
export function validateBoolean(
|
|
203
|
+
value: any,
|
|
204
|
+
parameterName: string,
|
|
205
|
+
required = true
|
|
206
|
+
): boolean {
|
|
207
|
+
if (required) {
|
|
208
|
+
validateRequired(value, parameterName);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (value === null || value === undefined) {
|
|
212
|
+
if (!required) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
throw new MissingParameterError(parameterName);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (!isBoolean(value)) {
|
|
219
|
+
throw new InvalidParameterError(parameterName, 'boolean', value);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return value;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Validate parameter is an object
|
|
227
|
+
*/
|
|
228
|
+
export function validateObject<T extends Record<string, any>>(
|
|
229
|
+
value: any,
|
|
230
|
+
parameterName: string,
|
|
231
|
+
required = true
|
|
232
|
+
): T {
|
|
233
|
+
if (required) {
|
|
234
|
+
validateRequired(value, parameterName);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (value === null || value === undefined) {
|
|
238
|
+
if (!required) {
|
|
239
|
+
return {} as T;
|
|
240
|
+
}
|
|
241
|
+
throw new MissingParameterError(parameterName);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (!isObject(value)) {
|
|
245
|
+
throw new InvalidParameterError(parameterName, 'object', value);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return value as T;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Validate parameter is an array
|
|
253
|
+
*/
|
|
254
|
+
export function validateArray<T>(
|
|
255
|
+
value: any,
|
|
256
|
+
parameterName: string,
|
|
257
|
+
options?: {
|
|
258
|
+
required?: boolean;
|
|
259
|
+
minLength?: number;
|
|
260
|
+
maxLength?: number;
|
|
261
|
+
itemValidator?: (item: any, index: number) => T;
|
|
262
|
+
}
|
|
263
|
+
): T[] {
|
|
264
|
+
if (options?.required !== false) {
|
|
265
|
+
validateRequired(value, parameterName);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (value === null || value === undefined) {
|
|
269
|
+
if (options?.required === false) {
|
|
270
|
+
return [];
|
|
271
|
+
}
|
|
272
|
+
throw new MissingParameterError(parameterName);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (!isArray(value)) {
|
|
276
|
+
throw new InvalidParameterError(parameterName, 'array', value);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (options?.minLength && value.length < options.minLength) {
|
|
280
|
+
throw new ValidationError(
|
|
281
|
+
`Parameter '${parameterName}' must have at least ${options.minLength} items`,
|
|
282
|
+
parameterName,
|
|
283
|
+
value
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (options?.maxLength && value.length > options.maxLength) {
|
|
288
|
+
throw new ValidationError(
|
|
289
|
+
`Parameter '${parameterName}' must have no more than ${options.maxLength} items`,
|
|
290
|
+
parameterName,
|
|
291
|
+
value
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (options?.itemValidator) {
|
|
296
|
+
return value.map((item, index) => {
|
|
297
|
+
try {
|
|
298
|
+
return options.itemValidator!(item, index);
|
|
299
|
+
} catch (error) {
|
|
300
|
+
throw new ValidationError(
|
|
301
|
+
`Invalid item at index ${index} in ${parameterName}: ${error instanceof Error ? error.message : 'unknown error'}`,
|
|
302
|
+
`${parameterName}[${index}]`,
|
|
303
|
+
item
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return value;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// ==================== DOMAIN-SPECIFIC VALIDATORS ====================
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Validate Sui address format
|
|
316
|
+
*/
|
|
317
|
+
export function validateSuiAddress(
|
|
318
|
+
address: any,
|
|
319
|
+
parameterName: string,
|
|
320
|
+
required = true
|
|
321
|
+
): string {
|
|
322
|
+
const addressStr = validateString(address, parameterName, { required });
|
|
323
|
+
|
|
324
|
+
if (!addressStr && !required) {
|
|
325
|
+
return '';
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (!isValidAddress(addressStr)) {
|
|
329
|
+
throw new ValidationError(
|
|
330
|
+
`Parameter '${parameterName}' must be a valid Sui address (0x followed by 64 hex characters)`,
|
|
331
|
+
parameterName,
|
|
332
|
+
address
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return addressStr;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Validate Sui object ID format
|
|
341
|
+
*/
|
|
342
|
+
export function validateObjectId(
|
|
343
|
+
objectId: any,
|
|
344
|
+
parameterName: string,
|
|
345
|
+
required = true
|
|
346
|
+
): string {
|
|
347
|
+
const idStr = validateString(objectId, parameterName, { required });
|
|
348
|
+
|
|
349
|
+
if (!idStr && !required) {
|
|
350
|
+
return '';
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (!isValidObjectId(idStr)) {
|
|
354
|
+
throw new ValidationError(
|
|
355
|
+
`Parameter '${parameterName}' must be a valid Sui object ID (0x followed by 64 hex characters)`,
|
|
356
|
+
parameterName,
|
|
357
|
+
objectId
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return idStr;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Validate memory category
|
|
366
|
+
*/
|
|
367
|
+
export function validateMemoryCategory(
|
|
368
|
+
category: any,
|
|
369
|
+
parameterName = 'category',
|
|
370
|
+
required = true
|
|
371
|
+
): string {
|
|
372
|
+
const categoryStr = validateString(category, parameterName, { required });
|
|
373
|
+
|
|
374
|
+
if (!categoryStr && !required) {
|
|
375
|
+
return 'general';
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (!isValidCategory(categoryStr)) {
|
|
379
|
+
throw new ValidationError(
|
|
380
|
+
`Parameter '${parameterName}' must be a valid memory category`,
|
|
381
|
+
parameterName,
|
|
382
|
+
category
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
return categoryStr.toLowerCase();
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* Validate memory importance (1-10)
|
|
391
|
+
*/
|
|
392
|
+
export function validateMemoryImportance(
|
|
393
|
+
importance: any,
|
|
394
|
+
parameterName = 'importance',
|
|
395
|
+
required = false
|
|
396
|
+
): number {
|
|
397
|
+
if (!required && (importance === null || importance === undefined)) {
|
|
398
|
+
return 5; // Default importance
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
const importanceNum = validateNumber(importance, parameterName, {
|
|
402
|
+
required,
|
|
403
|
+
min: 1,
|
|
404
|
+
max: 10,
|
|
405
|
+
integer: true,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
return importanceNum;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Validate Walrus blob ID format
|
|
413
|
+
*/
|
|
414
|
+
export function validateBlobId(
|
|
415
|
+
blobId: any,
|
|
416
|
+
parameterName: string,
|
|
417
|
+
required = true
|
|
418
|
+
): string {
|
|
419
|
+
const blobIdStr = validateString(blobId, parameterName, { required });
|
|
420
|
+
|
|
421
|
+
if (!blobIdStr && !required) {
|
|
422
|
+
return '';
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (!isValidBlobId(blobIdStr)) {
|
|
426
|
+
throw new ValidationError(
|
|
427
|
+
`Parameter '${parameterName}' must be a valid Walrus blob ID`,
|
|
428
|
+
parameterName,
|
|
429
|
+
blobId
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
return blobIdStr;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Validate access level
|
|
438
|
+
*/
|
|
439
|
+
export function validateAccessLevel(
|
|
440
|
+
accessLevel: any,
|
|
441
|
+
parameterName = 'accessLevel',
|
|
442
|
+
required = true
|
|
443
|
+
): 'read' | 'write' {
|
|
444
|
+
const levelStr = validateString(accessLevel, parameterName, { required });
|
|
445
|
+
|
|
446
|
+
if (!levelStr && !required) {
|
|
447
|
+
return 'read';
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
if (levelStr !== 'read' && levelStr !== 'write') {
|
|
451
|
+
throw new ValidationError(
|
|
452
|
+
`Parameter '${parameterName}' must be either 'read' or 'write'`,
|
|
453
|
+
parameterName,
|
|
454
|
+
accessLevel
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return levelStr;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// ==================== CONFIGURATION VALIDATORS ====================
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Validate PDW SDK configuration
|
|
465
|
+
*/
|
|
466
|
+
export function validatePDWConfig(config: any): void {
|
|
467
|
+
if (!isObject(config)) {
|
|
468
|
+
throw new ConfigurationError('Configuration must be an object');
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Validate package ID if provided
|
|
472
|
+
if (config.packageId !== undefined) {
|
|
473
|
+
validateObjectId(config.packageId, 'packageId');
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Validate encryption config if provided
|
|
477
|
+
if (config.encryptionConfig !== undefined) {
|
|
478
|
+
validateEncryptionConfig(config.encryptionConfig);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Validate storage config if provided
|
|
482
|
+
if (config.storageConfig !== undefined) {
|
|
483
|
+
validateStorageConfig(config.storageConfig);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Validate encryption configuration
|
|
489
|
+
*/
|
|
490
|
+
export function validateEncryptionConfig(config: any): void {
|
|
491
|
+
validateObject(config, 'encryptionConfig');
|
|
492
|
+
|
|
493
|
+
if (config.enabled !== undefined) {
|
|
494
|
+
validateBoolean(config.enabled, 'encryptionConfig.enabled');
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (config.keyServers !== undefined) {
|
|
498
|
+
validateArray(config.keyServers, 'encryptionConfig.keyServers', {
|
|
499
|
+
itemValidator: (server) => validateString(server, 'keyServer'),
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Validate storage configuration
|
|
506
|
+
*/
|
|
507
|
+
export function validateStorageConfig(config: any): void {
|
|
508
|
+
validateObject(config, 'storageConfig');
|
|
509
|
+
|
|
510
|
+
if (config.provider !== undefined) {
|
|
511
|
+
const provider = validateString(config.provider, 'storageConfig.provider');
|
|
512
|
+
if (provider !== 'walrus' && provider !== 'local') {
|
|
513
|
+
throw new ValidationError(
|
|
514
|
+
'storageConfig.provider must be either "walrus" or "local"',
|
|
515
|
+
'storageConfig.provider',
|
|
516
|
+
provider
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
if (config.cacheEnabled !== undefined) {
|
|
522
|
+
validateBoolean(config.cacheEnabled, 'storageConfig.cacheEnabled');
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (config.encryptionEnabled !== undefined) {
|
|
526
|
+
validateBoolean(config.encryptionEnabled, 'storageConfig.encryptionEnabled');
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// ==================== UTILITY FUNCTIONS ====================
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Sanitize user input to prevent common issues
|
|
534
|
+
*/
|
|
535
|
+
export function sanitizeString(input: string): string {
|
|
536
|
+
return input
|
|
537
|
+
.trim()
|
|
538
|
+
.replace(/\0/g, '') // Remove null bytes
|
|
539
|
+
.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, ''); // Remove control characters
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Validate and normalize Sui address
|
|
544
|
+
*/
|
|
545
|
+
export function normalizeSuiAddress(address: string): string {
|
|
546
|
+
const validated = validateSuiAddress(address, 'address');
|
|
547
|
+
return validated.toLowerCase();
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Create validation wrapper for functions
|
|
552
|
+
*/
|
|
553
|
+
export function withValidation<T extends any[], R>(
|
|
554
|
+
fn: (...args: T) => R,
|
|
555
|
+
validators: Array<(arg: any, index: number) => any>
|
|
556
|
+
): (...args: T) => R {
|
|
557
|
+
return (...args: T): R => {
|
|
558
|
+
// Apply validators to arguments
|
|
559
|
+
const validatedArgs = args.map((arg, index) => {
|
|
560
|
+
if (validators[index]) {
|
|
561
|
+
return validators[index](arg, index);
|
|
562
|
+
}
|
|
563
|
+
return arg;
|
|
564
|
+
}) as T;
|
|
565
|
+
|
|
566
|
+
return fn(...validatedArgs);
|
|
567
|
+
};
|
|
568
568
|
}
|