@smythos/sre 1.5.50 → 1.5.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG +98 -98
- package/LICENSE +18 -18
- package/README.md +135 -135
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/types/Components/APICall/AccessTokenManager.d.ts +3 -2
- package/dist/types/Components/APICall/OAuth.helper.d.ts +3 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.d.ts +6 -1
- package/dist/types/subsystems/LLMManager/ModelsProvider.service/connectors/SmythModelsProvider.class.d.ts +39 -0
- package/package.json +1 -1
- package/src/Components/APICall/APICall.class.ts +156 -156
- package/src/Components/APICall/AccessTokenManager.ts +166 -130
- package/src/Components/APICall/ArrayBufferResponse.helper.ts +58 -58
- package/src/Components/APICall/OAuth.helper.ts +446 -294
- package/src/Components/APICall/mimeTypeCategories.ts +46 -46
- package/src/Components/APICall/parseData.ts +167 -167
- package/src/Components/APICall/parseHeaders.ts +41 -41
- package/src/Components/APICall/parseProxy.ts +68 -68
- package/src/Components/APICall/parseUrl.ts +91 -91
- package/src/Components/APIEndpoint.class.ts +234 -234
- package/src/Components/APIOutput.class.ts +58 -58
- package/src/Components/AgentPlugin.class.ts +102 -102
- package/src/Components/Async.class.ts +155 -155
- package/src/Components/Await.class.ts +90 -90
- package/src/Components/Classifier.class.ts +158 -158
- package/src/Components/Component.class.ts +132 -132
- package/src/Components/ComponentHost.class.ts +38 -38
- package/src/Components/DataSourceCleaner.class.ts +92 -92
- package/src/Components/DataSourceIndexer.class.ts +181 -181
- package/src/Components/DataSourceLookup.class.ts +161 -161
- package/src/Components/ECMASandbox.class.ts +71 -71
- package/src/Components/FEncDec.class.ts +29 -29
- package/src/Components/FHash.class.ts +33 -33
- package/src/Components/FSign.class.ts +80 -80
- package/src/Components/FSleep.class.ts +25 -25
- package/src/Components/FTimestamp.class.ts +25 -25
- package/src/Components/FileStore.class.ts +78 -78
- package/src/Components/ForEach.class.ts +97 -97
- package/src/Components/GPTPlugin.class.ts +70 -70
- package/src/Components/GenAILLM.class.ts +586 -586
- package/src/Components/HuggingFace.class.ts +314 -314
- package/src/Components/Image/imageSettings.config.ts +70 -70
- package/src/Components/ImageGenerator.class.ts +502 -502
- package/src/Components/JSONFilter.class.ts +54 -54
- package/src/Components/LLMAssistant.class.ts +213 -213
- package/src/Components/LogicAND.class.ts +28 -28
- package/src/Components/LogicAtLeast.class.ts +85 -85
- package/src/Components/LogicAtMost.class.ts +86 -86
- package/src/Components/LogicOR.class.ts +29 -29
- package/src/Components/LogicXOR.class.ts +34 -34
- package/src/Components/MCPClient.class.ts +138 -138
- package/src/Components/MemoryDeleteKeyVal.class.ts +70 -70
- package/src/Components/MemoryReadKeyVal.class.ts +66 -66
- package/src/Components/MemoryWriteKeyVal.class.ts +62 -62
- package/src/Components/MemoryWriteObject.class.ts +97 -97
- package/src/Components/MultimodalLLM.class.ts +128 -128
- package/src/Components/OpenAPI.class.ts +72 -72
- package/src/Components/PromptGenerator.class.ts +122 -122
- package/src/Components/ScrapflyWebScrape.class.ts +159 -159
- package/src/Components/ServerlessCode.class.ts +123 -123
- package/src/Components/TavilyWebSearch.class.ts +98 -98
- package/src/Components/VisionLLM.class.ts +104 -104
- package/src/Components/ZapierAction.class.ts +127 -127
- package/src/Components/index.ts +97 -97
- package/src/Core/AgentProcess.helper.ts +240 -240
- package/src/Core/Connector.class.ts +123 -123
- package/src/Core/ConnectorsService.ts +197 -197
- package/src/Core/DummyConnector.ts +49 -49
- package/src/Core/HookService.ts +105 -105
- package/src/Core/SmythRuntime.class.ts +235 -235
- package/src/Core/SystemEvents.ts +16 -16
- package/src/Core/boot.ts +56 -56
- package/src/config.ts +15 -15
- package/src/constants.ts +126 -126
- package/src/data/hugging-face.params.json +579 -579
- package/src/helpers/AWSLambdaCode.helper.ts +590 -587
- package/src/helpers/BinaryInput.helper.ts +331 -331
- package/src/helpers/Conversation.helper.ts +1119 -1119
- package/src/helpers/ECMASandbox.helper.ts +54 -54
- package/src/helpers/JsonContent.helper.ts +97 -97
- package/src/helpers/LocalCache.helper.ts +97 -97
- package/src/helpers/Log.helper.ts +274 -274
- package/src/helpers/OpenApiParser.helper.ts +150 -150
- package/src/helpers/S3Cache.helper.ts +147 -147
- package/src/helpers/SmythURI.helper.ts +5 -5
- package/src/helpers/Sysconfig.helper.ts +77 -77
- package/src/helpers/TemplateString.helper.ts +243 -243
- package/src/helpers/TypeChecker.helper.ts +329 -329
- package/src/index.ts +3 -3
- package/src/index.ts.bak +3 -3
- package/src/subsystems/AgentManager/Agent.class.ts +1114 -1114
- package/src/subsystems/AgentManager/Agent.helper.ts +3 -3
- package/src/subsystems/AgentManager/AgentData.service/AgentDataConnector.ts +230 -230
- package/src/subsystems/AgentManager/AgentData.service/connectors/CLIAgentDataConnector.class.ts +66 -66
- package/src/subsystems/AgentManager/AgentData.service/connectors/LocalAgentDataConnector.class.ts +142 -142
- package/src/subsystems/AgentManager/AgentData.service/connectors/NullAgentData.class.ts +39 -39
- package/src/subsystems/AgentManager/AgentData.service/index.ts +18 -18
- package/src/subsystems/AgentManager/AgentLogger.class.ts +297 -297
- package/src/subsystems/AgentManager/AgentRequest.class.ts +51 -51
- package/src/subsystems/AgentManager/AgentRuntime.class.ts +559 -559
- package/src/subsystems/AgentManager/AgentSSE.class.ts +101 -101
- package/src/subsystems/AgentManager/AgentSettings.class.ts +52 -52
- package/src/subsystems/AgentManager/Component.service/ComponentConnector.ts +32 -32
- package/src/subsystems/AgentManager/Component.service/connectors/LocalComponentConnector.class.ts +60 -60
- package/src/subsystems/AgentManager/Component.service/index.ts +11 -11
- package/src/subsystems/AgentManager/EmbodimentSettings.class.ts +47 -47
- package/src/subsystems/AgentManager/ForkedAgent.class.ts +154 -154
- package/src/subsystems/AgentManager/OSResourceMonitor.ts +77 -77
- package/src/subsystems/ComputeManager/Code.service/CodeConnector.ts +98 -98
- package/src/subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class.ts +172 -172
- package/src/subsystems/ComputeManager/Code.service/connectors/ECMASandbox.class.ts +131 -131
- package/src/subsystems/ComputeManager/Code.service/index.ts +13 -13
- package/src/subsystems/IO/CLI.service/CLIConnector.ts +47 -47
- package/src/subsystems/IO/CLI.service/index.ts +9 -9
- package/src/subsystems/IO/Log.service/LogConnector.ts +32 -32
- package/src/subsystems/IO/Log.service/connectors/ConsoleLog.class.ts +28 -28
- package/src/subsystems/IO/Log.service/index.ts +13 -13
- package/src/subsystems/IO/NKV.service/NKVConnector.ts +43 -43
- package/src/subsystems/IO/NKV.service/connectors/NKVLocalStorage.class.ts +234 -234
- package/src/subsystems/IO/NKV.service/connectors/NKVRAM.class.ts +204 -204
- package/src/subsystems/IO/NKV.service/connectors/NKVRedis.class.ts +182 -182
- package/src/subsystems/IO/NKV.service/index.ts +14 -14
- package/src/subsystems/IO/Router.service/RouterConnector.ts +21 -21
- package/src/subsystems/IO/Router.service/connectors/ExpressRouter.class.ts +48 -48
- package/src/subsystems/IO/Router.service/connectors/NullRouter.class.ts +40 -40
- package/src/subsystems/IO/Router.service/index.ts +11 -11
- package/src/subsystems/IO/Storage.service/SmythFS.class.ts +489 -489
- package/src/subsystems/IO/Storage.service/StorageConnector.ts +66 -66
- package/src/subsystems/IO/Storage.service/connectors/LocalStorage.class.ts +327 -327
- package/src/subsystems/IO/Storage.service/connectors/S3Storage.class.ts +482 -482
- package/src/subsystems/IO/Storage.service/index.ts +13 -13
- package/src/subsystems/IO/VectorDB.service/VectorDBConnector.ts +108 -108
- package/src/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.ts +454 -454
- package/src/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.ts +384 -384
- package/src/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.ts +421 -421
- package/src/subsystems/IO/VectorDB.service/embed/BaseEmbedding.ts +107 -107
- package/src/subsystems/IO/VectorDB.service/embed/OpenAIEmbedding.ts +109 -109
- package/src/subsystems/IO/VectorDB.service/embed/index.ts +21 -21
- package/src/subsystems/IO/VectorDB.service/index.ts +14 -14
- package/src/subsystems/LLMManager/LLM.helper.ts +251 -251
- package/src/subsystems/LLMManager/LLM.inference.ts +339 -339
- package/src/subsystems/LLMManager/LLM.service/LLMConnector.ts +489 -489
- package/src/subsystems/LLMManager/LLM.service/LLMCredentials.helper.ts +171 -171
- package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +659 -659
- package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +400 -400
- package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +77 -77
- package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +757 -757
- package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +304 -304
- package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +250 -250
- package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +423 -423
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.ts +488 -488
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.ts +524 -524
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterface.ts +100 -100
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterfaceFactory.ts +81 -81
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +1145 -1145
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/constants.ts +13 -13
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/index.ts +4 -4
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/utils.ts +11 -11
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/types.ts +32 -32
- package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +471 -471
- package/src/subsystems/LLMManager/LLM.service/index.ts +44 -44
- package/src/subsystems/LLMManager/ModelsProvider.service/ModelsProviderConnector.ts +300 -300
- package/src/subsystems/LLMManager/ModelsProvider.service/connectors/JSONModelsProvider.class.ts +252 -252
- package/src/subsystems/LLMManager/ModelsProvider.service/index.ts +11 -11
- package/src/subsystems/LLMManager/custom-models.ts +854 -854
- package/src/subsystems/LLMManager/models.ts +2540 -2540
- package/src/subsystems/LLMManager/paramMappings.ts +69 -69
- package/src/subsystems/MemoryManager/Cache.service/CacheConnector.ts +86 -86
- package/src/subsystems/MemoryManager/Cache.service/connectors/LocalStorageCache.class.ts +297 -297
- package/src/subsystems/MemoryManager/Cache.service/connectors/RAMCache.class.ts +201 -201
- package/src/subsystems/MemoryManager/Cache.service/connectors/RedisCache.class.ts +252 -252
- package/src/subsystems/MemoryManager/Cache.service/connectors/S3Cache.class.ts +373 -373
- package/src/subsystems/MemoryManager/Cache.service/index.ts +15 -15
- package/src/subsystems/MemoryManager/LLMCache.ts +72 -72
- package/src/subsystems/MemoryManager/LLMContext.ts +124 -124
- package/src/subsystems/MemoryManager/LLMMemory.service/LLMMemoryConnector.ts +26 -26
- package/src/subsystems/MemoryManager/RuntimeContext.ts +266 -266
- package/src/subsystems/Security/AccessControl/ACL.class.ts +208 -208
- package/src/subsystems/Security/AccessControl/AccessCandidate.class.ts +82 -82
- package/src/subsystems/Security/AccessControl/AccessRequest.class.ts +52 -52
- package/src/subsystems/Security/Account.service/AccountConnector.ts +44 -44
- package/src/subsystems/Security/Account.service/connectors/AWSAccount.class.ts +76 -76
- package/src/subsystems/Security/Account.service/connectors/DummyAccount.class.ts +130 -130
- package/src/subsystems/Security/Account.service/connectors/JSONFileAccount.class.ts +159 -159
- package/src/subsystems/Security/Account.service/index.ts +14 -14
- package/src/subsystems/Security/Credentials.helper.ts +62 -62
- package/src/subsystems/Security/ManagedVault.service/ManagedVaultConnector.ts +38 -38
- package/src/subsystems/Security/ManagedVault.service/connectors/NullManagedVault.class.ts +53 -53
- package/src/subsystems/Security/ManagedVault.service/connectors/SecretManagerManagedVault.ts +154 -154
- package/src/subsystems/Security/ManagedVault.service/index.ts +12 -12
- package/src/subsystems/Security/SecureConnector.class.ts +110 -110
- package/src/subsystems/Security/Vault.service/Vault.helper.ts +30 -30
- package/src/subsystems/Security/Vault.service/VaultConnector.ts +29 -29
- package/src/subsystems/Security/Vault.service/connectors/HashicorpVault.class.ts +46 -46
- package/src/subsystems/Security/Vault.service/connectors/JSONFileVault.class.ts +221 -221
- package/src/subsystems/Security/Vault.service/connectors/NullVault.class.ts +54 -54
- package/src/subsystems/Security/Vault.service/connectors/SecretsManager.class.ts +140 -140
- package/src/subsystems/Security/Vault.service/index.ts +12 -12
- package/src/types/ACL.types.ts +104 -104
- package/src/types/AWS.types.ts +10 -10
- package/src/types/Agent.types.ts +61 -61
- package/src/types/AgentLogger.types.ts +17 -17
- package/src/types/Cache.types.ts +1 -1
- package/src/types/Common.types.ts +2 -2
- package/src/types/LLM.types.ts +496 -496
- package/src/types/Redis.types.ts +8 -8
- package/src/types/SRE.types.ts +64 -64
- package/src/types/Security.types.ts +14 -14
- package/src/types/Storage.types.ts +5 -5
- package/src/types/VectorDB.types.ts +86 -86
- package/src/utils/base64.utils.ts +275 -275
- package/src/utils/cli.utils.ts +68 -68
- package/src/utils/data.utils.ts +322 -322
- package/src/utils/date-time.utils.ts +22 -22
- package/src/utils/general.utils.ts +238 -238
- package/src/utils/index.ts +12 -12
- package/src/utils/lazy-client.ts +261 -261
- package/src/utils/numbers.utils.ts +13 -13
- package/src/utils/oauth.utils.ts +35 -35
- package/src/utils/string.utils.ts +414 -414
- package/src/utils/url.utils.ts +19 -19
- package/src/utils/validation.utils.ts +74 -74
- package/dist/bundle-analysis-lazy.html +0 -4949
- package/dist/bundle-analysis.html +0 -4949
- package/dist/types/utils/package-manager.utils.d.ts +0 -26
|
@@ -1,234 +1,234 @@
|
|
|
1
|
-
import { AccessRequest } from '@sre/Security/AccessControl/AccessRequest.class';
|
|
2
|
-
import { NKVConnector } from '../NKVConnector';
|
|
3
|
-
import { ACLAccessDeniedError, IAccessCandidate, TAccessResult } from '@sre/types/ACL.types';
|
|
4
|
-
import { ACL } from '@sre/Security/AccessControl/ACL.class';
|
|
5
|
-
import { CacheConnector } from '@sre/MemoryManager/Cache.service/CacheConnector';
|
|
6
|
-
import { ConnectorService } from '@sre/Core/ConnectorsService';
|
|
7
|
-
import { StorageData } from '@sre/types/Storage.types';
|
|
8
|
-
import { AccountConnector } from '@sre/Security/Account.service/AccountConnector';
|
|
9
|
-
import Joi from 'joi';
|
|
10
|
-
import fs from 'fs';
|
|
11
|
-
import path from 'path';
|
|
12
|
-
import { findSmythPath } from '../../../../';
|
|
13
|
-
import { Logger } from '@sre/helpers/Log.helper';
|
|
14
|
-
|
|
15
|
-
const console = Logger('NKVLocalStorage');
|
|
16
|
-
|
|
17
|
-
export type NKVLocalStorageConfig = {
|
|
18
|
-
folder?: string;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export class NKVLocalStorage extends NKVConnector {
|
|
22
|
-
public name = 'NKVLocalStorage';
|
|
23
|
-
private folder: string;
|
|
24
|
-
private accountConnector: AccountConnector;
|
|
25
|
-
private cacheConnector: CacheConnector;
|
|
26
|
-
private isInitialized = false;
|
|
27
|
-
|
|
28
|
-
constructor(protected _settings?: NKVLocalStorageConfig) {
|
|
29
|
-
super(_settings);
|
|
30
|
-
this.accountConnector = ConnectorService.getAccountConnector();
|
|
31
|
-
this.cacheConnector = ConnectorService.getCacheConnector('RAM');
|
|
32
|
-
this.folder = this.findStorageFolder(_settings?.folder);
|
|
33
|
-
this.initialize();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
private findStorageFolder(folder?: string): string {
|
|
37
|
-
let _storageFolder = folder;
|
|
38
|
-
|
|
39
|
-
if (_storageFolder && fs.existsSync(_storageFolder)) {
|
|
40
|
-
return _storageFolder;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
_storageFolder = findSmythPath('nkv');
|
|
44
|
-
|
|
45
|
-
if (fs.existsSync(_storageFolder)) {
|
|
46
|
-
console.warn('Using alternative storage folder found in : ', _storageFolder);
|
|
47
|
-
return _storageFolder;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
console.warn('!!! All attempts to find an existing storage folder failed !!!');
|
|
51
|
-
console.warn('!!! I will use this folder: ', _storageFolder);
|
|
52
|
-
return _storageFolder;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private initialize() {
|
|
56
|
-
if (!this.isInitialized) {
|
|
57
|
-
if (!fs.existsSync(this.folder)) {
|
|
58
|
-
fs.mkdirSync(this.folder, { recursive: true });
|
|
59
|
-
}
|
|
60
|
-
this.isInitialized = true;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
private normalizeFilename(filename: string): string {
|
|
65
|
-
// Step 1: Deduplicate successive colons (:: becomes :)
|
|
66
|
-
let normalized = filename.replace(/:+/g, ':');
|
|
67
|
-
|
|
68
|
-
// Step 2: Replace colons with forward slashes for subfolder structure
|
|
69
|
-
normalized = normalized.replace(/:/g, '/');
|
|
70
|
-
|
|
71
|
-
// Step 3: Replace invalid filename characters with dots
|
|
72
|
-
// Invalid characters for cross-platform compatibility:
|
|
73
|
-
// - Control characters (0-31 and 127)
|
|
74
|
-
// - Windows reserved: < > : " | ? * \
|
|
75
|
-
// - Preserve forward slashes from step 2 for subfolder structure
|
|
76
|
-
normalized = normalized.replace(/[<>:"|?*\\\x00-\x1f\x7f]/g, '.');
|
|
77
|
-
|
|
78
|
-
// Step 4: Handle edge cases - remove leading/trailing dots and spaces
|
|
79
|
-
normalized = normalized.replace(/^[.\s]+|[.\s]+$/g, '');
|
|
80
|
-
|
|
81
|
-
// Step 5: Ensure we don't have empty path components
|
|
82
|
-
normalized = normalized.replace(/\/+/g, '/').replace(/\/\./g, '/').replace(/\.\//g, './');
|
|
83
|
-
|
|
84
|
-
return normalized || 'default';
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
private getStoragePath(teamId: string, namespace: string, key?: string): string {
|
|
88
|
-
const parts = [`team_${this.normalizeFilename(teamId)}`, this.normalizeFilename(namespace)];
|
|
89
|
-
if (key) {
|
|
90
|
-
parts.push(this.normalizeFilename(key));
|
|
91
|
-
}
|
|
92
|
-
return path.join(this.folder, ...parts);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
public key(...parts: string[]) {
|
|
96
|
-
return parts.join(':');
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
@NKVLocalStorage.Validate
|
|
100
|
-
@NKVLocalStorage.NamespaceAccessControl
|
|
101
|
-
protected async get(acRequest: AccessRequest, namespace: string, key: string): Promise<StorageData> {
|
|
102
|
-
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
103
|
-
const filePath = this.getStoragePath(teamId, namespace, key);
|
|
104
|
-
if (!fs.existsSync(filePath)) {
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
try {
|
|
108
|
-
const data = fs.readFileSync(filePath, 'utf-8');
|
|
109
|
-
return JSON.parse(data);
|
|
110
|
-
} catch (error) {
|
|
111
|
-
console.error(`Error reading from NKVLocalStorage: ${error.message}`);
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
@NKVLocalStorage.Validate
|
|
117
|
-
@NKVLocalStorage.NamespaceAccessControl
|
|
118
|
-
protected async set(acRequest: AccessRequest, namespace: string, key: string, value: any): Promise<void> {
|
|
119
|
-
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
120
|
-
const filePath = this.getStoragePath(teamId, namespace, key);
|
|
121
|
-
const dirPath = path.dirname(filePath);
|
|
122
|
-
|
|
123
|
-
if (!fs.existsSync(dirPath)) {
|
|
124
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
fs.writeFileSync(filePath, JSON.stringify(value));
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
@NKVLocalStorage.Validate
|
|
131
|
-
@NKVLocalStorage.NamespaceAccessControl
|
|
132
|
-
protected async delete(acRequest: AccessRequest, namespace: string, key: string): Promise<void> {
|
|
133
|
-
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
134
|
-
const filePath = this.getStoragePath(teamId, namespace, key);
|
|
135
|
-
if (fs.existsSync(filePath)) {
|
|
136
|
-
fs.unlinkSync(filePath);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
@NKVLocalStorage.Validate
|
|
141
|
-
@NKVLocalStorage.NamespaceAccessControl
|
|
142
|
-
protected async exists(acRequest: AccessRequest, namespace: string, key: string): Promise<boolean> {
|
|
143
|
-
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
144
|
-
const filePath = this.getStoragePath(teamId, namespace, key);
|
|
145
|
-
return fs.existsSync(filePath);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
@NKVLocalStorage.NamespaceAccessControl
|
|
149
|
-
public async list(acRequest: AccessRequest, namespace: string): Promise<{ key: string; data: StorageData }[]> {
|
|
150
|
-
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
151
|
-
const namespacePath = this.getStoragePath(teamId, namespace);
|
|
152
|
-
const results: { key: string; data: StorageData }[] = [];
|
|
153
|
-
|
|
154
|
-
if (!fs.existsSync(namespacePath)) {
|
|
155
|
-
return results;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const files = fs.readdirSync(namespacePath);
|
|
159
|
-
for (const file of files) {
|
|
160
|
-
const filePath = path.join(namespacePath, file);
|
|
161
|
-
const stat = fs.statSync(filePath);
|
|
162
|
-
if (stat.isFile()) {
|
|
163
|
-
const data = fs.readFileSync(filePath, 'utf-8');
|
|
164
|
-
results.push({
|
|
165
|
-
key: file,
|
|
166
|
-
data: JSON.parse(data) as StorageData,
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return results;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
@NKVLocalStorage.NamespaceAccessControl
|
|
174
|
-
public async deleteAll(acRequest: AccessRequest, namespace: string): Promise<void> {
|
|
175
|
-
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
176
|
-
const namespacePath = this.getStoragePath(teamId, namespace);
|
|
177
|
-
if (fs.existsSync(namespacePath)) {
|
|
178
|
-
fs.rmSync(namespacePath, { recursive: true, force: true });
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
public async getResourceACL(resourceId: string, candidate: IAccessCandidate): Promise<ACL> {
|
|
183
|
-
return this.cacheConnector.getResourceACL(resourceId, candidate);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
public clearAll(): void {
|
|
187
|
-
if (fs.existsSync(this.folder)) {
|
|
188
|
-
fs.rmSync(this.folder, { recursive: true, force: true });
|
|
189
|
-
this.initialize();
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
static NamespaceAccessControl(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
194
|
-
const originalMethod = descriptor.value;
|
|
195
|
-
|
|
196
|
-
descriptor.value = async function (...args: any[]) {
|
|
197
|
-
let [acRequest, namespace, key] = args;
|
|
198
|
-
const isNamespaceSearch = key === undefined;
|
|
199
|
-
|
|
200
|
-
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
201
|
-
const resourceId = isNamespaceSearch ? namespace : `${namespace}:${key}`;
|
|
202
|
-
const finalKey = this.key(`team_${teamId}`, resourceId);
|
|
203
|
-
const accessTicket = await this.getAccessTicket(finalKey, acRequest);
|
|
204
|
-
|
|
205
|
-
if (accessTicket.access !== TAccessResult.Granted) throw new ACLAccessDeniedError('Access Denied');
|
|
206
|
-
|
|
207
|
-
return originalMethod.apply(this, args);
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
return descriptor;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
static Validate(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
214
|
-
const originalMethod = descriptor.value;
|
|
215
|
-
|
|
216
|
-
descriptor.value = async function (...args: any[]) {
|
|
217
|
-
let [acRequest, namespace, key] = args;
|
|
218
|
-
|
|
219
|
-
const schemaValidator = Joi.object().keys({
|
|
220
|
-
namespace: Joi.string().min(1).required(),
|
|
221
|
-
key: Joi.string().min(1).required(),
|
|
222
|
-
});
|
|
223
|
-
const validationResult = schemaValidator.validate({ namespace, key });
|
|
224
|
-
|
|
225
|
-
if (validationResult.error) {
|
|
226
|
-
throw new Error(`Validation Error: ${validationResult.error.message}`);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return originalMethod.apply(this, args);
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
return descriptor;
|
|
233
|
-
}
|
|
234
|
-
}
|
|
1
|
+
import { AccessRequest } from '@sre/Security/AccessControl/AccessRequest.class';
|
|
2
|
+
import { NKVConnector } from '../NKVConnector';
|
|
3
|
+
import { ACLAccessDeniedError, IAccessCandidate, TAccessResult } from '@sre/types/ACL.types';
|
|
4
|
+
import { ACL } from '@sre/Security/AccessControl/ACL.class';
|
|
5
|
+
import { CacheConnector } from '@sre/MemoryManager/Cache.service/CacheConnector';
|
|
6
|
+
import { ConnectorService } from '@sre/Core/ConnectorsService';
|
|
7
|
+
import { StorageData } from '@sre/types/Storage.types';
|
|
8
|
+
import { AccountConnector } from '@sre/Security/Account.service/AccountConnector';
|
|
9
|
+
import Joi from 'joi';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import { findSmythPath } from '../../../../';
|
|
13
|
+
import { Logger } from '@sre/helpers/Log.helper';
|
|
14
|
+
|
|
15
|
+
const console = Logger('NKVLocalStorage');
|
|
16
|
+
|
|
17
|
+
export type NKVLocalStorageConfig = {
|
|
18
|
+
folder?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export class NKVLocalStorage extends NKVConnector {
|
|
22
|
+
public name = 'NKVLocalStorage';
|
|
23
|
+
private folder: string;
|
|
24
|
+
private accountConnector: AccountConnector;
|
|
25
|
+
private cacheConnector: CacheConnector;
|
|
26
|
+
private isInitialized = false;
|
|
27
|
+
|
|
28
|
+
constructor(protected _settings?: NKVLocalStorageConfig) {
|
|
29
|
+
super(_settings);
|
|
30
|
+
this.accountConnector = ConnectorService.getAccountConnector();
|
|
31
|
+
this.cacheConnector = ConnectorService.getCacheConnector('RAM');
|
|
32
|
+
this.folder = this.findStorageFolder(_settings?.folder);
|
|
33
|
+
this.initialize();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private findStorageFolder(folder?: string): string {
|
|
37
|
+
let _storageFolder = folder;
|
|
38
|
+
|
|
39
|
+
if (_storageFolder && fs.existsSync(_storageFolder)) {
|
|
40
|
+
return _storageFolder;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
_storageFolder = findSmythPath('nkv');
|
|
44
|
+
|
|
45
|
+
if (fs.existsSync(_storageFolder)) {
|
|
46
|
+
console.warn('Using alternative storage folder found in : ', _storageFolder);
|
|
47
|
+
return _storageFolder;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
console.warn('!!! All attempts to find an existing storage folder failed !!!');
|
|
51
|
+
console.warn('!!! I will use this folder: ', _storageFolder);
|
|
52
|
+
return _storageFolder;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private initialize() {
|
|
56
|
+
if (!this.isInitialized) {
|
|
57
|
+
if (!fs.existsSync(this.folder)) {
|
|
58
|
+
fs.mkdirSync(this.folder, { recursive: true });
|
|
59
|
+
}
|
|
60
|
+
this.isInitialized = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private normalizeFilename(filename: string): string {
|
|
65
|
+
// Step 1: Deduplicate successive colons (:: becomes :)
|
|
66
|
+
let normalized = filename.replace(/:+/g, ':');
|
|
67
|
+
|
|
68
|
+
// Step 2: Replace colons with forward slashes for subfolder structure
|
|
69
|
+
normalized = normalized.replace(/:/g, '/');
|
|
70
|
+
|
|
71
|
+
// Step 3: Replace invalid filename characters with dots
|
|
72
|
+
// Invalid characters for cross-platform compatibility:
|
|
73
|
+
// - Control characters (0-31 and 127)
|
|
74
|
+
// - Windows reserved: < > : " | ? * \
|
|
75
|
+
// - Preserve forward slashes from step 2 for subfolder structure
|
|
76
|
+
normalized = normalized.replace(/[<>:"|?*\\\x00-\x1f\x7f]/g, '.');
|
|
77
|
+
|
|
78
|
+
// Step 4: Handle edge cases - remove leading/trailing dots and spaces
|
|
79
|
+
normalized = normalized.replace(/^[.\s]+|[.\s]+$/g, '');
|
|
80
|
+
|
|
81
|
+
// Step 5: Ensure we don't have empty path components
|
|
82
|
+
normalized = normalized.replace(/\/+/g, '/').replace(/\/\./g, '/').replace(/\.\//g, './');
|
|
83
|
+
|
|
84
|
+
return normalized || 'default';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private getStoragePath(teamId: string, namespace: string, key?: string): string {
|
|
88
|
+
const parts = [`team_${this.normalizeFilename(teamId)}`, this.normalizeFilename(namespace)];
|
|
89
|
+
if (key) {
|
|
90
|
+
parts.push(this.normalizeFilename(key));
|
|
91
|
+
}
|
|
92
|
+
return path.join(this.folder, ...parts);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public key(...parts: string[]) {
|
|
96
|
+
return parts.join(':');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@NKVLocalStorage.Validate
|
|
100
|
+
@NKVLocalStorage.NamespaceAccessControl
|
|
101
|
+
protected async get(acRequest: AccessRequest, namespace: string, key: string): Promise<StorageData> {
|
|
102
|
+
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
103
|
+
const filePath = this.getStoragePath(teamId, namespace, key);
|
|
104
|
+
if (!fs.existsSync(filePath)) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
const data = fs.readFileSync(filePath, 'utf-8');
|
|
109
|
+
return JSON.parse(data);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.error(`Error reading from NKVLocalStorage: ${error.message}`);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@NKVLocalStorage.Validate
|
|
117
|
+
@NKVLocalStorage.NamespaceAccessControl
|
|
118
|
+
protected async set(acRequest: AccessRequest, namespace: string, key: string, value: any): Promise<void> {
|
|
119
|
+
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
120
|
+
const filePath = this.getStoragePath(teamId, namespace, key);
|
|
121
|
+
const dirPath = path.dirname(filePath);
|
|
122
|
+
|
|
123
|
+
if (!fs.existsSync(dirPath)) {
|
|
124
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
fs.writeFileSync(filePath, JSON.stringify(value));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@NKVLocalStorage.Validate
|
|
131
|
+
@NKVLocalStorage.NamespaceAccessControl
|
|
132
|
+
protected async delete(acRequest: AccessRequest, namespace: string, key: string): Promise<void> {
|
|
133
|
+
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
134
|
+
const filePath = this.getStoragePath(teamId, namespace, key);
|
|
135
|
+
if (fs.existsSync(filePath)) {
|
|
136
|
+
fs.unlinkSync(filePath);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@NKVLocalStorage.Validate
|
|
141
|
+
@NKVLocalStorage.NamespaceAccessControl
|
|
142
|
+
protected async exists(acRequest: AccessRequest, namespace: string, key: string): Promise<boolean> {
|
|
143
|
+
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
144
|
+
const filePath = this.getStoragePath(teamId, namespace, key);
|
|
145
|
+
return fs.existsSync(filePath);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@NKVLocalStorage.NamespaceAccessControl
|
|
149
|
+
public async list(acRequest: AccessRequest, namespace: string): Promise<{ key: string; data: StorageData }[]> {
|
|
150
|
+
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
151
|
+
const namespacePath = this.getStoragePath(teamId, namespace);
|
|
152
|
+
const results: { key: string; data: StorageData }[] = [];
|
|
153
|
+
|
|
154
|
+
if (!fs.existsSync(namespacePath)) {
|
|
155
|
+
return results;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const files = fs.readdirSync(namespacePath);
|
|
159
|
+
for (const file of files) {
|
|
160
|
+
const filePath = path.join(namespacePath, file);
|
|
161
|
+
const stat = fs.statSync(filePath);
|
|
162
|
+
if (stat.isFile()) {
|
|
163
|
+
const data = fs.readFileSync(filePath, 'utf-8');
|
|
164
|
+
results.push({
|
|
165
|
+
key: file,
|
|
166
|
+
data: JSON.parse(data) as StorageData,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return results;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@NKVLocalStorage.NamespaceAccessControl
|
|
174
|
+
public async deleteAll(acRequest: AccessRequest, namespace: string): Promise<void> {
|
|
175
|
+
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
176
|
+
const namespacePath = this.getStoragePath(teamId, namespace);
|
|
177
|
+
if (fs.existsSync(namespacePath)) {
|
|
178
|
+
fs.rmSync(namespacePath, { recursive: true, force: true });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
public async getResourceACL(resourceId: string, candidate: IAccessCandidate): Promise<ACL> {
|
|
183
|
+
return this.cacheConnector.getResourceACL(resourceId, candidate);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
public clearAll(): void {
|
|
187
|
+
if (fs.existsSync(this.folder)) {
|
|
188
|
+
fs.rmSync(this.folder, { recursive: true, force: true });
|
|
189
|
+
this.initialize();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
static NamespaceAccessControl(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
194
|
+
const originalMethod = descriptor.value;
|
|
195
|
+
|
|
196
|
+
descriptor.value = async function (...args: any[]) {
|
|
197
|
+
let [acRequest, namespace, key] = args;
|
|
198
|
+
const isNamespaceSearch = key === undefined;
|
|
199
|
+
|
|
200
|
+
const teamId = await this.accountConnector.getCandidateTeam(acRequest.candidate);
|
|
201
|
+
const resourceId = isNamespaceSearch ? namespace : `${namespace}:${key}`;
|
|
202
|
+
const finalKey = this.key(`team_${teamId}`, resourceId);
|
|
203
|
+
const accessTicket = await this.getAccessTicket(finalKey, acRequest);
|
|
204
|
+
|
|
205
|
+
if (accessTicket.access !== TAccessResult.Granted) throw new ACLAccessDeniedError('Access Denied');
|
|
206
|
+
|
|
207
|
+
return originalMethod.apply(this, args);
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
return descriptor;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
static Validate(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
|
|
214
|
+
const originalMethod = descriptor.value;
|
|
215
|
+
|
|
216
|
+
descriptor.value = async function (...args: any[]) {
|
|
217
|
+
let [acRequest, namespace, key] = args;
|
|
218
|
+
|
|
219
|
+
const schemaValidator = Joi.object().keys({
|
|
220
|
+
namespace: Joi.string().min(1).required(),
|
|
221
|
+
key: Joi.string().min(1).required(),
|
|
222
|
+
});
|
|
223
|
+
const validationResult = schemaValidator.validate({ namespace, key });
|
|
224
|
+
|
|
225
|
+
if (validationResult.error) {
|
|
226
|
+
throw new Error(`Validation Error: ${validationResult.error.message}`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return originalMethod.apply(this, args);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
return descriptor;
|
|
233
|
+
}
|
|
234
|
+
}
|