libmodulor 0.4.0 → 0.5.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/CHANGELOG.md +18 -1
- package/README.md +3 -3
- package/dist/esm/app/workers/AppSrcFilePathBuilder.d.ts +16 -0
- package/dist/esm/app/workers/AppSrcFilePathBuilder.js +6 -4
- package/dist/esm/apps/Helper/index.js +1 -0
- package/dist/esm/apps/Helper/src/ucds/GenerateAppsTestsUCD.js +3 -2
- package/dist/esm/bundlers/vite/StripUCDLifecycleServerPlugin.js +3 -0
- package/dist/esm/convention.d.ts +1 -0
- package/dist/esm/convention.js +17 -4
- package/dist/esm/dt/Validation.d.ts +8 -0
- package/dist/esm/dt/Validation.js +8 -0
- package/dist/esm/dt/base/TBase.d.ts +2 -1
- package/dist/esm/dt/base/TBoolean.js +2 -0
- package/dist/esm/dt/base/TInt.js +3 -0
- package/dist/esm/dt/base/TNumber.js +2 -0
- package/dist/esm/dt/base/TObject.d.ts +15 -0
- package/dist/esm/dt/base/TObject.js +14 -0
- package/dist/esm/dt/base/TString.js +1 -1
- package/dist/esm/dt/final/TAmount.js +1 -0
- package/dist/esm/dt/final/TCountryISO3166Alpha2.js +1 -0
- package/dist/esm/dt/final/TCurrencyISO4217.js +1 -0
- package/dist/esm/dt/final/TDateTimeFormat.js +1 -0
- package/dist/esm/dt/final/TEmail.js +2 -0
- package/dist/esm/dt/final/TEmoji.js +4 -0
- package/dist/esm/dt/final/TFile.js +3 -0
- package/dist/esm/dt/final/THostAddress.js +2 -0
- package/dist/esm/dt/final/TIPv6.js +1 -0
- package/dist/esm/dt/final/TJWT.js +8 -0
- package/dist/esm/dt/final/TPercentage.js +5 -0
- package/dist/esm/dt/final/TSQLQuery.js +1 -0
- package/dist/esm/dt/final/TSSHPrivateKey.js +3 -1
- package/dist/esm/dt/final/TSemVerVersion.js +1 -0
- package/dist/esm/dt/final/TShellCommand.js +1 -0
- package/dist/esm/dt/final/TURL.js +2 -0
- package/dist/esm/dt/final/TUUID.js +1 -0
- package/dist/esm/dt/final/TYesNo.js +1 -1
- package/dist/esm/i18n/WordingManager.d.ts +16 -0
- package/dist/esm/i18n/types.d.ts +5 -0
- package/dist/esm/icon/Icon.d.ts +7 -0
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/product/manifest.d.ts +15 -0
- package/dist/esm/products/Helper/index.js +3 -0
- package/dist/esm/products/Helper/manifest.d.ts +6 -1
- package/dist/esm/std/BufferManager.d.ts +18 -0
- package/dist/esm/std/ClockManager.d.ts +5 -0
- package/dist/esm/std/EnvironmentManager.d.ts +10 -0
- package/dist/esm/std/HTTPAPICaller.d.ts +6 -0
- package/dist/esm/std/I18nManager.d.ts +26 -0
- package/dist/esm/std/JWTManager.d.ts +26 -0
- package/dist/esm/std/JobManager.d.ts +6 -0
- package/dist/esm/std/LLMManager.d.ts +25 -0
- package/dist/esm/std/LLMManager.js +1 -0
- package/dist/esm/std/PromptManager.d.ts +8 -0
- package/dist/esm/std/SettingsManager.d.ts +19 -0
- package/dist/esm/std/SettingsManager.js +9 -0
- package/dist/esm/std/impl/ConsoleLogger.js +7 -1
- package/dist/esm/std/impl/FakeEmailManager.js +1 -0
- package/dist/esm/std/impl/FakeJobManager.js +1 -0
- package/dist/esm/std/impl/FetchHTTPAPICallExecutor.d.ts +9 -0
- package/dist/esm/std/impl/FetchHTTPAPICallExecutor.js +11 -0
- package/dist/esm/std/impl/MistralAILLMManager.d.ts +17 -0
- package/dist/esm/std/impl/MistralAILLMManager.js +56 -0
- package/dist/esm/std/impl/NodeCryptoManager.js +6 -1
- package/dist/esm/std/impl/NodeDeterministicCryptoManager.d.ts +14 -0
- package/dist/esm/std/impl/NodeDeterministicCryptoManager.js +17 -3
- package/dist/esm/std/impl/NodeFSManager.js +10 -0
- package/dist/esm/std/impl/NodeHTTPAPICallExecutorAgentBuilder.js +2 -0
- package/dist/esm/std/impl/NodePromptManager.js +3 -0
- package/dist/esm/std/impl/OllamaLLMManager.d.ts +20 -0
- package/dist/esm/std/impl/OllamaLLMManager.js +56 -0
- package/dist/esm/std/impl/OpenAILLMManager.d.ts +17 -0
- package/dist/esm/std/impl/OpenAILLMManager.js +51 -0
- package/dist/esm/std/impl/SimpleHTTPAPICaller.js +14 -0
- package/dist/esm/std/impl/SimpleMapI18nManager.js +4 -2
- package/dist/esm/std/impl/StdDateClockManager.js +3 -0
- package/dist/esm/std/impl/UCDataStoreExternalResourceManager.js +3 -0
- package/dist/esm/std/impl/WebCryptoManager.js +9 -0
- package/dist/esm/std/index.d.ts +1 -0
- package/dist/esm/std/index.js +1 -0
- package/dist/esm/target/lib/cli/renderer.js +3 -0
- package/dist/esm/target/lib/client/consts.d.ts +3 -0
- package/dist/esm/target/lib/client/consts.js +3 -0
- package/dist/esm/target/lib/mcp-server/MCPServerBooter.js +1 -0
- package/dist/esm/target/lib/react/UCContainer.js +1 -0
- package/dist/esm/target/lib/react/UCPanel.js +4 -0
- package/dist/esm/target/lib/react/useUC.d.ts +8 -0
- package/dist/esm/target/lib/react/useUC.js +22 -0
- package/dist/esm/target/lib/react/useUCOR.d.ts +15 -0
- package/dist/esm/target/lib/react/useUCOR.js +45 -0
- package/dist/esm/target/lib/rn/input.d.ts +7 -0
- package/dist/esm/target/lib/rn/input.js +2 -0
- package/dist/esm/target/lib/server/AuthenticationChecker.js +2 -1
- package/dist/esm/target/lib/server/BasicAuthenticationChecker.js +1 -0
- package/dist/esm/target/lib/server/CSPDirectivesBuilder.js +13 -0
- package/dist/esm/target/lib/server/CustomerFacingErrorBuilder.js +3 -0
- package/dist/esm/target/lib/server/PrivateApiKeyAuthenticationChecker.js +1 -0
- package/dist/esm/target/lib/server/PublicApiKeyChecker.js +1 -1
- package/dist/esm/target/lib/server/RequestChecker.js +5 -4
- package/dist/esm/target/lib/server/RequestHandler.d.ts +5 -0
- package/dist/esm/target/lib/server/RequestLogger.js +5 -0
- package/dist/esm/target/lib/server/ServerManager.d.ts +19 -0
- package/dist/esm/target/lib/server/consts.d.ts +3 -0
- package/dist/esm/target/lib/server/consts.js +3 -0
- package/dist/esm/target/lib/web/input.d.ts +21 -0
- package/dist/esm/target/lib/web/input.js +4 -0
- package/dist/esm/target/node-core-cli/NodeCoreCLIManager.js +2 -2
- package/dist/esm/target/node-express-server/NodeExpressServerManager.js +5 -0
- package/dist/esm/target/node-express-server/lib/AuthCookieCreator.js +1 -1
- package/dist/esm/target/node-express-server/middlewares/AuthenticationCheckerMiddlewareBuilder.js +1 -0
- package/dist/esm/target/node-express-server/middlewares/PublicApiKeyCheckerMiddlewareBuilder.js +1 -0
- package/dist/esm/target/node-express-server/middlewares/RequestCheckerMiddlewareBuilder.js +1 -0
- package/dist/esm/target/node-express-server/middlewares/RequestHandlerMiddlewareBuilder.js +8 -0
- package/dist/esm/target/node-express-server/middlewares/RequestLoggerMiddlewareBuilder.js +1 -0
- package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.d.ts +10 -0
- package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.js +14 -0
- package/dist/esm/target/react-native-pure/UCFormFieldControl.js +1 -0
- package/dist/esm/testing/AppTester.d.ts +4 -0
- package/dist/esm/testing/AppTester.js +16 -0
- package/dist/esm/testing/AppTesterConfigurator.d.ts +68 -0
- package/dist/esm/testing/UCDataStoreTester.d.ts +9 -0
- package/dist/esm/testing/UCDataStoreTester.js +13 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter.js +22 -2
- package/dist/esm/testing/impl/SimpleAppTesterConfigurator.js +1 -0
- package/dist/esm/testing/impl/SimpleHTMLAppTestReportEmitter.js +9 -3
- package/dist/esm/testing/impl/TypeScriptLibUCDefASTParser.js +12 -4
- package/dist/esm/testing/impl/VitestAppTestSuiteEmitter.js +6 -0
- package/dist/esm/testing/opts.d.ts +38 -0
- package/dist/esm/testing/opts.js +1 -1
- package/dist/esm/testing/uc-input.js +2 -0
- package/dist/esm/testing/workers/AppTesterCtxInitializer.js +7 -0
- package/dist/esm/testing/workers/UCExecutor.js +1 -0
- package/dist/esm/testing/workers/checkers/AppIndexChecker.js +1 -0
- package/dist/esm/testing/workers/checkers/UCDefSourcesChecker.js +4 -0
- package/dist/esm/uc/UC.js +19 -1
- package/dist/esm/uc/UCInputField.d.ts +28 -0
- package/dist/esm/uc/UCInputField.js +42 -0
- package/dist/esm/uc/data.d.ts +3 -0
- package/dist/esm/uc/def.d.ts +7 -0
- package/dist/esm/uc/exec.d.ts +39 -0
- package/dist/esm/uc/exec.js +29 -0
- package/dist/esm/uc/ext.d.ts +30 -1
- package/dist/esm/uc/helpers/UCOutputBuilder.js +5 -0
- package/dist/esm/uc/helpers/UCOutputReader.js +3 -1
- package/dist/esm/uc/impl/HTTPUCTransporter.js +4 -0
- package/dist/esm/uc/impl/InMemoryUCDataStore.js +7 -0
- package/dist/esm/uc/impl/KnexUCDataStore.d.ts +4 -0
- package/dist/esm/uc/impl/KnexUCDataStore.js +14 -0
- package/dist/esm/uc/impl/SimpleUCManager.js +6 -0
- package/dist/esm/uc/input-field.d.ts +60 -0
- package/dist/esm/uc/input-field.js +33 -0
- package/dist/esm/uc/input.d.ts +24 -0
- package/dist/esm/uc/lifecycle/client/IdleClientMain.js +1 -0
- package/dist/esm/uc/lifecycle/server/IdleServerMain.js +2 -0
- package/dist/esm/uc/manager.d.ts +11 -0
- package/dist/esm/uc/metadata.d.ts +10 -0
- package/dist/esm/uc/opi-layout.d.ts +3 -0
- package/dist/esm/uc/opi.d.ts +8 -0
- package/dist/esm/uc/output-field.d.ts +9 -0
- package/dist/esm/uc/output-part.d.ts +22 -0
- package/dist/esm/uc/output.d.ts +3 -0
- package/dist/esm/uc/policies/RoleRegularUCPolicy.js +1 -0
- package/dist/esm/uc/policies/funcs.js +1 -0
- package/dist/esm/uc/policy.d.ts +22 -0
- package/dist/esm/uc/sec.d.ts +9 -0
- package/dist/esm/uc/server.d.ts +10 -0
- package/dist/esm/uc/settings.d.ts +25 -0
- package/dist/esm/uc/side-effect.d.ts +16 -0
- package/dist/esm/uc/side-effect.js +16 -0
- package/dist/esm/uc/utils/rInput.d.ts +12 -0
- package/dist/esm/uc/utils/rInput.js +2 -0
- package/dist/esm/uc/utils/rVal.d.ts +25 -0
- package/dist/esm/uc/utils/rVal.js +27 -0
- package/dist/esm/uc/utils/recIs.d.ts +9 -0
- package/dist/esm/uc/utils/recIs.js +12 -1
- package/dist/esm/uc/utils/stripUCDLifecycleServer.d.ts +13 -0
- package/dist/esm/uc/utils/stripUCDLifecycleServer.js +17 -0
- package/dist/esm/uc/utils/ucifcoIsForArray.d.ts +6 -0
- package/dist/esm/uc/utils/ucifcoIsForArray.js +6 -0
- package/dist/esm/uc/workers/SimpleAggregateFinder.d.ts +12 -0
- package/dist/esm/uc/workers/SimpleAggregateFinder.js +12 -0
- package/dist/esm/uc/workers/UCBuilder.d.ts +7 -0
- package/dist/esm/uc/workers/UCBuilder.js +7 -0
- package/dist/esm/uc/workers/UCExecChecker.js +2 -0
- package/dist/esm/uc/workers/UCInputFilesProcessor.js +10 -4
- package/dist/esm/uc/workers/UCOutputFilesProcessor.js +6 -2
- package/dist/esm/utils/async/sleep.d.ts +10 -0
- package/dist/esm/utils/async/sleep.js +10 -0
- package/dist/esm/utils/http/appendData.js +5 -1
- package/dist/esm/utils/ioc/ContainerPrinter.js +2 -0
- package/dist/esm/utils/ioc/bindCommon.js +4 -0
- package/dist/esm/utils/ioc/bindNodeCLI.js +2 -0
- package/dist/esm/utils/ioc/bindNodeCore.js +1 -0
- package/dist/esm/utils/ioc/bindProduct.js +2 -0
- package/dist/esm/utils/ioc/bindRN.js +1 -0
- package/dist/esm/utils/ioc/bindServer.js +1 -0
- package/dist/esm/utils/ioc/bindWeb.js +2 -0
- package/dist/esm/utils/ioc/container.js +6 -0
- package/dist/esm/utils/numbers/units.js +3 -0
- package/dist/esm/utils/types/funcs.d.ts +35 -0
- package/dist/esm/utils/types/funcs.js +35 -0
- package/dist/esm/utils/types/utility-types.d.ts +17 -0
- package/dist/esm/utils/types/utility-types.js +1 -0
- package/package.json +9 -9
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { inject, injectable } from 'inversify';
|
|
14
|
+
import { IllegalArgumentError } from '../../error/index.js';
|
|
15
|
+
let OllamaLLMManager = class OllamaLLMManager {
|
|
16
|
+
httpAPICaller;
|
|
17
|
+
settingsManager;
|
|
18
|
+
constructor(httpAPICaller, settingsManager) {
|
|
19
|
+
this.httpAPICaller = httpAPICaller;
|
|
20
|
+
this.settingsManager = settingsManager;
|
|
21
|
+
}
|
|
22
|
+
s() {
|
|
23
|
+
return {
|
|
24
|
+
oll_base_url: this.settingsManager.get()('oll_base_url'),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
async send(req) {
|
|
28
|
+
const firstMessage = req.messages[0];
|
|
29
|
+
if (!firstMessage) {
|
|
30
|
+
throw new IllegalArgumentError('Please provide at least one message');
|
|
31
|
+
}
|
|
32
|
+
return await this.httpAPICaller.exec({
|
|
33
|
+
errBuilder: async (error) => error.error,
|
|
34
|
+
method: 'POST',
|
|
35
|
+
outputBuilder: async (res) => ({
|
|
36
|
+
choices: [{ message: { content: res.response } }],
|
|
37
|
+
}),
|
|
38
|
+
req: {
|
|
39
|
+
envelope: 'json',
|
|
40
|
+
builder: async () => ({
|
|
41
|
+
model: req.model,
|
|
42
|
+
prompt: firstMessage.content,
|
|
43
|
+
stream: false,
|
|
44
|
+
}),
|
|
45
|
+
},
|
|
46
|
+
urlBuilder: async () => `${this.s().oll_base_url}/api/generate`,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
OllamaLLMManager = __decorate([
|
|
51
|
+
injectable(),
|
|
52
|
+
__param(0, inject('HTTPAPICaller')),
|
|
53
|
+
__param(1, inject('SettingsManager')),
|
|
54
|
+
__metadata("design:paramtypes", [Object, Object])
|
|
55
|
+
], OllamaLLMManager);
|
|
56
|
+
export { OllamaLLMManager };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ApiKey } from '../../dt/index.js';
|
|
2
|
+
import type { HTTPAPICaller } from '../HTTPAPICaller.js';
|
|
3
|
+
import type { LLMManager, LLMManagerSendReq, LLMManagerSendRes } from '../LLMManager.js';
|
|
4
|
+
import type { Configurable, Settings, SettingsManager } from '../SettingsManager.js';
|
|
5
|
+
export interface OpenAILLMManagerSettings extends Settings {
|
|
6
|
+
oai_api_key: ApiKey;
|
|
7
|
+
}
|
|
8
|
+
type S = OpenAILLMManagerSettings;
|
|
9
|
+
export declare class OpenAILLMManager implements Configurable<S>, LLMManager {
|
|
10
|
+
private httpAPICaller;
|
|
11
|
+
private settingsManager;
|
|
12
|
+
private static BASE_URL;
|
|
13
|
+
constructor(httpAPICaller: HTTPAPICaller, settingsManager: SettingsManager<S>);
|
|
14
|
+
s(): OpenAILLMManagerSettings;
|
|
15
|
+
send(req: LLMManagerSendReq): Promise<LLMManagerSendRes>;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
var OpenAILLMManager_1;
|
|
14
|
+
import { inject, injectable } from 'inversify';
|
|
15
|
+
let OpenAILLMManager = class OpenAILLMManager {
|
|
16
|
+
static { OpenAILLMManager_1 = this; }
|
|
17
|
+
httpAPICaller;
|
|
18
|
+
settingsManager;
|
|
19
|
+
static BASE_URL = 'https://api.openai.com/v1';
|
|
20
|
+
constructor(httpAPICaller, settingsManager) {
|
|
21
|
+
this.httpAPICaller = httpAPICaller;
|
|
22
|
+
this.settingsManager = settingsManager;
|
|
23
|
+
}
|
|
24
|
+
s() {
|
|
25
|
+
return {
|
|
26
|
+
oai_api_key: this.settingsManager.get()('oai_api_key'),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async send(req) {
|
|
30
|
+
return await this.httpAPICaller.exec({
|
|
31
|
+
authorizationHeader: {
|
|
32
|
+
value: this.s().oai_api_key,
|
|
33
|
+
prefix: 'Bearer',
|
|
34
|
+
},
|
|
35
|
+
errBuilder: async (error) => error.error.message,
|
|
36
|
+
method: 'POST',
|
|
37
|
+
req: {
|
|
38
|
+
envelope: 'json',
|
|
39
|
+
builder: async () => req,
|
|
40
|
+
},
|
|
41
|
+
urlBuilder: async () => `${OpenAILLMManager_1.BASE_URL}/chat/completions`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
OpenAILLMManager = OpenAILLMManager_1 = __decorate([
|
|
46
|
+
injectable(),
|
|
47
|
+
__param(0, inject('HTTPAPICaller')),
|
|
48
|
+
__param(1, inject('SettingsManager')),
|
|
49
|
+
__metadata("design:paramtypes", [Object, Object])
|
|
50
|
+
], OpenAILLMManager);
|
|
51
|
+
export { OpenAILLMManager };
|
|
@@ -64,6 +64,7 @@ let SimpleHTTPAPICaller = class SimpleHTTPAPICaller {
|
|
|
64
64
|
if (status === 202 || status === 204) {
|
|
65
65
|
return {};
|
|
66
66
|
}
|
|
67
|
+
// Using .startsWith instead of === because the value can look like this 'application/json; charset=utf-8'
|
|
67
68
|
const responseContentType = headers.get('Content-Type');
|
|
68
69
|
const isJSON = responseContentType?.startsWith('application/json');
|
|
69
70
|
const isFormURLEncoded = responseContentType?.startsWith('application/x-www-form-urlencoded');
|
|
@@ -87,6 +88,10 @@ let SimpleHTTPAPICaller = class SimpleHTTPAPICaller {
|
|
|
87
88
|
async computeHeaders({ additionalHeadersBuilder, authorizationHeader, basicAuth, contentType = 'application/json', req, }) {
|
|
88
89
|
const headers = {};
|
|
89
90
|
if (req?.envelope !== 'form-data') {
|
|
91
|
+
// The boundary needs to be set when sending data this way, so the server can understand how to read it (Source : https://stackoverflow.com/a/20321259/1259118)
|
|
92
|
+
// In RN, the content-type we set is automatically overriden by the internal fetch client (i.e. 'content-type': 'multipart/form-data; boundary=7ZsqoHiTstShSc4-Yi4U7ier3GPc_4QL5iN2eT9rnSNd0g1UoFPgt3I6.fsWlV8YpJhFkG')
|
|
93
|
+
// In CLI, if it is set, it's not overriden. So it creates problems. With 'form-data', we send 'content-type': 'multipart/form-data'` but the server expects something like 'content-type': 'multipart/form-data;boundary=--------------------------743913816161509008636675'
|
|
94
|
+
// So we don't set it at all and we're good to go.
|
|
90
95
|
headers['Content-Type'] = contentType;
|
|
91
96
|
}
|
|
92
97
|
if (authorizationHeader) {
|
|
@@ -110,6 +115,8 @@ let SimpleHTTPAPICaller = class SimpleHTTPAPICaller {
|
|
|
110
115
|
return headers;
|
|
111
116
|
}
|
|
112
117
|
async processResBad({ errBuilder, opts, }, isJSON, isXML, response) {
|
|
118
|
+
// NOTE : This method must handle all possible cases and never throw
|
|
119
|
+
// Indeed, it's supposed to handle the errors so it shouldn't throw one
|
|
113
120
|
let error;
|
|
114
121
|
try {
|
|
115
122
|
if (isJSON) {
|
|
@@ -134,6 +141,7 @@ let SimpleHTTPAPICaller = class SimpleHTTPAPICaller {
|
|
|
134
141
|
return null;
|
|
135
142
|
}
|
|
136
143
|
if (typeof error === 'string') {
|
|
144
|
+
// For example, it can be from `asText`, containing funny formatting (developers and errors you know...)
|
|
137
145
|
return error.trim();
|
|
138
146
|
}
|
|
139
147
|
if (!error) {
|
|
@@ -144,10 +152,14 @@ let SimpleHTTPAPICaller = class SimpleHTTPAPICaller {
|
|
|
144
152
|
if (typeof message === 'string') {
|
|
145
153
|
return message;
|
|
146
154
|
}
|
|
155
|
+
// Case where `errBuilder` is of type (error: string) => string
|
|
156
|
+
// If an object is passed to it, it would return an object instead, interpreted incorrectly as [object Object] by error handlers
|
|
147
157
|
return JSON.stringify(message);
|
|
148
158
|
}
|
|
149
159
|
catch (err) {
|
|
150
160
|
this.logger.error(err);
|
|
161
|
+
// Case where `errBuilder` is of type (error: Object) => string
|
|
162
|
+
// If an object of another shape is passed to it, it would trigger some TypeError or cannot call .message of undefined
|
|
151
163
|
return JSON.stringify(error);
|
|
152
164
|
}
|
|
153
165
|
}
|
|
@@ -163,7 +175,9 @@ let SimpleHTTPAPICaller = class SimpleHTTPAPICaller {
|
|
|
163
175
|
});
|
|
164
176
|
if (isFormURLEncoded) {
|
|
165
177
|
payload = {};
|
|
178
|
+
// TODO : Find a better way to do this (without adding any external dependency because the code must be portable)
|
|
166
179
|
new URL(`http://localhost?${asText}`).searchParams.forEach((v, k) => {
|
|
180
|
+
// @ts-ignore
|
|
167
181
|
payload[k] = v;
|
|
168
182
|
});
|
|
169
183
|
}
|
|
@@ -17,7 +17,7 @@ let SimpleMapI18nManager = class SimpleMapI18nManager {
|
|
|
17
17
|
static { SimpleMapI18nManager_1 = this; }
|
|
18
18
|
i18n;
|
|
19
19
|
logger;
|
|
20
|
-
static PLACEHOLDERS_REGEX = /{{([A-Z-a-z0-9]+)}}/g;
|
|
20
|
+
static PLACEHOLDERS_REGEX = /{{([A-Z-a-z0-9]+)}}/g; // Note the 'g' so it can be used with `matchAll`
|
|
21
21
|
entries;
|
|
22
22
|
constructor(i18n, logger) {
|
|
23
23
|
this.i18n = i18n;
|
|
@@ -48,12 +48,14 @@ let SimpleMapI18nManager = class SimpleMapI18nManager {
|
|
|
48
48
|
if (opts?.fallback) {
|
|
49
49
|
return opts.fallback;
|
|
50
50
|
}
|
|
51
|
-
return key;
|
|
51
|
+
return key; // Mimic the behavior of some common libraries like i18next
|
|
52
52
|
}
|
|
53
53
|
tOrNull(key, _opts) {
|
|
54
54
|
return this.entries.get(key) || null;
|
|
55
55
|
}
|
|
56
56
|
replacePlaceholders(v, opts) {
|
|
57
|
+
// DO NOT USE THIS IN PRODUCTION
|
|
58
|
+
// The purpose of it is to have a simple and dependency-less implementation, to play with
|
|
57
59
|
let res = v;
|
|
58
60
|
const placeholders = res.matchAll(SimpleMapI18nManager_1.PLACEHOLDERS_REGEX);
|
|
59
61
|
for (const [placeholder, key] of placeholders) {
|
|
@@ -10,6 +10,9 @@ let StdDateClockManager = class StdDateClockManager {
|
|
|
10
10
|
return new Date();
|
|
11
11
|
}
|
|
12
12
|
nowToKey() {
|
|
13
|
+
// The rationale behind this being hardcoded is to avoid adding a library (luxon, date-fns) just for that.
|
|
14
|
+
// For instance, luxon adds a huge amount of code to a basic web target when bundled, for nothing.
|
|
15
|
+
// See https://github.com/moment/luxon/issues/854#issuecomment-1729384672
|
|
13
16
|
return this.now()
|
|
14
17
|
.toISOString()
|
|
15
18
|
.replaceAll(/-|T|:/g, '')
|
|
@@ -11,6 +11,9 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
13
|
import { inject, injectable } from 'inversify';
|
|
14
|
+
// TODO : Wait for the DB to be ready or add a retry mechanism
|
|
15
|
+
// Because when we start from a fresh install, this is executed before the docker container is ready
|
|
16
|
+
// A temporary workaround is to stop and restart everything. At the 2nd startup, the db is ready, and it works
|
|
14
17
|
let UCDataStoreExternalResourceManager = class UCDataStoreExternalResourceManager {
|
|
15
18
|
ucDataStore;
|
|
16
19
|
constructor(ucDataStore) {
|
|
@@ -10,6 +10,7 @@ const DIGEST_MAPPING = new Map([
|
|
|
10
10
|
]);
|
|
11
11
|
let WebCryptoManager = class WebCryptoManager {
|
|
12
12
|
async clear() {
|
|
13
|
+
// Nothing to do
|
|
13
14
|
}
|
|
14
15
|
hash(_algorithm, _base) {
|
|
15
16
|
throw new Error('Method not implemented.');
|
|
@@ -25,9 +26,13 @@ let WebCryptoManager = class WebCryptoManager {
|
|
|
25
26
|
if (!hash) {
|
|
26
27
|
throw new Error(`Digest ${digest} is not valid for WebCryptoManager`);
|
|
27
28
|
}
|
|
29
|
+
// "Secure context: This feature is available only in secure contexts (HTTPS), in some or all supporting browsers."
|
|
30
|
+
// Warning: This API provides a number of low-level cryptographic primitives. It's very easy to misuse them, and the pitfalls involved can be very subtle.
|
|
31
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
|
|
28
32
|
const textEncoder = new TextEncoder();
|
|
29
33
|
const passwordKey = await crypto.subtle.importKey('raw', textEncoder.encode(password), 'PBKDF2', false, ['deriveBits']);
|
|
30
34
|
const result = await crypto.subtle.deriveBits({
|
|
35
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Pbkdf2Params
|
|
31
36
|
hash,
|
|
32
37
|
iterations: iterationsCount,
|
|
33
38
|
name: 'PBKDF2',
|
|
@@ -36,9 +41,11 @@ let WebCryptoManager = class WebCryptoManager {
|
|
|
36
41
|
return new Uint8Array(result);
|
|
37
42
|
}
|
|
38
43
|
async randomString(length) {
|
|
44
|
+
// Not perfect in terms of randomness (because of Math.random() but pretty fine for now)
|
|
39
45
|
let res = '';
|
|
40
46
|
while (res.length < length) {
|
|
41
47
|
const next = Math.random().toString(36).slice(2, 3);
|
|
48
|
+
// For now, we want only chars at the beginning, so it can be used as an identifier (i.e. in a database)
|
|
42
49
|
if (res.length === 0 &&
|
|
43
50
|
Number.isInteger(Number.parseInt(next, 10))) {
|
|
44
51
|
continue;
|
|
@@ -48,6 +55,8 @@ let WebCryptoManager = class WebCryptoManager {
|
|
|
48
55
|
return res;
|
|
49
56
|
}
|
|
50
57
|
randomUUID() {
|
|
58
|
+
// "Secure context: This feature is available only in secure contexts (HTTPS), in some or all supporting browsers."
|
|
59
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Crypto/randomUUID
|
|
51
60
|
return crypto.randomUUID();
|
|
52
61
|
}
|
|
53
62
|
async scrypt() {
|
package/dist/esm/std/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export * from './HTTPAPICallExecutor.js';
|
|
|
13
13
|
export * from './I18nManager.js';
|
|
14
14
|
export * from './JobManager.js';
|
|
15
15
|
export * from './JWTManager.js';
|
|
16
|
+
export * from './LLMManager.js';
|
|
16
17
|
export * from './Logger.js';
|
|
17
18
|
export * from './PromptManager.js';
|
|
18
19
|
export * from './SettingsManager.js';
|
package/dist/esm/std/index.js
CHANGED
|
@@ -13,6 +13,7 @@ export * from './HTTPAPICallExecutor.js';
|
|
|
13
13
|
export * from './I18nManager.js';
|
|
14
14
|
export * from './JobManager.js';
|
|
15
15
|
export * from './JWTManager.js';
|
|
16
|
+
export * from './LLMManager.js';
|
|
16
17
|
export * from './Logger.js';
|
|
17
18
|
export * from './PromptManager.js';
|
|
18
19
|
export * from './SettingsManager.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CustomError } from '../../../error/index.js';
|
|
2
2
|
export function print(line) {
|
|
3
|
+
// biome-ignore lint/suspicious/noConsole: we want it
|
|
3
4
|
console.info(line);
|
|
4
5
|
}
|
|
5
6
|
export function printError(err) {
|
|
@@ -7,11 +8,13 @@ export function printError(err) {
|
|
|
7
8
|
if (err instanceof Error) {
|
|
8
9
|
message = err.message;
|
|
9
10
|
if (!(err instanceof CustomError)) {
|
|
11
|
+
// biome-ignore lint/suspicious/noConsole: we want it
|
|
10
12
|
console.error(err);
|
|
11
13
|
}
|
|
12
14
|
}
|
|
13
15
|
else if (typeof err === 'string') {
|
|
14
16
|
message = err;
|
|
15
17
|
}
|
|
18
|
+
// biome-ignore lint/suspicious/noConsole: we want it
|
|
16
19
|
console.error(message);
|
|
17
20
|
}
|
|
@@ -32,6 +32,7 @@ let MCPServerBooter = class MCPServerBooter {
|
|
|
32
32
|
srcImporter,
|
|
33
33
|
});
|
|
34
34
|
for await (const uc of ucs) {
|
|
35
|
+
// Declared only for compatibility with ServerManager's contract but not used
|
|
35
36
|
const contract = ucHTTPContract(uc);
|
|
36
37
|
await this.ucManager.initServer(uc);
|
|
37
38
|
await this.serverManager.mount(uc.appManifest, uc.def, contract);
|
|
@@ -33,6 +33,9 @@ export function UCPanel({ autoExec = false, clearAfterExec = true, onDone, onErr
|
|
|
33
33
|
};
|
|
34
34
|
const onSubmit = async () => {
|
|
35
35
|
setExecState('submitting');
|
|
36
|
+
// Is some targets, the confirmClient blocks the main thread (e.g. window.confirm()).
|
|
37
|
+
// This leads to the state set above not being updated.
|
|
38
|
+
// This is a "hacky" workaroud to let React re-render the control with 'submitting' state before
|
|
36
39
|
await sleep(100);
|
|
37
40
|
await onStartSubmitting?.();
|
|
38
41
|
const confirmed = await ucManager.confirmClient(uc);
|
|
@@ -62,6 +65,7 @@ export function UCPanel({ autoExec = false, clearAfterExec = true, onDone, onErr
|
|
|
62
65
|
};
|
|
63
66
|
const disabled = ucIsDisabled(execState);
|
|
64
67
|
const loading = ucIsLoading(execState);
|
|
68
|
+
// TODO : Keep these as a state to avoid recomputation
|
|
65
69
|
const ctx = {
|
|
66
70
|
clearAfterExec,
|
|
67
71
|
disabled,
|
|
@@ -2,6 +2,14 @@ import { type ArgsRecord, UC, type UCDef, type UCInput, type UCOPIBase } from '.
|
|
|
2
2
|
type CloneFunc<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = (i: Partial<I>) => UC<I, OPI0, OPI1>;
|
|
3
3
|
type DivertFunc<II extends UCInput | undefined = undefined, OOPI0 extends UCOPIBase | undefined = undefined, OOPI1 extends UCOPIBase | undefined = undefined> = (siblingUCD: UCDef) => UC<II, OOPI0, OOPI1>;
|
|
4
4
|
type RefillFunc<I extends UCInput | undefined = undefined> = (i: Partial<I>) => void;
|
|
5
|
+
/**
|
|
6
|
+
* This hook provides utilities to init a use case and perform actions on it in a React way
|
|
7
|
+
* @param appManifest
|
|
8
|
+
* @param def
|
|
9
|
+
* @param auth
|
|
10
|
+
* @param opts
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
5
13
|
export declare function useUC<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: ArgsRecord<I, OPI0, OPI1>['appManifest'], def: ArgsRecord<I, OPI0, OPI1>['def'], auth: ArgsRecord<I, OPI0, OPI1>['auth'], opts?: {
|
|
6
14
|
fillWith: Partial<I>;
|
|
7
15
|
}): [
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
2
|
import { UC, } from '../../../uc/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* This hook provides utilities to init a use case and perform actions on it in a React way
|
|
5
|
+
* @param appManifest
|
|
6
|
+
* @param def
|
|
7
|
+
* @param auth
|
|
8
|
+
* @param opts
|
|
9
|
+
* @returns
|
|
10
|
+
*/
|
|
3
11
|
export function useUC(appManifest, def, auth, opts) {
|
|
4
12
|
const [uc, setUC] = useState(() => {
|
|
5
13
|
const { name: appName, ucReg } = appManifest;
|
|
@@ -13,8 +21,22 @@ export function useUC(appManifest, def, auth, opts) {
|
|
|
13
21
|
}
|
|
14
22
|
return v;
|
|
15
23
|
});
|
|
24
|
+
/**
|
|
25
|
+
* Get a new `UC` based on the initial one
|
|
26
|
+
* @param i
|
|
27
|
+
* @returns
|
|
28
|
+
*/
|
|
16
29
|
const clone = (i) => new UC(uc.appManifest, uc.def, uc.auth).fill(i);
|
|
30
|
+
/**
|
|
31
|
+
* Get a new `UC` based on the "common" settings of the initial one (i.e. `auth`)
|
|
32
|
+
* @param ucd
|
|
33
|
+
* @returns
|
|
34
|
+
*/
|
|
17
35
|
const divert = (siblingUCD) => new UC(uc.appManifest, siblingUCD, uc.auth);
|
|
36
|
+
/**
|
|
37
|
+
* Update the existing `uc` in an immutable way to trigger components re-rendering
|
|
38
|
+
* @param i
|
|
39
|
+
*/
|
|
18
40
|
const refill = (i) => {
|
|
19
41
|
setUC(new UC(uc.appManifest, uc.def, uc.auth).fill(i));
|
|
20
42
|
};
|
|
@@ -2,6 +2,21 @@ import type { UCInput, UCOPIBase, UCOutputReader, UCOutputReaderPart } from '../
|
|
|
2
2
|
type AppendFunc<OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = (ucor: UCOutputReader<any, OPI0, OPI1>) => void;
|
|
3
3
|
type RemoveFunc<OPI extends UCOPIBase> = (item: OPI) => void;
|
|
4
4
|
type UpdateFunc<OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = (ucor: UCOutputReader<any, OPI0, OPI1>) => void;
|
|
5
|
+
/**
|
|
6
|
+
* This hook provides utilities to act on a {@link UCOutputReader} in a React way
|
|
7
|
+
*
|
|
8
|
+
* A usual scenario of this is a "CRUD-like" UI displaying multiple use cases :
|
|
9
|
+
*
|
|
10
|
+
* - A `List` use case to display a collection of items
|
|
11
|
+
* - A `Create` use case to add an item
|
|
12
|
+
* - A `Delete` use case to remove an item
|
|
13
|
+
* - An `Update` use case to update an item
|
|
14
|
+
*
|
|
15
|
+
* Whenever one of this use case is performed, you can use the `ucor` to act on the main UCOR in an immutable way.
|
|
16
|
+
*
|
|
17
|
+
* @param ucor
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
5
20
|
export declare function useUCOR<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(ucor: UCOutputReader<I, OPI0, OPI1>): [
|
|
6
21
|
UCOutputReaderPart<NonNullable<OPI0>> | undefined,
|
|
7
22
|
UCOutputReaderPart<NonNullable<OPI1>> | undefined,
|
|
@@ -39,10 +39,35 @@ function update(a, b) {
|
|
|
39
39
|
items: newItems,
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* This hook provides utilities to act on a {@link UCOutputReader} in a React way
|
|
44
|
+
*
|
|
45
|
+
* A usual scenario of this is a "CRUD-like" UI displaying multiple use cases :
|
|
46
|
+
*
|
|
47
|
+
* - A `List` use case to display a collection of items
|
|
48
|
+
* - A `Create` use case to add an item
|
|
49
|
+
* - A `Delete` use case to remove an item
|
|
50
|
+
* - An `Update` use case to update an item
|
|
51
|
+
*
|
|
52
|
+
* Whenever one of this use case is performed, you can use the `ucor` to act on the main UCOR in an immutable way.
|
|
53
|
+
*
|
|
54
|
+
* @param ucor
|
|
55
|
+
* @returns
|
|
56
|
+
*/
|
|
42
57
|
export function useUCOR(ucor) {
|
|
43
58
|
const [part0, setPart0] = useState(ucor.part0());
|
|
44
59
|
const [part1, setPart1] = useState(ucor.part1());
|
|
60
|
+
/**
|
|
61
|
+
* Append items to part0
|
|
62
|
+
* @param ucor2
|
|
63
|
+
* @returns
|
|
64
|
+
*/
|
|
45
65
|
const append0 = (ucor2) => setPart0((prev) => append(prev, ucor2.part0()));
|
|
66
|
+
/**
|
|
67
|
+
* Append items to part1 (if applicable)
|
|
68
|
+
* @param ucor2
|
|
69
|
+
* @returns
|
|
70
|
+
*/
|
|
46
71
|
const append1 = (ucor2) => setPart1((prev) => {
|
|
47
72
|
const b = ucor2.part1();
|
|
48
73
|
if (!prev || !b) {
|
|
@@ -50,14 +75,34 @@ export function useUCOR(ucor) {
|
|
|
50
75
|
}
|
|
51
76
|
return append(prev, b);
|
|
52
77
|
});
|
|
78
|
+
/**
|
|
79
|
+
* Remove the item from part0
|
|
80
|
+
* @param item
|
|
81
|
+
* @returns
|
|
82
|
+
*/
|
|
53
83
|
const remove0 = (item) => setPart0((prev) => remove(prev, item));
|
|
84
|
+
/**
|
|
85
|
+
* Remove the item from part1 (if applicable)
|
|
86
|
+
* @param item
|
|
87
|
+
* @returns
|
|
88
|
+
*/
|
|
54
89
|
const remove1 = (item) => setPart1((prev) => {
|
|
55
90
|
if (!prev) {
|
|
56
91
|
return;
|
|
57
92
|
}
|
|
58
93
|
return remove(prev, item);
|
|
59
94
|
});
|
|
95
|
+
/**
|
|
96
|
+
* Update items in part0
|
|
97
|
+
* @param ucor2
|
|
98
|
+
* @returns
|
|
99
|
+
*/
|
|
60
100
|
const update0 = (ucor2) => setPart0((prev) => update(prev, ucor2.part0()));
|
|
101
|
+
/**
|
|
102
|
+
* Update items in part1 (if applicable)
|
|
103
|
+
* @param ucor2
|
|
104
|
+
* @returns
|
|
105
|
+
*/
|
|
61
106
|
const update1 = (ucor2) => setPart1((prev) => {
|
|
62
107
|
const b = ucor2.part1();
|
|
63
108
|
if (!prev || !b) {
|
|
@@ -3,6 +3,13 @@ import { type DataType, type ErrorMessage } from '../../../dt/index.js';
|
|
|
3
3
|
import { type UCExecState, type UCInputField } from '../../../uc/index.js';
|
|
4
4
|
export interface RNInputDef {
|
|
5
5
|
internal?: undefined;
|
|
6
|
+
/**
|
|
7
|
+
* Fields that are part of {@link TextInputProps}
|
|
8
|
+
*
|
|
9
|
+
* These are safe to destructure directly in a `<TextInput />` component.
|
|
10
|
+
*
|
|
11
|
+
* @example `<TextInput {...attrs.spec} />`
|
|
12
|
+
*/
|
|
6
13
|
spec?: TextInputProps;
|
|
7
14
|
}
|
|
8
15
|
export declare function rnInputDef<T extends DataType>(field: UCInputField<T>, execState: UCExecState, _errMsg: ErrorMessage | null): RNInputDef;
|
|
@@ -6,12 +6,14 @@ export function rnInputDef(field, execState, _errMsg) {
|
|
|
6
6
|
spec: {},
|
|
7
7
|
};
|
|
8
8
|
if (!def.spec) {
|
|
9
|
+
// Just a guard to safely type the rest of the function without using !
|
|
9
10
|
return def;
|
|
10
11
|
}
|
|
11
12
|
const { key, def: fDef } = field;
|
|
12
13
|
const { type: fType } = fDef;
|
|
13
14
|
def.spec.editable = !ucIsDisabled(execState);
|
|
14
15
|
def.spec.id = ucifId(key);
|
|
16
|
+
// Testing the types by usage probability to make the if/else evaluation stop ideally earlier
|
|
15
17
|
if (fType instanceof TString) {
|
|
16
18
|
const constraints = fType.getConstraints();
|
|
17
19
|
if (constraints) {
|
|
@@ -35,7 +35,7 @@ let AuthenticationChecker = class AuthenticationChecker {
|
|
|
35
35
|
authorizationHeader,
|
|
36
36
|
});
|
|
37
37
|
const output = {
|
|
38
|
-
allowed: false,
|
|
38
|
+
allowed: false, // By default it's not allowed
|
|
39
39
|
auth: null,
|
|
40
40
|
};
|
|
41
41
|
const { lifecycle: { server }, sec, } = uc.def;
|
|
@@ -52,6 +52,7 @@ let AuthenticationChecker = class AuthenticationChecker {
|
|
|
52
52
|
output.allowed = allowed;
|
|
53
53
|
}
|
|
54
54
|
else {
|
|
55
|
+
// Follows the OpenAPI spec : https://swagger.io/docs/specification/authentication
|
|
55
56
|
switch (authType) {
|
|
56
57
|
case 'apiKey':
|
|
57
58
|
if (authorizationHeader &&
|
|
@@ -36,10 +36,23 @@ let CSPDirectivesBuilder = class CSPDirectivesBuilder {
|
|
|
36
36
|
this.logger.info('Default CSP directives', defaultDirectives);
|
|
37
37
|
const directives = { ...defaultDirectives };
|
|
38
38
|
if (!this.environmentManager.isProd()) {
|
|
39
|
+
// In dev mode, we allow ourselves to remove this directive.
|
|
40
|
+
// It is necessary when testing from an external device and accessing the server via 192.168.x.x for example
|
|
41
|
+
// Otherwise the requests are upgraded and it doesn't work since there is no HTTPS in localhost
|
|
42
|
+
// Source : https://stackoverflow.com/questions/66599655/how-to-enable-and-disable-upgradeinsecurerequests-csp-directive-using-helmet-4-4
|
|
39
43
|
this.logger.warn('Disabling upgrade-insecure-requests');
|
|
40
44
|
directives['upgrade-insecure-requests'] = null;
|
|
45
|
+
// In dev mode, NextJS uses eval
|
|
46
|
+
// Enabling it prevents the following error from occurring in the console
|
|
47
|
+
// Uncaught EvalError: call to eval() blocked by CSP NextJS
|
|
48
|
+
// Source : https://github.com/vercel/next.js/discussions/17396
|
|
41
49
|
this.logger.warn('Enabling unsafe-eval');
|
|
42
50
|
directives[CSPDirectivesBuilder_1.SCRIPT_SRC]?.push("'unsafe-eval'");
|
|
51
|
+
// In dev mode, React Dev Tools use inline injection
|
|
52
|
+
// Enabling it prevents the following error from occurring in the console
|
|
53
|
+
// Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”).
|
|
54
|
+
// Download the React DevTools for a better development experience: https://reactjs.org/link/react-devtools
|
|
55
|
+
// Uncaught TypeError: hook.sub is not a function
|
|
43
56
|
this.logger.warn('Enabling unsafe-inline');
|
|
44
57
|
directives[CSPDirectivesBuilder_1.SCRIPT_SRC]?.push("'unsafe-inline'");
|
|
45
58
|
}
|
|
@@ -21,11 +21,14 @@ let CustomerFacingErrorBuilder = class CustomerFacingErrorBuilder {
|
|
|
21
21
|
}
|
|
22
22
|
exec({ error }) {
|
|
23
23
|
if (error instanceof CustomError) {
|
|
24
|
+
// It's already ready to be sent as is
|
|
24
25
|
return {
|
|
25
26
|
error,
|
|
26
27
|
};
|
|
27
28
|
}
|
|
28
29
|
this.logger.error(error);
|
|
30
|
+
// Create a specific generic error to avoid leaking potentially sensitive error
|
|
31
|
+
// We all know the infamous "Cannot connect to MySQL database"...
|
|
29
32
|
return {
|
|
30
33
|
error: new InternalServerError(this.environmentManager.isProd()
|
|
31
34
|
? undefined
|
|
@@ -27,7 +27,7 @@ let PublicApiKeyChecker = class PublicApiKeyChecker {
|
|
|
27
27
|
}
|
|
28
28
|
async exec({ checkType = DEFAULT_UC_SEC_PAKCT, value, }) {
|
|
29
29
|
this.logger.trace('Checking apiKey', { checkType, value });
|
|
30
|
-
let allowed = false;
|
|
30
|
+
let allowed = false; // By default it's not allowed
|
|
31
31
|
switch (checkType) {
|
|
32
32
|
case 'off':
|
|
33
33
|
allowed = true;
|