libmodulor 0.27.0 → 0.29.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 +39 -0
- package/README.md +2 -2
- package/dist/esm/apps/Helper/src/i18n.js +4 -4
- package/dist/esm/apps/Helper/src/lib/layers/project.js +6 -6
- package/dist/esm/apps/Helper/src/ucds/CreateAppUCD.js +5 -10
- package/dist/esm/apps/Helper/src/ucds/CreateProductUCD.js +5 -10
- package/dist/esm/apps/Helper/src/ucds/CreateTargetUCD.js +6 -11
- package/dist/esm/apps/Helper/src/ucds/TestAppUCD.js +5 -8
- package/dist/esm/dt/DataType.d.ts +2 -1
- package/dist/esm/dt/DataTypes.d.ts +1 -1
- package/dist/esm/dt/DataTypes.js +1 -0
- package/dist/esm/dt/base/TBase.d.ts +2 -0
- package/dist/esm/dt/base/TBase.js +5 -0
- package/dist/esm/dt/base/TBoolean.d.ts +2 -0
- package/dist/esm/dt/base/TBoolean.js +3 -0
- package/dist/esm/dt/base/TInt.d.ts +2 -0
- package/dist/esm/dt/base/TInt.js +3 -0
- package/dist/esm/dt/base/TNumber.d.ts +2 -0
- package/dist/esm/dt/base/TNumber.js +3 -0
- package/dist/esm/dt/base/TObject.d.ts +2 -0
- package/dist/esm/dt/base/TObject.js +29 -0
- package/dist/esm/dt/final/TApiKey.d.ts +2 -0
- package/dist/esm/dt/final/TApiKey.js +3 -0
- package/dist/esm/dt/final/TDateISO8601.d.ts +2 -0
- package/dist/esm/dt/final/TDateISO8601.js +3 -0
- package/dist/esm/dt/final/TDomainName.d.ts +2 -0
- package/dist/esm/dt/final/TDomainName.js +3 -0
- package/dist/esm/dt/final/TEmail.d.ts +2 -0
- package/dist/esm/dt/final/TEmail.js +3 -0
- package/dist/esm/dt/final/TEncryptionKey.d.ts +2 -0
- package/dist/esm/dt/final/TEncryptionKey.js +3 -0
- package/dist/esm/dt/final/TErrorCode.d.ts +7 -0
- package/dist/esm/dt/final/TErrorCode.js +9 -0
- package/dist/esm/dt/final/TFile.d.ts +2 -0
- package/dist/esm/dt/final/TFile.js +3 -0
- package/dist/esm/dt/final/TIPv4.d.ts +2 -0
- package/dist/esm/dt/final/TIPv4.js +3 -0
- package/dist/esm/dt/final/TIPv6.d.ts +2 -0
- package/dist/esm/dt/final/TIPv6.js +3 -0
- package/dist/esm/dt/final/TJWT.d.ts +2 -0
- package/dist/esm/dt/final/TJWT.js +3 -0
- package/dist/esm/dt/final/TPassword.d.ts +2 -0
- package/dist/esm/dt/final/TPassword.js +3 -0
- package/dist/esm/dt/final/TSSHPrivateKey.d.ts +2 -0
- package/dist/esm/dt/final/TSSHPrivateKey.js +3 -0
- package/dist/esm/dt/final/TTime.d.ts +2 -0
- package/dist/esm/dt/final/TTime.js +3 -0
- package/dist/esm/dt/final/TURL.d.ts +2 -0
- package/dist/esm/dt/final/TURL.js +3 -0
- package/dist/esm/dt/index.d.ts +2 -0
- package/dist/esm/dt/index.js +1 -0
- package/dist/esm/dt/targets/json-schema.d.ts +24 -0
- package/dist/esm/error/CustomError.d.ts +1 -1
- package/dist/esm/error/CustomError.js +2 -2
- package/dist/esm/error/ForbiddenAsNotFoundError.js +1 -1
- package/dist/esm/error/ForbiddenError.js +1 -1
- package/dist/esm/error/IllegalArgumentError.js +2 -2
- package/dist/esm/error/InternalServerError.js +1 -1
- package/dist/esm/error/NotFoundError.js +1 -1
- package/dist/esm/error/UnauthorizedError.js +1 -1
- package/dist/esm/error/UnavailableError.d.ts +6 -0
- package/dist/esm/error/UnavailableError.js +9 -0
- package/dist/esm/error/funcs.d.ts +3 -0
- package/dist/esm/error/funcs.js +3 -1
- package/dist/esm/error/index.d.ts +2 -1
- package/dist/esm/error/index.js +2 -1
- package/dist/esm/i18n/locales/de.js +8 -0
- package/dist/esm/i18n/locales/en.js +8 -0
- package/dist/esm/i18n/locales/es.js +8 -0
- package/dist/esm/i18n/locales/fr.js +8 -0
- package/dist/esm/i18n/types.d.ts +1 -1
- package/dist/esm/product/manifest.d.ts +2 -0
- package/dist/esm/products/Helper/i18n.d.ts +8 -0
- package/dist/esm/std/impl/SimpleHTTPAPICaller.js +1 -1
- package/dist/esm/std/impl/SimpleMapI18nManager.d.ts +1 -1
- package/dist/esm/std/impl/SimpleMapI18nManager.js +4 -2
- package/dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.d.ts +6 -2
- package/dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.js +17 -9
- package/dist/esm/target/index.d.ts +1 -0
- package/dist/esm/target/lib/cli/CommandExecutor.js +2 -2
- package/dist/esm/target/lib/cli/renderer.d.ts +2 -1
- package/dist/esm/target/lib/cli/renderer.js +10 -11
- package/dist/esm/target/lib/openapi/OpenAPISpecBuilder.d.ts +25 -0
- package/dist/esm/target/lib/openapi/OpenAPISpecBuilder.js +131 -0
- package/dist/esm/target/lib/openapi/consts.d.ts +2 -0
- package/dist/esm/target/lib/openapi/consts.js +1 -0
- package/dist/esm/target/lib/openapi/funcs.d.ts +16 -0
- package/dist/esm/target/lib/openapi/funcs.js +249 -0
- package/dist/esm/target/lib/openapi/input.d.ts +16 -0
- package/dist/esm/target/lib/openapi/input.js +33 -0
- package/dist/esm/target/lib/openapi/types.d.ts +109 -0
- package/dist/esm/target/lib/rn/input.d.ts +3 -0
- package/dist/esm/target/lib/server/AuthCookieCreator.d.ts +2 -1
- package/dist/esm/target/lib/server/AuthenticationChecker.d.ts +3 -3
- package/dist/esm/target/lib/server/AuthenticationChecker.js +5 -5
- package/dist/esm/target/lib/server/ServerBooter.d.ts +4 -2
- package/dist/esm/target/lib/server/ServerBooter.js +34 -11
- package/dist/esm/target/lib/server/ServerManager.d.ts +19 -9
- package/dist/esm/target/lib/server/ServerRequestHandler.d.ts +0 -1
- package/dist/esm/target/lib/server/ServerRequestHandler.js +2 -2
- package/dist/esm/target/lib/server/consts.d.ts +4 -0
- package/dist/esm/target/lib/server/consts.js +22 -0
- package/dist/esm/target/lib/server-express/CORSMiddlewareBuilder.d.ts +15 -0
- package/dist/esm/target/lib/server-express/CORSMiddlewareBuilder.js +55 -0
- package/dist/esm/target/lib/server-express/funcs.d.ts +2 -1
- package/dist/esm/target/lib/server-express/funcs.js +7 -2
- package/dist/esm/target/lib/server-hono/CORSMiddlewareBuilder.d.ts +14 -0
- package/dist/esm/target/{node-express-server/middlewares/PublicApiKeyCheckerMiddlewareBuilder.js → lib/server-hono/CORSMiddlewareBuilder.js} +22 -20
- package/dist/esm/target/lib/server-hono/funcs.d.ts +2 -1
- package/dist/esm/target/lib/server-hono/funcs.js +2 -1
- package/dist/esm/target/lib/shared.d.ts +4 -0
- package/dist/esm/target/lib/shared.js +2 -1
- package/dist/esm/target/nextjs-server/NextJSServerManager.d.ts +3 -1
- package/dist/esm/target/nextjs-server/NextJSServerManager.js +3 -0
- package/dist/esm/target/node-core-cli/NodeCoreCLIManager.js +1 -1
- package/dist/esm/target/node-express-server/NodeExpressServerManager.d.ts +7 -3
- package/dist/esm/target/node-express-server/NodeExpressServerManager.js +24 -14
- package/dist/esm/target/node-hono-server/NodeHonoServerManager.d.ts +6 -2
- package/dist/esm/target/node-hono-server/NodeHonoServerManager.js +21 -11
- package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.d.ts +3 -1
- package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.js +19 -14
- package/dist/esm/target/node-mcp-server/types.d.ts +0 -4
- package/dist/esm/target/react-web-pure/UCForm.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCForm.js +3 -2
- package/dist/esm/testing/workers/checkers/AppI18nChecker.js +4 -2
- package/dist/esm/uc/UC.d.ts +2 -0
- package/dist/esm/uc/UC.js +16 -1
- package/dist/esm/uc/data-store.d.ts +9 -1
- package/dist/esm/uc/data-store.js +33 -1
- package/dist/esm/uc/impl/CloudflareD1UCDataStore.d.ts +2 -2
- package/dist/esm/uc/impl/CloudflareD1UCDataStore.js +7 -0
- package/dist/esm/uc/impl/InMemoryUCDataStore.d.ts +8 -3
- package/dist/esm/uc/impl/InMemoryUCDataStore.js +19 -3
- package/dist/esm/uc/impl/KnexUCDataStore.d.ts +2 -2
- package/dist/esm/uc/impl/KnexUCDataStore.js +10 -2
- package/dist/esm/uc/impl/SimpleUCManager.d.ts +4 -4
- package/dist/esm/uc/impl/SimpleUCManager.js +10 -10
- package/dist/esm/uc/metadata.d.ts +7 -0
- package/dist/esm/uc/metadata.js +10 -0
- package/dist/esm/uc/output-field.d.ts +1 -0
- package/dist/esm/uc/output-field.js +13 -1
- package/dist/esm/uc/settings/consts.js +1 -0
- package/dist/esm/uc/settings.d.ts +8 -1
- package/dist/esm/uc/utils/ucHTTPContract.js +1 -1
- package/dist/esm/uc/workers/UCExecChecker.d.ts +3 -3
- package/dist/esm/uc/workers/UCExecChecker.js +5 -5
- package/dist/esm/utils/http/types.d.ts +5 -0
- package/dist/esm/utils/index.d.ts +2 -2
- package/dist/esm/utils/index.js +1 -1
- package/dist/esm/utils/ioc/bindCommon.js +4 -4
- package/dist/esm/utils/ioc/bindFactory.d.ts +2 -0
- package/dist/esm/utils/ioc/bindFactory.js +9 -0
- package/package.json +21 -20
- package/dist/esm/apps/Helper/src/lib/app.d.ts +0 -6
- package/dist/esm/apps/Helper/src/lib/app.js +0 -12
- package/dist/esm/apps/Helper/src/lib/project.d.ts +0 -3
- package/dist/esm/apps/Helper/src/lib/project.js +0 -163
- package/dist/esm/bundlers/vite/StripUCDLifecycleServerPlugin.d.ts +0 -2
- package/dist/esm/bundlers/vite/StripUCDLifecycleServerPlugin.js +0 -18
- package/dist/esm/products/Helper/cli-node-core/container.d.ts +0 -3
- package/dist/esm/products/Helper/cli-node-core/container.js +0 -26
- package/dist/esm/products/Helper/cli-node-core/index.js +0 -9
- package/dist/esm/products/Helper/container.d.ts +0 -3
- package/dist/esm/products/Helper/container.js +0 -26
- package/dist/esm/products/Helper/index.js +0 -16
- package/dist/esm/target/lib/react/common.d.ts +0 -6
- package/dist/esm/target/lib/react/common.js +0 -1
- package/dist/esm/target/lib/server/RequestHandler.d.ts +0 -14
- package/dist/esm/target/lib/server/RequestHandler.js +0 -1
- package/dist/esm/target/lib/server-node/stop.d.ts +0 -2
- package/dist/esm/target/lib/server-node/stop.js +0 -18
- package/dist/esm/target/node-express-server/lib/AuthCookieCreator.d.ts +0 -21
- package/dist/esm/target/node-express-server/lib/AuthCookieCreator.js +0 -50
- package/dist/esm/target/node-express-server/middlewares/AuthenticationCheckerMiddlewareBuilder.d.ts +0 -21
- package/dist/esm/target/node-express-server/middlewares/AuthenticationCheckerMiddlewareBuilder.js +0 -61
- package/dist/esm/target/node-express-server/middlewares/ErrorMiddlewareBuilder.d.ts +0 -12
- package/dist/esm/target/node-express-server/middlewares/ErrorMiddlewareBuilder.js +0 -35
- package/dist/esm/target/node-express-server/middlewares/HelmetMiddlewareBuilder.d.ts +0 -12
- package/dist/esm/target/node-express-server/middlewares/HelmetMiddlewareBuilder.js +0 -39
- package/dist/esm/target/node-express-server/middlewares/PublicApiKeyCheckerMiddlewareBuilder.d.ts +0 -18
- package/dist/esm/target/node-express-server/middlewares/RequestCheckerMiddlewareBuilder.d.ts +0 -12
- package/dist/esm/target/node-express-server/middlewares/RequestCheckerMiddlewareBuilder.js +0 -36
- package/dist/esm/target/node-express-server/middlewares/RequestHandlerMiddlewareBuilder.d.ts +0 -23
- package/dist/esm/target/node-express-server/middlewares/RequestHandlerMiddlewareBuilder.js +0 -154
- package/dist/esm/target/node-express-server/middlewares/RequestLoggerMiddlewareBuilder.d.ts +0 -13
- package/dist/esm/target/node-express-server/middlewares/RequestLoggerMiddlewareBuilder.js +0 -46
- package/dist/esm/testing/impl/SimpleAppDocsEmitter.d.ts +0 -7
- package/dist/esm/testing/impl/SimpleAppDocsEmitter.js +0 -180
- package/dist/esm/testing/impl/SimpleAppTesterConfigurator.d.ts +0 -14
- package/dist/esm/testing/impl/SimpleAppTesterConfigurator.js +0 -35
- package/dist/esm/uc/utils/stripUCDLifecycleServer.d.ts +0 -15
- package/dist/esm/uc/utils/stripUCDLifecycleServer.js +0 -77
- package/dist/esm/uc/utils/ucifcoIsForArray.d.ts +0 -8
- package/dist/esm/uc/utils/ucifcoIsForArray.js +0 -13
- package/dist/esm/utils/bundling/vite/StripUCDLifecycleServerPlugin.d.ts +0 -2
- package/dist/esm/utils/bundling/vite/StripUCDLifecycleServerPlugin.js +0 -18
- package/dist/esm/utils/http/toFormData.d.ts +0 -3
- package/dist/esm/utils/http/toFormData.js +0 -4
- package/dist/esm/utils/http/toJSON.d.ts +0 -3
- package/dist/esm/utils/http/toJSON.js +0 -3
- package/dist/esm/utils/http/toQueryParams.d.ts +0 -2
- package/dist/esm/utils/http/toQueryParams.js +0 -4
- package/dist/esm/utils/ioc/ContainerPrinter.d.ts +0 -15
- package/dist/esm/utils/ioc/ContainerPrinter.js +0 -58
- package/dist/esm/utils/ioc/bindProvider.d.ts +0 -2
- package/dist/esm/utils/ioc/bindProvider.js +0 -9
- /package/dist/esm/{products/Helper/cli-node-core/index.d.ts → dt/targets/json-schema.js} +0 -0
- /package/dist/esm/{products/Helper/index.d.ts → target/lib/openapi/types.js} +0 -0
|
@@ -11,18 +11,21 @@ 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
|
-
import { NotAvailableError, NotCallableError } from '../../error/index.js';
|
|
14
|
+
import { NotAvailableError, NotCallableError, NotImplementedError, } from '../../error/index.js';
|
|
15
15
|
import { CustomerFacingErrorBuilder } from '../lib/server/CustomerFacingErrorBuilder.js';
|
|
16
16
|
import { ServerRequestHandler } from '../lib/server/ServerRequestHandler.js';
|
|
17
|
+
import { CORSMiddlewareBuilder } from '../lib/server-hono/CORSMiddlewareBuilder.js';
|
|
17
18
|
import { buildHandler, init, mountHandler } from '../lib/server-hono/funcs.js';
|
|
18
19
|
let SyncEdgeWorkerHonoServerManager = class SyncEdgeWorkerHonoServerManager {
|
|
20
|
+
corsMiddlewareBuilder;
|
|
19
21
|
customerFacingErrorBuilder;
|
|
20
22
|
serverRequestHandler;
|
|
21
23
|
settingsManager;
|
|
22
24
|
ucDataStore;
|
|
23
25
|
ucManager;
|
|
24
26
|
runtime;
|
|
25
|
-
constructor(customerFacingErrorBuilder, serverRequestHandler, settingsManager, ucDataStore, ucManager) {
|
|
27
|
+
constructor(corsMiddlewareBuilder, customerFacingErrorBuilder, serverRequestHandler, settingsManager, ucDataStore, ucManager) {
|
|
28
|
+
this.corsMiddlewareBuilder = corsMiddlewareBuilder;
|
|
26
29
|
this.customerFacingErrorBuilder = customerFacingErrorBuilder;
|
|
27
30
|
this.serverRequestHandler = serverRequestHandler;
|
|
28
31
|
this.settingsManager = settingsManager;
|
|
@@ -44,7 +47,7 @@ let SyncEdgeWorkerHonoServerManager = class SyncEdgeWorkerHonoServerManager {
|
|
|
44
47
|
throw new NotCallableError('init', 'initSync', 'sync-only');
|
|
45
48
|
}
|
|
46
49
|
initSync() {
|
|
47
|
-
this.runtime = init(this.customerFacingErrorBuilder);
|
|
50
|
+
this.runtime = init(this.corsMiddlewareBuilder, this.customerFacingErrorBuilder);
|
|
48
51
|
}
|
|
49
52
|
async mount(_appManifest, _ucd, _contract) {
|
|
50
53
|
throw new NotCallableError('mount', 'mountSync', 'sync-only');
|
|
@@ -52,6 +55,9 @@ let SyncEdgeWorkerHonoServerManager = class SyncEdgeWorkerHonoServerManager {
|
|
|
52
55
|
mountSync(appManifest, ucd, contract) {
|
|
53
56
|
mountHandler(contract, this.runtime, buildHandler(appManifest, ucd, contract, this.serverRequestHandler, this.ucManager, (c) => this.beforeExec(c)));
|
|
54
57
|
}
|
|
58
|
+
async mountOpenAPISpec(_spec, _at) {
|
|
59
|
+
throw new NotImplementedError('mountOpenAPISpec');
|
|
60
|
+
}
|
|
55
61
|
async mountStaticDir(_dirPath) {
|
|
56
62
|
throw new NotAvailableError('mountStaticDir');
|
|
57
63
|
}
|
|
@@ -81,12 +87,14 @@ let SyncEdgeWorkerHonoServerManager = class SyncEdgeWorkerHonoServerManager {
|
|
|
81
87
|
};
|
|
82
88
|
SyncEdgeWorkerHonoServerManager = __decorate([
|
|
83
89
|
injectable(),
|
|
84
|
-
__param(0, inject(
|
|
85
|
-
__param(1, inject(
|
|
86
|
-
__param(2, inject(
|
|
87
|
-
__param(3, inject('
|
|
88
|
-
__param(4, inject('
|
|
89
|
-
|
|
90
|
+
__param(0, inject(CORSMiddlewareBuilder)),
|
|
91
|
+
__param(1, inject(CustomerFacingErrorBuilder)),
|
|
92
|
+
__param(2, inject(ServerRequestHandler)),
|
|
93
|
+
__param(3, inject('SettingsManager')),
|
|
94
|
+
__param(4, inject('UCDataStore')),
|
|
95
|
+
__param(5, inject('UCManager')),
|
|
96
|
+
__metadata("design:paramtypes", [CORSMiddlewareBuilder,
|
|
97
|
+
CustomerFacingErrorBuilder,
|
|
90
98
|
ServerRequestHandler, Object, Object, Object])
|
|
91
99
|
], SyncEdgeWorkerHonoServerManager);
|
|
92
100
|
export { SyncEdgeWorkerHonoServerManager };
|
|
@@ -56,7 +56,7 @@ let CommandExecutor = class CommandExecutor {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
catch (err) {
|
|
59
|
-
printError(err);
|
|
59
|
+
printError(this.i18nManager, err);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
fieldsForFlags(uc) {
|
|
@@ -107,7 +107,7 @@ let CommandExecutor = class CommandExecutor {
|
|
|
107
107
|
const message = this.i18nManager.t(key, {
|
|
108
108
|
vars: { expected },
|
|
109
109
|
});
|
|
110
|
-
printError(message);
|
|
110
|
+
printError(this.i18nManager, message);
|
|
111
111
|
return false;
|
|
112
112
|
},
|
|
113
113
|
});
|
|
@@ -3,18 +3,17 @@ export function print(line) {
|
|
|
3
3
|
// biome-ignore lint/suspicious/noConsole: we want it
|
|
4
4
|
console.info(line);
|
|
5
5
|
}
|
|
6
|
-
export function printError(err) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// biome-ignore lint/suspicious/noConsole: we want it
|
|
12
|
-
console.error(err);
|
|
13
|
-
}
|
|
6
|
+
export function printError(i18nManager, err) {
|
|
7
|
+
if (typeof err === 'string') {
|
|
8
|
+
// biome-ignore lint/suspicious/noConsole: we want it
|
|
9
|
+
console.error(err);
|
|
10
|
+
return;
|
|
14
11
|
}
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
if (!(err instanceof CustomError)) {
|
|
13
|
+
// biome-ignore lint/suspicious/noConsole: we want it
|
|
14
|
+
console.error(err);
|
|
15
|
+
return;
|
|
17
16
|
}
|
|
18
17
|
// biome-ignore lint/suspicious/noConsole: we want it
|
|
19
|
-
console.error(message);
|
|
18
|
+
console.error(i18nManager.t(err.message));
|
|
20
19
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { WordingManager } from '../../../i18n/index.js';
|
|
2
|
+
import type { ProductManifest, ProductUCsLoaderOutput } from '../../../product/index.js';
|
|
3
|
+
import type { Configurable, I18nManager, SettingsManager, Worker } from '../../../std/index.js';
|
|
4
|
+
import type { ServerManagerSettings } from '../server/ServerManager.js';
|
|
5
|
+
import type { OpenAPISpec } from './types.js';
|
|
6
|
+
type Input = {
|
|
7
|
+
ucs: ProductUCsLoaderOutput;
|
|
8
|
+
};
|
|
9
|
+
interface Output {
|
|
10
|
+
spec: OpenAPISpec;
|
|
11
|
+
}
|
|
12
|
+
type S = Pick<ServerManagerSettings, 'server_cookies_name_auth' | 'server_public_api_key_header_name' | 'server_public_url'>;
|
|
13
|
+
export declare class OpenAPISpecBuilder implements Configurable<S>, Worker<Input, Promise<Output>> {
|
|
14
|
+
private i18nManager;
|
|
15
|
+
private productManifest;
|
|
16
|
+
private settingsManager;
|
|
17
|
+
private wordingManager;
|
|
18
|
+
constructor(i18nManager: I18nManager, productManifest: ProductManifest, settingsManager: SettingsManager<S>, wordingManager: WordingManager);
|
|
19
|
+
s(): S;
|
|
20
|
+
exec({ ucs }: Input): Promise<Output>;
|
|
21
|
+
private initErrors;
|
|
22
|
+
private initOutput;
|
|
23
|
+
private initPath;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,131 @@
|
|
|
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 { WordingManager } from '../../../i18n/index.js';
|
|
15
|
+
import { formatFQUCInputName, formatFQUCName, ucHTTPContract, } from '../../../uc/index.js';
|
|
16
|
+
import { DEFAULT_VERSION } from '../shared.js';
|
|
17
|
+
import { openAPIErrorSchema, openAPIErrors, openAPIInputSchema, openAPIParameters, openAPIRequestBody, openAPISecurity, openAPISecuritySchemes, openAPISuccess, } from './funcs.js';
|
|
18
|
+
let OpenAPISpecBuilder = class OpenAPISpecBuilder {
|
|
19
|
+
i18nManager;
|
|
20
|
+
productManifest;
|
|
21
|
+
settingsManager;
|
|
22
|
+
wordingManager;
|
|
23
|
+
constructor(i18nManager, productManifest, settingsManager, wordingManager) {
|
|
24
|
+
this.i18nManager = i18nManager;
|
|
25
|
+
this.productManifest = productManifest;
|
|
26
|
+
this.settingsManager = settingsManager;
|
|
27
|
+
this.wordingManager = wordingManager;
|
|
28
|
+
}
|
|
29
|
+
s() {
|
|
30
|
+
return {
|
|
31
|
+
server_cookies_name_auth: this.settingsManager.get()('server_cookies_name_auth'),
|
|
32
|
+
server_public_api_key_header_name: this.settingsManager.get()('server_public_api_key_header_name'),
|
|
33
|
+
server_public_url: this.settingsManager.get()('server_public_url'),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async exec({ ucs }) {
|
|
37
|
+
const output = this.initOutput();
|
|
38
|
+
const errors = this.initErrors();
|
|
39
|
+
const { desc, slogan } = this.wordingManager.p();
|
|
40
|
+
if (desc) {
|
|
41
|
+
output.spec.info.description = desc;
|
|
42
|
+
}
|
|
43
|
+
if (slogan) {
|
|
44
|
+
output.spec.info.summary = slogan;
|
|
45
|
+
}
|
|
46
|
+
for (const uc of ucs) {
|
|
47
|
+
const { method, path, pathAliases, envelope } = ucHTTPContract(uc);
|
|
48
|
+
const httpMethod = method.toLowerCase();
|
|
49
|
+
const fqUCName = formatFQUCName(uc.appManifest.name, uc.def.metadata.name);
|
|
50
|
+
const fqUCInputName = formatFQUCInputName(fqUCName);
|
|
51
|
+
output.spec.components.schemas[fqUCInputName] =
|
|
52
|
+
openAPIInputSchema(uc);
|
|
53
|
+
for (const p of [path, ...pathAliases]) {
|
|
54
|
+
output.spec.paths[p] = {
|
|
55
|
+
...output.spec.paths[p],
|
|
56
|
+
[httpMethod]: this.initPath(errors, uc, envelope, fqUCInputName),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return output;
|
|
61
|
+
}
|
|
62
|
+
initErrors() {
|
|
63
|
+
const errors = openAPIErrors();
|
|
64
|
+
for (const error of Object.values(errors)) {
|
|
65
|
+
error.description = this.i18nManager.t(error.description);
|
|
66
|
+
}
|
|
67
|
+
return errors;
|
|
68
|
+
}
|
|
69
|
+
initOutput() {
|
|
70
|
+
return {
|
|
71
|
+
spec: {
|
|
72
|
+
components: {
|
|
73
|
+
schemas: {
|
|
74
|
+
Error: openAPIErrorSchema(),
|
|
75
|
+
},
|
|
76
|
+
securitySchemes: openAPISecuritySchemes(this.s().server_cookies_name_auth, this.s().server_public_api_key_header_name),
|
|
77
|
+
},
|
|
78
|
+
info: {
|
|
79
|
+
title: this.productManifest.name,
|
|
80
|
+
version: this.productManifest.version ?? DEFAULT_VERSION,
|
|
81
|
+
},
|
|
82
|
+
openapi: '3.1.0',
|
|
83
|
+
paths: {},
|
|
84
|
+
servers: [
|
|
85
|
+
{
|
|
86
|
+
url: this.s().server_public_url,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
initPath(errors,
|
|
93
|
+
// biome-ignore lint/suspicious/noExplicitAny: can be anything
|
|
94
|
+
uc, envelope, fqUCInputName) {
|
|
95
|
+
const { desc, label } = this.wordingManager.uc(uc.def);
|
|
96
|
+
const path = {
|
|
97
|
+
responses: {
|
|
98
|
+
...openAPISuccess(uc),
|
|
99
|
+
...errors,
|
|
100
|
+
// TODO : Infer errors that can be sent within ServerMain
|
|
101
|
+
},
|
|
102
|
+
security: openAPISecurity(uc.def.sec),
|
|
103
|
+
summary: label,
|
|
104
|
+
tags: [uc.appManifest.name],
|
|
105
|
+
};
|
|
106
|
+
if (desc) {
|
|
107
|
+
path.description = desc;
|
|
108
|
+
}
|
|
109
|
+
switch (envelope) {
|
|
110
|
+
case 'form-data':
|
|
111
|
+
case 'json':
|
|
112
|
+
path.requestBody = openAPIRequestBody(uc, envelope, fqUCInputName);
|
|
113
|
+
break;
|
|
114
|
+
case 'query-params':
|
|
115
|
+
path.parameters = openAPIParameters(uc, envelope);
|
|
116
|
+
break;
|
|
117
|
+
default:
|
|
118
|
+
envelope;
|
|
119
|
+
}
|
|
120
|
+
return path;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
OpenAPISpecBuilder = __decorate([
|
|
124
|
+
injectable(),
|
|
125
|
+
__param(0, inject('I18nManager')),
|
|
126
|
+
__param(1, inject('ProductManifest')),
|
|
127
|
+
__param(2, inject('SettingsManager')),
|
|
128
|
+
__param(3, inject(WordingManager)),
|
|
129
|
+
__metadata("design:paramtypes", [Object, Object, Object, WordingManager])
|
|
130
|
+
], OpenAPISpecBuilder);
|
|
131
|
+
export { OpenAPISpecBuilder };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SUCCESS_DESCRIPTION = '🕺🏽';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ServerError } from '../../../error/index.js';
|
|
2
|
+
import { type FQUCInputName, type UC, type UCInput, type UCInputUnwrapped, type UCOPIBase, type UCOutput, type UCOutputPart, type UCOutputReaderPart, type UCSec } from '../../../uc/index.js';
|
|
3
|
+
import { type HTTPDataEnvelope } from '../../../utils/index.js';
|
|
4
|
+
import { type AuthCookieName, type PublicApiKeyHeaderName } from '../shared.js';
|
|
5
|
+
import type { OpenAPIParameter, OpenAPIRequestBody, OpenAPIResponses, OpenAPISchema, OpenAPISecurity, OpenAPISecuritySchemes } from './types.js';
|
|
6
|
+
export declare function openAPIErrorSchema(): OpenAPISchema<ServerError>;
|
|
7
|
+
export declare function openAPIErrors(): OpenAPIResponses;
|
|
8
|
+
export declare function openAPIInputSchema<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): OpenAPISchema<UCInputUnwrapped<I>>;
|
|
9
|
+
export declare function openAPIOPISchema<OPI extends UCOPIBase>(part: UCOutputReaderPart<NonNullable<OPI>>): OpenAPISchema<OPI>;
|
|
10
|
+
export declare function openAPIOutputPartSchema<OPI extends UCOPIBase>(part: UCOutputReaderPart<NonNullable<OPI>>): OpenAPISchema<UCOutputPart<OPI>>;
|
|
11
|
+
export declare function openAPIOutputSchema<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): OpenAPISchema<UCOutput<OPI0, OPI1>>;
|
|
12
|
+
export declare function openAPIParameters<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, envelope: Extract<HTTPDataEnvelope, 'query-params'>): OpenAPIParameter[];
|
|
13
|
+
export declare function openAPIRequestBody<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>, envelope: Extract<HTTPDataEnvelope, 'form-data' | 'json'>, fqUCInputName: FQUCInputName): OpenAPIRequestBody;
|
|
14
|
+
export declare function openAPISecuritySchemes(authCookieName: AuthCookieName, publicApiKeyHeaderName: PublicApiKeyHeaderName): OpenAPISecuritySchemes;
|
|
15
|
+
export declare function openAPISecurity(sec: UCSec | undefined): OpenAPISecurity;
|
|
16
|
+
export declare function openAPISuccess<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(uc: UC<I, OPI0, OPI1>): OpenAPIResponses;
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { ERROR_HTTP_STATUS_MAP, IllegalArgumentError, } from '../../../error/index.js';
|
|
2
|
+
import { DEFAULT_UC_SEC_AT, DEFAULT_UC_SEC_PAKCT, UCOutputReader, ucofExamples, } from '../../../uc/index.js';
|
|
3
|
+
import { isBlank } from '../../../utils/index.js';
|
|
4
|
+
import { AUTHORIZATION_HEADER_NAME, } from '../shared.js';
|
|
5
|
+
import { SUCCESS_DESCRIPTION } from './consts.js';
|
|
6
|
+
import { openAPIInputDef } from './input.js';
|
|
7
|
+
export function openAPIErrorSchema() {
|
|
8
|
+
return {
|
|
9
|
+
additionalProperties: false,
|
|
10
|
+
properties: {
|
|
11
|
+
message: {
|
|
12
|
+
examples: [new IllegalArgumentError().message],
|
|
13
|
+
type: 'string',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
type: 'object',
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function openAPIErrors() {
|
|
20
|
+
return ERROR_HTTP_STATUS_MAP.entries().reduce((acc, cur) => {
|
|
21
|
+
const [status, clazz] = cur;
|
|
22
|
+
const message = new clazz().message;
|
|
23
|
+
acc[status] = {
|
|
24
|
+
content: {
|
|
25
|
+
'application/json': {
|
|
26
|
+
schema: {
|
|
27
|
+
additionalProperties: false,
|
|
28
|
+
properties: {
|
|
29
|
+
message: {
|
|
30
|
+
examples: [message],
|
|
31
|
+
type: 'string',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
type: 'object',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
description: message,
|
|
39
|
+
};
|
|
40
|
+
return acc;
|
|
41
|
+
}, {});
|
|
42
|
+
}
|
|
43
|
+
export function openAPIInputSchema(uc) {
|
|
44
|
+
const res = {
|
|
45
|
+
additionalProperties: false,
|
|
46
|
+
properties: {},
|
|
47
|
+
type: 'object',
|
|
48
|
+
};
|
|
49
|
+
for (const f of uc.inputFields) {
|
|
50
|
+
const { key } = f;
|
|
51
|
+
const { internal, spec } = openAPIInputDef(f);
|
|
52
|
+
if (!spec) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const k = key;
|
|
56
|
+
res.properties[k] = spec;
|
|
57
|
+
if (!internal?.required) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (!res.required) {
|
|
61
|
+
res.required = [];
|
|
62
|
+
}
|
|
63
|
+
res.required.push(k);
|
|
64
|
+
}
|
|
65
|
+
return res;
|
|
66
|
+
}
|
|
67
|
+
export function openAPIOPISchema(part) {
|
|
68
|
+
const res = {
|
|
69
|
+
additionalProperties: false,
|
|
70
|
+
properties: {},
|
|
71
|
+
type: 'object',
|
|
72
|
+
};
|
|
73
|
+
for (const f of part.fields) {
|
|
74
|
+
const { def, key } = f;
|
|
75
|
+
const { type } = def;
|
|
76
|
+
const k = key;
|
|
77
|
+
res.properties[k] = type.jsonSchemaType();
|
|
78
|
+
const examples = ucofExamples(def);
|
|
79
|
+
if (examples) {
|
|
80
|
+
res.properties[k].examples = examples;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return res;
|
|
84
|
+
}
|
|
85
|
+
export function openAPIOutputPartSchema(part) {
|
|
86
|
+
return {
|
|
87
|
+
additionalProperties: false,
|
|
88
|
+
properties: {
|
|
89
|
+
items: {
|
|
90
|
+
items: openAPIOPISchema(part),
|
|
91
|
+
type: 'array',
|
|
92
|
+
},
|
|
93
|
+
pagination: {
|
|
94
|
+
properties: {
|
|
95
|
+
id: { format: 'uuid', type: 'string' },
|
|
96
|
+
limit: { type: 'integer' },
|
|
97
|
+
offset: { type: 'integer' },
|
|
98
|
+
q: { type: 'string' },
|
|
99
|
+
},
|
|
100
|
+
type: 'object',
|
|
101
|
+
},
|
|
102
|
+
total: { examples: [1], type: 'integer' },
|
|
103
|
+
},
|
|
104
|
+
required: ['items', 'total'],
|
|
105
|
+
type: 'object',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
export function openAPIOutputSchema(uc) {
|
|
109
|
+
const res = {
|
|
110
|
+
additionalProperties: false,
|
|
111
|
+
properties: {},
|
|
112
|
+
type: 'object',
|
|
113
|
+
};
|
|
114
|
+
if (!uc.hasOutputParts()) {
|
|
115
|
+
return res;
|
|
116
|
+
}
|
|
117
|
+
const ucor = new UCOutputReader(uc.def, undefined);
|
|
118
|
+
const [part0, part1] = ucor.parts();
|
|
119
|
+
res.properties.parts = {
|
|
120
|
+
properties: {
|
|
121
|
+
_0: openAPIOutputPartSchema(part0),
|
|
122
|
+
},
|
|
123
|
+
type: 'object',
|
|
124
|
+
};
|
|
125
|
+
if (part1) {
|
|
126
|
+
res.properties.parts.properties = {
|
|
127
|
+
_1: openAPIOutputPartSchema(part1),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return res;
|
|
131
|
+
}
|
|
132
|
+
export function openAPIParameters(uc, envelope) {
|
|
133
|
+
const res = [];
|
|
134
|
+
switch (envelope) {
|
|
135
|
+
case 'query-params':
|
|
136
|
+
{
|
|
137
|
+
for (const f of uc.inputFields) {
|
|
138
|
+
const { key } = f;
|
|
139
|
+
const { internal, spec } = openAPIInputDef(f);
|
|
140
|
+
if (!spec) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
res.push({
|
|
144
|
+
in: 'query',
|
|
145
|
+
name: key,
|
|
146
|
+
required: internal?.required ?? false,
|
|
147
|
+
schema: spec,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
break;
|
|
152
|
+
default:
|
|
153
|
+
envelope;
|
|
154
|
+
}
|
|
155
|
+
return res;
|
|
156
|
+
}
|
|
157
|
+
export function openAPIRequestBody(uc, envelope, fqUCInputName) {
|
|
158
|
+
const innerContent = {
|
|
159
|
+
schema: {
|
|
160
|
+
$ref: `#/components/schemas/${fqUCInputName}`,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
switch (envelope) {
|
|
164
|
+
case 'form-data': {
|
|
165
|
+
const repeatableFields = uc.inputFieldsRepeatable();
|
|
166
|
+
const content = {
|
|
167
|
+
'multipart/form-data': innerContent,
|
|
168
|
+
};
|
|
169
|
+
if (!isBlank(repeatableFields)) {
|
|
170
|
+
content['multipart/form-data'].encoding = {};
|
|
171
|
+
}
|
|
172
|
+
for (const f of repeatableFields) {
|
|
173
|
+
// This is to prevent SwaggerUI from sending the values comma separated
|
|
174
|
+
// biome-ignore lint/style/noNonNullAssertion: we want it
|
|
175
|
+
content['multipart/form-data'].encoding[f.key] = {
|
|
176
|
+
explode: true,
|
|
177
|
+
style: 'form',
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
content,
|
|
182
|
+
required: true,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
case 'json':
|
|
186
|
+
return {
|
|
187
|
+
content: {
|
|
188
|
+
'application/json': innerContent,
|
|
189
|
+
},
|
|
190
|
+
required: true,
|
|
191
|
+
};
|
|
192
|
+
default:
|
|
193
|
+
envelope;
|
|
194
|
+
throw new Error();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
export function openAPISecuritySchemes(authCookieName, publicApiKeyHeaderName) {
|
|
198
|
+
return {
|
|
199
|
+
apiKey: {
|
|
200
|
+
bearerFormat: 'Bearer',
|
|
201
|
+
in: 'header',
|
|
202
|
+
name: AUTHORIZATION_HEADER_NAME,
|
|
203
|
+
type: 'apiKey',
|
|
204
|
+
},
|
|
205
|
+
basic: {
|
|
206
|
+
scheme: 'basic',
|
|
207
|
+
type: 'http',
|
|
208
|
+
},
|
|
209
|
+
jwt: {
|
|
210
|
+
in: 'cookie',
|
|
211
|
+
name: authCookieName,
|
|
212
|
+
type: 'apiKey',
|
|
213
|
+
},
|
|
214
|
+
publicApiKey: {
|
|
215
|
+
in: 'header',
|
|
216
|
+
name: publicApiKeyHeaderName,
|
|
217
|
+
type: 'apiKey',
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
export function openAPISecurity(sec) {
|
|
222
|
+
const item = {};
|
|
223
|
+
const res = [item];
|
|
224
|
+
const publicApiCheckType = sec?.publicApiKeyCheckType ?? DEFAULT_UC_SEC_PAKCT;
|
|
225
|
+
switch (publicApiCheckType) {
|
|
226
|
+
case 'off':
|
|
227
|
+
break;
|
|
228
|
+
case 'on':
|
|
229
|
+
item.publicApiKey = [];
|
|
230
|
+
break;
|
|
231
|
+
default:
|
|
232
|
+
publicApiCheckType;
|
|
233
|
+
}
|
|
234
|
+
const authType = sec?.authType ?? DEFAULT_UC_SEC_AT;
|
|
235
|
+
item[authType] = [];
|
|
236
|
+
return res;
|
|
237
|
+
}
|
|
238
|
+
export function openAPISuccess(uc) {
|
|
239
|
+
return {
|
|
240
|
+
'200': {
|
|
241
|
+
content: {
|
|
242
|
+
'application/json': {
|
|
243
|
+
schema: openAPIOutputSchema(uc),
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
description: SUCCESS_DESCRIPTION,
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DataType } from '../../../dt/index.js';
|
|
2
|
+
import { type UCInputField } from '../../../uc/index.js';
|
|
3
|
+
import type { OpenAPIProperty } from './types.js';
|
|
4
|
+
export interface OpenAPIInputDef<T extends DataType> {
|
|
5
|
+
/**
|
|
6
|
+
* Internal types that are not part of the spec
|
|
7
|
+
*/
|
|
8
|
+
internal?: {
|
|
9
|
+
required?: boolean;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Fields that are part of the spec
|
|
13
|
+
*/
|
|
14
|
+
spec?: OpenAPIProperty<T>;
|
|
15
|
+
}
|
|
16
|
+
export declare function openAPIInputDef<T extends DataType>(field: UCInputField<T>): OpenAPIInputDef<T>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ucifExamples, ucifIsMandatory, ucifRepeatability, } from '../../../uc/index.js';
|
|
2
|
+
export function openAPIInputDef(field) {
|
|
3
|
+
const def = {
|
|
4
|
+
internal: {},
|
|
5
|
+
spec: { type: 'string' },
|
|
6
|
+
};
|
|
7
|
+
if (!def.internal || !def.spec) {
|
|
8
|
+
// Just a guard to safely type the rest of the function without using !
|
|
9
|
+
return def;
|
|
10
|
+
}
|
|
11
|
+
const { def: fDef } = field;
|
|
12
|
+
const { type: fType } = fDef;
|
|
13
|
+
def.internal.required = ucifIsMandatory(fDef);
|
|
14
|
+
def.spec = fType.jsonSchemaType();
|
|
15
|
+
const examples = ucifExamples(fDef);
|
|
16
|
+
if (examples) {
|
|
17
|
+
def.spec.examples = examples;
|
|
18
|
+
}
|
|
19
|
+
const options = fType.getOptions();
|
|
20
|
+
if (options) {
|
|
21
|
+
def.spec.enum = options.map((o) => o.value);
|
|
22
|
+
}
|
|
23
|
+
const [isRepeatable] = ucifRepeatability(fDef);
|
|
24
|
+
if (isRepeatable) {
|
|
25
|
+
def.spec = {
|
|
26
|
+
items: def.spec,
|
|
27
|
+
maxItems: fDef.cardinality?.max,
|
|
28
|
+
minItems: fDef.cardinality?.min,
|
|
29
|
+
type: 'array',
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return def;
|
|
33
|
+
}
|