libmodulor 0.28.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.
Files changed (100) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +2 -2
  3. package/dist/esm/apps/Helper/src/lib/layers/project.js +3 -3
  4. package/dist/esm/dt/base/TBase.d.ts +2 -0
  5. package/dist/esm/dt/base/TBase.js +5 -0
  6. package/dist/esm/dt/base/TBoolean.d.ts +2 -0
  7. package/dist/esm/dt/base/TBoolean.js +3 -0
  8. package/dist/esm/dt/base/TInt.d.ts +2 -0
  9. package/dist/esm/dt/base/TInt.js +3 -0
  10. package/dist/esm/dt/base/TNumber.d.ts +2 -0
  11. package/dist/esm/dt/base/TNumber.js +3 -0
  12. package/dist/esm/dt/base/TObject.d.ts +2 -0
  13. package/dist/esm/dt/base/TObject.js +29 -0
  14. package/dist/esm/dt/final/TApiKey.d.ts +2 -0
  15. package/dist/esm/dt/final/TApiKey.js +3 -0
  16. package/dist/esm/dt/final/TDateISO8601.d.ts +2 -0
  17. package/dist/esm/dt/final/TDateISO8601.js +3 -0
  18. package/dist/esm/dt/final/TDomainName.d.ts +2 -0
  19. package/dist/esm/dt/final/TDomainName.js +3 -0
  20. package/dist/esm/dt/final/TEmail.d.ts +2 -0
  21. package/dist/esm/dt/final/TEmail.js +3 -0
  22. package/dist/esm/dt/final/TEncryptionKey.d.ts +2 -0
  23. package/dist/esm/dt/final/TEncryptionKey.js +3 -0
  24. package/dist/esm/dt/final/TFile.d.ts +2 -0
  25. package/dist/esm/dt/final/TFile.js +3 -0
  26. package/dist/esm/dt/final/TIPv4.d.ts +2 -0
  27. package/dist/esm/dt/final/TIPv4.js +3 -0
  28. package/dist/esm/dt/final/TIPv6.d.ts +2 -0
  29. package/dist/esm/dt/final/TIPv6.js +3 -0
  30. package/dist/esm/dt/final/TJWT.d.ts +2 -0
  31. package/dist/esm/dt/final/TJWT.js +3 -0
  32. package/dist/esm/dt/final/TPassword.d.ts +2 -0
  33. package/dist/esm/dt/final/TPassword.js +3 -0
  34. package/dist/esm/dt/final/TSSHPrivateKey.d.ts +2 -0
  35. package/dist/esm/dt/final/TSSHPrivateKey.js +3 -0
  36. package/dist/esm/dt/final/TTime.d.ts +2 -0
  37. package/dist/esm/dt/final/TTime.js +3 -0
  38. package/dist/esm/dt/final/TURL.d.ts +2 -0
  39. package/dist/esm/dt/final/TURL.js +3 -0
  40. package/dist/esm/dt/index.d.ts +1 -0
  41. package/dist/esm/dt/targets/json-schema.d.ts +24 -0
  42. package/dist/esm/dt/targets/json-schema.js +1 -0
  43. package/dist/esm/error/funcs.d.ts +3 -0
  44. package/dist/esm/error/funcs.js +1 -1
  45. package/dist/esm/error/index.d.ts +1 -1
  46. package/dist/esm/error/index.js +1 -1
  47. package/dist/esm/product/manifest.d.ts +2 -0
  48. package/dist/esm/std/impl/SimpleMapI18nManager.d.ts +1 -1
  49. package/dist/esm/std/impl/SimpleMapI18nManager.js +4 -2
  50. package/dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.d.ts +6 -2
  51. package/dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.js +17 -9
  52. package/dist/esm/target/index.d.ts +1 -0
  53. package/dist/esm/target/lib/openapi/OpenAPISpecBuilder.d.ts +25 -0
  54. package/dist/esm/target/lib/openapi/OpenAPISpecBuilder.js +131 -0
  55. package/dist/esm/target/lib/openapi/consts.d.ts +2 -0
  56. package/dist/esm/target/lib/openapi/consts.js +1 -0
  57. package/dist/esm/target/lib/openapi/funcs.d.ts +16 -0
  58. package/dist/esm/target/lib/openapi/funcs.js +249 -0
  59. package/dist/esm/target/lib/openapi/input.d.ts +16 -0
  60. package/dist/esm/target/lib/openapi/input.js +33 -0
  61. package/dist/esm/target/lib/openapi/types.d.ts +109 -0
  62. package/dist/esm/target/lib/openapi/types.js +1 -0
  63. package/dist/esm/target/lib/rn/input.d.ts +3 -0
  64. package/dist/esm/target/lib/server/AuthCookieCreator.d.ts +2 -1
  65. package/dist/esm/target/lib/server/ServerBooter.d.ts +4 -2
  66. package/dist/esm/target/lib/server/ServerBooter.js +34 -11
  67. package/dist/esm/target/lib/server/ServerManager.d.ts +19 -9
  68. package/dist/esm/target/lib/server/ServerRequestHandler.d.ts +0 -1
  69. package/dist/esm/target/lib/server/ServerRequestHandler.js +2 -2
  70. package/dist/esm/target/lib/server/consts.d.ts +4 -0
  71. package/dist/esm/target/lib/server/consts.js +22 -0
  72. package/dist/esm/target/lib/server-express/CORSMiddlewareBuilder.d.ts +15 -0
  73. package/dist/esm/target/lib/server-express/CORSMiddlewareBuilder.js +55 -0
  74. package/dist/esm/target/lib/server-express/funcs.d.ts +2 -1
  75. package/dist/esm/target/lib/server-express/funcs.js +7 -2
  76. package/dist/esm/target/lib/server-hono/CORSMiddlewareBuilder.d.ts +14 -0
  77. package/dist/esm/target/lib/server-hono/CORSMiddlewareBuilder.js +46 -0
  78. package/dist/esm/target/lib/server-hono/funcs.d.ts +2 -1
  79. package/dist/esm/target/lib/server-hono/funcs.js +2 -1
  80. package/dist/esm/target/lib/shared.d.ts +4 -0
  81. package/dist/esm/target/lib/shared.js +2 -1
  82. package/dist/esm/target/nextjs-server/NextJSServerManager.d.ts +3 -1
  83. package/dist/esm/target/nextjs-server/NextJSServerManager.js +3 -0
  84. package/dist/esm/target/node-express-server/NodeExpressServerManager.d.ts +7 -3
  85. package/dist/esm/target/node-express-server/NodeExpressServerManager.js +24 -14
  86. package/dist/esm/target/node-hono-server/NodeHonoServerManager.d.ts +6 -2
  87. package/dist/esm/target/node-hono-server/NodeHonoServerManager.js +21 -11
  88. package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.d.ts +3 -1
  89. package/dist/esm/target/node-mcp-server/NodeLocalStdioMCPServerManager.js +19 -14
  90. package/dist/esm/target/node-mcp-server/types.d.ts +0 -4
  91. package/dist/esm/uc/UC.d.ts +2 -0
  92. package/dist/esm/uc/UC.js +16 -1
  93. package/dist/esm/uc/metadata.d.ts +7 -0
  94. package/dist/esm/uc/metadata.js +10 -0
  95. package/dist/esm/uc/output-field.d.ts +1 -0
  96. package/dist/esm/uc/output-field.js +13 -1
  97. package/dist/esm/uc/utils/ucHTTPContract.js +1 -1
  98. package/dist/esm/utils/http/types.d.ts +5 -0
  99. package/dist/esm/utils/index.d.ts +1 -1
  100. package/package.json +8 -8
@@ -0,0 +1,109 @@
1
+ import type { DataType, FreeTextLong, FreeTextShort, HTTPMethod, HTTPStatusNumber, JSONSchemaType, SemVerVersion, URL } from '../../../dt/index.js';
2
+ import type { ProductName } from '../../../product/index.js';
3
+ import type { FQUCInputName, FQUCOPI0Name, FQUCOPI1Name, UCFieldKey } from '../../../uc/index.js';
4
+ import type { StringKeys } from '../../../utils/index.js';
5
+ import type { AUTHORIZATION_HEADER_NAME, AuthCookieName, PublicApiKeyHeaderName } from '../shared.js';
6
+ export type OpenAPIPathName = string;
7
+ export type OpenAPIDescription = FreeTextLong;
8
+ export type OpenAPISchemaName = FQUCInputName | FQUCOPI0Name | FQUCOPI1Name | `Error`;
9
+ export type OpenAPISchemaRef = `#/components/schemas/${OpenAPISchemaName}`;
10
+ export type OpenAPISummary = FreeTextShort;
11
+ export type OpenAPIProperty<T extends DataType> = JSONSchemaType & {
12
+ enum?: T[];
13
+ examples?: T[];
14
+ };
15
+ export interface OpenAPISchema<T extends object> {
16
+ additionalProperties: false;
17
+ properties: Record<StringKeys<T>, OpenAPIProperty<any>>;
18
+ required?: StringKeys<T>[];
19
+ type: 'object';
20
+ }
21
+ export type OpenAPISecurityItem = Partial<Record<keyof OpenAPISecuritySchemes, []>>;
22
+ export type OpenAPISecurity = OpenAPISecurityItem[];
23
+ export interface OpenAPISecurityScheme {
24
+ description?: OpenAPIDescription;
25
+ }
26
+ export interface OpenAPISecuritySchemes {
27
+ apiKey?: OpenAPISecurityScheme & {
28
+ bearerFormat: 'Bearer';
29
+ in: 'header';
30
+ name: typeof AUTHORIZATION_HEADER_NAME;
31
+ type: 'apiKey';
32
+ };
33
+ basic?: OpenAPISecurityScheme & {
34
+ scheme: 'basic';
35
+ type: 'http';
36
+ };
37
+ jwt?: OpenAPISecurityScheme & {
38
+ in: 'cookie';
39
+ name: AuthCookieName;
40
+ type: 'apiKey';
41
+ };
42
+ publicApiKey?: OpenAPISecurityScheme & {
43
+ in: 'header';
44
+ name: PublicApiKeyHeaderName;
45
+ type: 'apiKey';
46
+ };
47
+ }
48
+ export interface OpenAPIComponents {
49
+ securitySchemes: OpenAPISecuritySchemes;
50
+ schemas: Record<OpenAPISchemaName, OpenAPISchema<any>>;
51
+ }
52
+ export interface OpenAPIParameter {
53
+ description?: OpenAPIDescription;
54
+ in: 'path' | 'query';
55
+ name: UCFieldKey;
56
+ required: boolean;
57
+ schema: OpenAPIProperty<any>;
58
+ }
59
+ export interface OpenAPIPath {
60
+ description?: OpenAPIDescription;
61
+ parameters?: OpenAPIParameter[];
62
+ requestBody?: OpenAPIRequestBody;
63
+ responses: OpenAPIResponses;
64
+ security?: OpenAPISecurity;
65
+ summary?: OpenAPISummary;
66
+ tags?: string[];
67
+ }
68
+ export interface OpenAPIInnerContent {
69
+ schema: {
70
+ $ref: OpenAPISchemaRef;
71
+ } | OpenAPISchema<any>;
72
+ }
73
+ export type OpenAPIContent = {
74
+ 'application/json': OpenAPIInnerContent;
75
+ } | {
76
+ 'multipart/form-data': OpenAPIInnerContent & {
77
+ encoding?: Record<UCFieldKey, {
78
+ style: 'form';
79
+ explode: boolean;
80
+ }>;
81
+ };
82
+ };
83
+ export interface OpenAPIRequestBody {
84
+ content: OpenAPIContent;
85
+ description?: OpenAPIDescription;
86
+ required: boolean;
87
+ }
88
+ export type OpenAPIPaths = Record<OpenAPIPathName, Partial<Record<Lowercase<HTTPMethod>, OpenAPIPath>>>;
89
+ export interface OpenAPIResponse {
90
+ content: OpenAPIContent;
91
+ description: OpenAPIDescription;
92
+ }
93
+ export type OpenAPIResponses = Partial<Record<HTTPStatusNumber, OpenAPIResponse>>;
94
+ export interface OpenAPIServer {
95
+ description?: OpenAPIDescription;
96
+ url: URL;
97
+ }
98
+ export interface OpenAPISpec {
99
+ components: OpenAPIComponents;
100
+ info: {
101
+ description?: OpenAPIDescription;
102
+ title: ProductName;
103
+ summary?: OpenAPISummary;
104
+ version: SemVerVersion;
105
+ };
106
+ openapi: '3.1.0';
107
+ paths: OpenAPIPaths;
108
+ servers: OpenAPIServer[];
109
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -2,6 +2,9 @@ import type { TextInputProps } from 'react-native';
2
2
  import { type DataType, type ErrorMessage } from '../../../dt/index.js';
3
3
  import { type UCInputField } from '../../../uc/index.js';
4
4
  export interface RNInputDef {
5
+ /**
6
+ * Internal types that are not part of the spec
7
+ */
5
8
  internal?: undefined;
6
9
  /**
7
10
  * Fields that are part of {@link TextInputProps}
@@ -1,10 +1,11 @@
1
1
  import type { JWT, Timestamp } from '../../../dt/index.js';
2
2
  import type { JWTManager, SettingsManager, Worker } from '../../../std/index.js';
3
+ import type { HTTPCookieSameSite } from '../../../utils/index.js';
3
4
  import type { ServerManagerSettings } from '../../lib/server/ServerManager.js';
4
5
  export interface CookieOpts {
5
6
  expires: Date;
6
7
  httpOnly: boolean;
7
- sameSite: 'strict';
8
+ sameSite: HTTPCookieSameSite;
8
9
  secure: boolean;
9
10
  signed: boolean;
10
11
  }
@@ -2,9 +2,10 @@ import { ProductUCsLoader } from '../../../product/index.js';
2
2
  import type { Configurable, EmailManager, FSManager, I18nManager, JobManager, Logger, SettingsManager, Worker } from '../../../std/index.js';
3
3
  import { type UCManager } from '../../../uc/index.js';
4
4
  import type { TargetEntrypointInput } from '../entrypoint.js';
5
+ import { OpenAPISpecBuilder } from '../openapi/OpenAPISpecBuilder.js';
5
6
  import { ServerInstaller } from './ServerInstaller.js';
6
7
  import type { ServerManager, ServerManagerSettings } from './ServerManager.js';
7
- type S = Pick<ServerManagerSettings, 'server_static_dir_path' | 'server_tmp_path'>;
8
+ type S = Pick<ServerManagerSettings, 'server_expose_openapi_spec' | 'server_expose_openapi_spec_at' | 'server_static_dir_path' | 'server_tmp_path'>;
8
9
  type Input = TargetEntrypointInput & {
9
10
  autoMountUCs?: boolean;
10
11
  };
@@ -13,13 +14,14 @@ export declare class ServerBooter implements Configurable<S>, Worker<Input, Prom
13
14
  private fsManager;
14
15
  private i18nManager;
15
16
  private jobManager;
17
+ private openAPISpecBuilder;
16
18
  private logger;
17
19
  private productUCsLoader;
18
20
  private serverManager;
19
21
  private serverInstaller;
20
22
  private settingsManager;
21
23
  private ucManager;
22
- constructor(emailManager: EmailManager, fsManager: FSManager, i18nManager: I18nManager, jobManager: JobManager, logger: Logger, productUCsLoader: ProductUCsLoader, serverManager: ServerManager, serverInstaller: ServerInstaller, settingsManager: SettingsManager<S>, ucManager: UCManager);
24
+ constructor(emailManager: EmailManager, fsManager: FSManager, i18nManager: I18nManager, jobManager: JobManager, openAPISpecBuilder: OpenAPISpecBuilder, logger: Logger, productUCsLoader: ProductUCsLoader, serverManager: ServerManager, serverInstaller: ServerInstaller, settingsManager: SettingsManager<S>, ucManager: UCManager);
23
25
  s(): S;
24
26
  exec({ appsRootPath, autoMountUCs, srcImporter, }: Input): Promise<void>;
25
27
  private mountUC;
@@ -11,8 +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
- import { ProductUCsLoader } from '../../../product/index.js';
14
+ import { ProductUCsLoader, } from '../../../product/index.js';
15
15
  import { ucHTTPContract, } from '../../../uc/index.js';
16
+ import { OpenAPISpecBuilder } from '../openapi/OpenAPISpecBuilder.js';
16
17
  import { shouldMountUC } from './funcs.js';
17
18
  import { ServerInstaller } from './ServerInstaller.js';
18
19
  let ServerBooter = class ServerBooter {
@@ -20,17 +21,19 @@ let ServerBooter = class ServerBooter {
20
21
  fsManager;
21
22
  i18nManager;
22
23
  jobManager;
24
+ openAPISpecBuilder;
23
25
  logger;
24
26
  productUCsLoader;
25
27
  serverManager;
26
28
  serverInstaller;
27
29
  settingsManager;
28
30
  ucManager;
29
- constructor(emailManager, fsManager, i18nManager, jobManager, logger, productUCsLoader, serverManager, serverInstaller, settingsManager, ucManager) {
31
+ constructor(emailManager, fsManager, i18nManager, jobManager, openAPISpecBuilder, logger, productUCsLoader, serverManager, serverInstaller, settingsManager, ucManager) {
30
32
  this.emailManager = emailManager;
31
33
  this.fsManager = fsManager;
32
34
  this.i18nManager = i18nManager;
33
35
  this.jobManager = jobManager;
36
+ this.openAPISpecBuilder = openAPISpecBuilder;
34
37
  this.logger = logger;
35
38
  this.productUCsLoader = productUCsLoader;
36
39
  this.serverManager = serverManager;
@@ -40,6 +43,8 @@ let ServerBooter = class ServerBooter {
40
43
  }
41
44
  s() {
42
45
  return {
46
+ server_expose_openapi_spec: this.settingsManager.get()('server_expose_openapi_spec'),
47
+ server_expose_openapi_spec_at: this.settingsManager.get()('server_expose_openapi_spec_at'),
43
48
  server_static_dir_path: this.settingsManager.get()('server_static_dir_path'),
44
49
  server_tmp_path: this.settingsManager.get()('server_tmp_path'),
45
50
  };
@@ -55,13 +60,18 @@ let ServerBooter = class ServerBooter {
55
60
  await this.emailManager.verify();
56
61
  this.logger.info('Initializing server manager');
57
62
  await this.serverManager.init();
63
+ const mountedUCs = [];
58
64
  if (autoMountUCs) {
59
65
  const ucs = await this.productUCsLoader.exec({
60
66
  appsRootPath,
61
67
  srcImporter,
62
68
  });
63
69
  for await (const uc of ucs) {
64
- await this.mountUC(uc);
70
+ const mounted = await this.mountUC(uc);
71
+ if (!mounted) {
72
+ continue;
73
+ }
74
+ mountedUCs.push(uc);
65
75
  }
66
76
  }
67
77
  const staticDirPath = this.s().server_static_dir_path;
@@ -76,6 +86,17 @@ let ServerBooter = class ServerBooter {
76
86
  if (!(await this.fsManager.exists(tmpDirPath))) {
77
87
  await this.fsManager.mkdir(tmpDirPath);
78
88
  }
89
+ if (this.s().server_expose_openapi_spec) {
90
+ const at = this.s().server_expose_openapi_spec_at;
91
+ this.logger.info('Mounting OpenAPI spec', {
92
+ at,
93
+ mountedUCs: mountedUCs.length,
94
+ });
95
+ const { spec } = await this.openAPISpecBuilder.exec({
96
+ ucs: mountedUCs,
97
+ });
98
+ await this.serverManager.mountOpenAPISpec(spec, at);
99
+ }
79
100
  await this.serverManager.warmUp();
80
101
  await this.serverManager.start();
81
102
  }
@@ -88,7 +109,7 @@ let ServerBooter = class ServerBooter {
88
109
  this.logger.debug(`Not mounting ${mountingPoint}`, {
89
110
  reason: shouldNotMountReason,
90
111
  });
91
- return;
112
+ return false;
92
113
  }
93
114
  this.logger.info(`Mounting ${mountingPoint}`, {
94
115
  contract,
@@ -96,6 +117,7 @@ let ServerBooter = class ServerBooter {
96
117
  });
97
118
  await this.ucManager.initServer(uc);
98
119
  await this.serverManager.mount(uc.appManifest, uc.def, contract);
120
+ return true;
99
121
  }
100
122
  };
101
123
  ServerBooter = __decorate([
@@ -104,12 +126,13 @@ ServerBooter = __decorate([
104
126
  __param(1, inject('FSManager')),
105
127
  __param(2, inject('I18nManager')),
106
128
  __param(3, inject('JobManager')),
107
- __param(4, inject('Logger')),
108
- __param(5, inject(ProductUCsLoader)),
109
- __param(6, inject('ServerManager')),
110
- __param(7, inject(ServerInstaller)),
111
- __param(8, inject('SettingsManager')),
112
- __param(9, inject('UCManager')),
113
- __metadata("design:paramtypes", [Object, Object, Object, Object, Object, ProductUCsLoader, Object, ServerInstaller, Object, Object])
129
+ __param(4, inject(OpenAPISpecBuilder)),
130
+ __param(5, inject('Logger')),
131
+ __param(6, inject(ProductUCsLoader)),
132
+ __param(7, inject('ServerManager')),
133
+ __param(8, inject(ServerInstaller)),
134
+ __param(9, inject('SettingsManager')),
135
+ __param(10, inject('UCManager')),
136
+ __metadata("design:paramtypes", [Object, Object, Object, Object, OpenAPISpecBuilder, Object, ProductUCsLoader, Object, ServerInstaller, Object, Object])
114
137
  ], ServerBooter);
115
138
  export { ServerBooter };
@@ -1,12 +1,11 @@
1
1
  import type { AppManifest } from '../../../app/index.js';
2
- import type { ApiKey, DirPath, FilePath, HostPort, Password, URL, Username } from '../../../dt/index.js';
2
+ import type { ApiKey, DirPath, FilePath, HostPort, HTTPMethod, Password, URL, URLPath, Username } from '../../../dt/index.js';
3
3
  import type { Settings } from '../../../std/index.js';
4
4
  import type { UCDef, UCHTTPContract, UCInput, UCManager, UCOPIBase } from '../../../uc/index.js';
5
- import type { Initializable } from '../../../utils/index.js';
5
+ import type { HTTPCSPValue } from '../../../utils/http/types.js';
6
+ import type { HTTPCookieSameSite, HTTPHeaderName, Initializable } from '../../../utils/index.js';
7
+ import type { OpenAPISpec } from '../openapi/types.js';
6
8
  import type { AuthCookieName, PublicApiKeyHeaderName } from '../shared.js';
7
- export type ServerManagerCSPDefType = 'defaultSrc' | 'imgSrc' | 'scriptSrc';
8
- export type ServerManagerCSPDefValue = URL[];
9
- export type ServerManagerCSPDef = Record<ServerManagerCSPDefType, ServerManagerCSPDefValue>;
10
9
  export interface ServerManagerAuthSettings {
11
10
  server_basic_auth_entries: Record<Username, Password>;
12
11
  server_private_api_key_entries: ApiKey[];
@@ -17,11 +16,17 @@ export interface ServerManagerSettings extends ServerManagerAuthSettings, Settin
17
16
  server_binding_port: HostPort;
18
17
  server_cookies_http_only: boolean;
19
18
  server_cookies_name_auth: AuthCookieName;
20
- server_cookies_same_site: 'strict';
19
+ server_cookies_same_site: HTTPCookieSameSite;
21
20
  server_cookies_secure: boolean;
22
- server_csp_default_src: ServerManagerCSPDefValue;
23
- server_csp_img_src: ServerManagerCSPDefValue;
24
- server_csp_script_src: ServerManagerCSPDefValue;
21
+ server_csp_default_src: HTTPCSPValue;
22
+ server_csp_img_src: HTTPCSPValue;
23
+ server_csp_script_src: HTTPCSPValue;
24
+ server_cors_credentials: boolean;
25
+ server_cors_headers: HTTPHeaderName[];
26
+ server_cors_methods: HTTPMethod[];
27
+ server_cors_origins: URL[];
28
+ server_expose_openapi_spec: boolean;
29
+ server_expose_openapi_spec_at: URLPath;
25
30
  server_public_api_key_header_name: PublicApiKeyHeaderName;
26
31
  server_public_url: URL;
27
32
  server_ssl_fullchain_path: FilePath | null;
@@ -46,6 +51,11 @@ export interface ServerManager extends Initializable {
46
51
  * @param contract
47
52
  */
48
53
  mountSync<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract): void;
54
+ /**
55
+ * Mount the OpenAPI spec
56
+ * @param spec
57
+ */
58
+ mountOpenAPISpec(spec: OpenAPISpec, at: URLPath): Promise<void>;
49
59
  /**
50
60
  * Mount the static directory at `/`
51
61
  * @param dirPath
@@ -58,7 +58,6 @@ export declare class ServerRequestHandler implements Worker<Input, Promise<Outpu
58
58
  private requestLogger;
59
59
  private settingsManager;
60
60
  private ucBuilder;
61
- private static AUTHORIZATION_HEADER_NAME;
62
61
  private static X_FORWARDED_PROTO_HEADER_NAME;
63
62
  constructor(authCookieCreator: AuthCookieCreator, authenticationChecker: AuthenticationChecker, customerFacingErrorBuilder: CustomerFacingErrorBuilder, publicApiKeyChecker: PublicApiKeyChecker, requestChecker: RequestChecker, requestLogger: RequestLogger, settingsManager: SettingsManager<S>, ucBuilder: UCBuilder);
64
63
  s(): S;
@@ -14,6 +14,7 @@ var ServerRequestHandler_1;
14
14
  import { inject, injectable } from 'inversify';
15
15
  import { IllegalArgumentError, isEmptyJSON } from '../../../error/index.js';
16
16
  import { UCBuilder, UCOutputReader, UCOutputSideEffectType, } from '../../../uc/index.js';
17
+ import { AUTHORIZATION_HEADER_NAME } from '../shared.js';
17
18
  import { AuthCookieCreator, } from './AuthCookieCreator.js';
18
19
  import { AuthenticationChecker } from './AuthenticationChecker.js';
19
20
  import { CustomerFacingErrorBuilder } from './CustomerFacingErrorBuilder.js';
@@ -30,7 +31,6 @@ let ServerRequestHandler = class ServerRequestHandler {
30
31
  requestLogger;
31
32
  settingsManager;
32
33
  ucBuilder;
33
- static AUTHORIZATION_HEADER_NAME = 'Authorization';
34
34
  static X_FORWARDED_PROTO_HEADER_NAME = 'X-Forwarded-Proto';
35
35
  constructor(authCookieCreator, authenticationChecker, customerFacingErrorBuilder, publicApiKeyChecker, requestChecker, requestLogger, settingsManager, ucBuilder) {
36
36
  this.authCookieCreator = authCookieCreator;
@@ -73,7 +73,7 @@ let ServerRequestHandler = class ServerRequestHandler {
73
73
  });
74
74
  const { auth } = await this.authenticationChecker.exec({
75
75
  authCookie: await cookie(this.s().server_cookies_name_auth),
76
- authorizationHeader: await header(ServerRequestHandler_1.AUTHORIZATION_HEADER_NAME),
76
+ authorizationHeader: await header(AUTHORIZATION_HEADER_NAME),
77
77
  uc,
78
78
  });
79
79
  if (auth) {
@@ -1,5 +1,9 @@
1
+ import type { HTTPMethod } from '../../../dt/index.js';
2
+ import type { HTTPHeaderName } from '../../../utils/index.js';
1
3
  import type { ServerManagerSettings } from './ServerManager.js';
2
4
  /**
3
5
  * @see TARGET_DEFAULT_SERVER_CLIENT_MANAGER_SETTINGS
4
6
  */
5
7
  export declare const TARGET_DEFAULT_SERVER_MANAGER_SETTINGS: ServerManagerSettings;
8
+ export declare const TARGET_USUAL_SERVER_MANAGER_CORS_HEADERS: HTTPHeaderName[];
9
+ export declare const TARGET_USUAL_SERVER_MANAGER_CORS_METHODS: HTTPMethod[];
@@ -10,9 +10,15 @@ export const TARGET_DEFAULT_SERVER_MANAGER_SETTINGS = {
10
10
  server_cookies_name_auth: 'auth',
11
11
  server_cookies_same_site: 'strict',
12
12
  server_cookies_secure: true,
13
+ server_cors_credentials: false,
14
+ server_cors_headers: [],
15
+ server_cors_methods: [],
16
+ server_cors_origins: [],
13
17
  server_csp_default_src: [],
14
18
  server_csp_img_src: [],
15
19
  server_csp_script_src: [],
20
+ server_expose_openapi_spec: false,
21
+ server_expose_openapi_spec_at: '/api/openapi.json',
16
22
  server_private_api_key_entries: [],
17
23
  server_public_api_key_entries: [unsafeDefaultSetting()],
18
24
  server_public_api_key_header_name: 'X-API-Key',
@@ -23,3 +29,19 @@ export const TARGET_DEFAULT_SERVER_MANAGER_SETTINGS = {
23
29
  server_stop_mode: 'patient',
24
30
  server_tmp_path: 'tmp',
25
31
  };
32
+ export const TARGET_USUAL_SERVER_MANAGER_CORS_HEADERS = [
33
+ 'Accept',
34
+ 'Authorization',
35
+ 'Content-Type',
36
+ 'Cookie',
37
+ 'Origin',
38
+ 'X-Requested-With',
39
+ ];
40
+ export const TARGET_USUAL_SERVER_MANAGER_CORS_METHODS = [
41
+ 'DELETE',
42
+ 'GET',
43
+ 'HEAD',
44
+ 'OPTIONS',
45
+ 'POST',
46
+ 'PUT',
47
+ ];
@@ -0,0 +1,15 @@
1
+ import type { RequestHandler } from 'express';
2
+ import type { Configurable, SettingsManager, Worker } from '../../../std/index.js';
3
+ import type { ServerManagerSettings } from '../server/ServerManager.js';
4
+ interface Input {
5
+ }
6
+ type Output = RequestHandler;
7
+ type S = Pick<ServerManagerSettings, 'server_cors_credentials' | 'server_cors_headers' | 'server_cors_methods' | 'server_cors_origins' | 'server_public_api_key_header_name'>;
8
+ export declare class CORSMiddlewareBuilder implements Configurable<S>, Worker<Input, Output> {
9
+ private settingsManager;
10
+ constructor(settingsManager: SettingsManager<S>);
11
+ s(): S;
12
+ exec(_input: Input): Output;
13
+ private fmt;
14
+ }
15
+ export {};
@@ -0,0 +1,55 @@
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
+ let CORSMiddlewareBuilder = class CORSMiddlewareBuilder {
15
+ settingsManager;
16
+ constructor(settingsManager) {
17
+ this.settingsManager = settingsManager;
18
+ }
19
+ s() {
20
+ return {
21
+ server_cors_credentials: this.settingsManager.get()('server_cors_credentials'),
22
+ server_cors_headers: this.settingsManager.get()('server_cors_headers'),
23
+ server_cors_methods: this.settingsManager.get()('server_cors_methods'),
24
+ server_cors_origins: this.settingsManager.get()('server_cors_origins'),
25
+ server_public_api_key_header_name: this.settingsManager.get()('server_public_api_key_header_name'),
26
+ };
27
+ }
28
+ exec(_input) {
29
+ return (req, res, next) => {
30
+ res.header('Access-Control-Allow-Credentials', String(this.s().server_cors_credentials));
31
+ res.header('Access-Control-Allow-Headers', this.fmt([
32
+ ...this.s().server_cors_headers,
33
+ this.s().server_public_api_key_header_name,
34
+ ]));
35
+ res.header('Access-Control-Allow-Methods', this.fmt(this.s().server_cors_methods));
36
+ const { origin } = req.headers;
37
+ if (origin) {
38
+ const electedOrigin = this.s().server_cors_origins.find((o) => o.startsWith(origin));
39
+ if (electedOrigin) {
40
+ res.header('Access-Control-Allow-Origin', electedOrigin);
41
+ }
42
+ }
43
+ next();
44
+ };
45
+ }
46
+ fmt(arr) {
47
+ return arr.join(', ');
48
+ }
49
+ };
50
+ CORSMiddlewareBuilder = __decorate([
51
+ injectable(),
52
+ __param(0, inject('SettingsManager')),
53
+ __metadata("design:paramtypes", [Object])
54
+ ], CORSMiddlewareBuilder);
55
+ export { CORSMiddlewareBuilder };
@@ -7,9 +7,10 @@ import type { UCDef, UCHTTPContract, UCInput, UCManager, UCOPIBase } from '../..
7
7
  import type { CustomerFacingErrorBuilder } from '../server/CustomerFacingErrorBuilder.js';
8
8
  import type { ServerManagerSettings } from '../server/ServerManager.js';
9
9
  import type { ServerRequestHandler, ServerRequestHandlerReq, ServerRequestHandlerRes } from '../server/ServerRequestHandler.js';
10
+ import type { CORSMiddlewareBuilder } from './CORSMiddlewareBuilder.js';
10
11
  import type { HelmetMiddlewareBuilder } from './HelmetMiddlewareBuilder.js';
11
12
  export declare function buildHandler<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract, serverRequestHandler: ServerRequestHandler, ucManager: UCManager): RequestHandler;
12
- export declare function init(helmetMB: HelmetMiddlewareBuilder, loggerLevel: LoggerLevel, serverTmpPath: ServerManagerSettings['server_tmp_path']): Express;
13
+ export declare function init(corsMB: CORSMiddlewareBuilder, helmetMB: HelmetMiddlewareBuilder, loggerLevel: LoggerLevel, serverTmpPath: ServerManagerSettings['server_tmp_path']): Express;
13
14
  export declare function mountHandler(contract: UCHTTPContract, express: Express, handler: RequestHandler): void;
14
15
  export declare function postInit(app: Express, customerFacingErrorBuilder: CustomerFacingErrorBuilder): void;
15
16
  export declare function toFile(f: fileUpload.UploadedFile): File;
@@ -12,12 +12,16 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
12
12
  // Nothing to do
13
13
  break;
14
14
  case 'stream': {
15
+ let streamedOnce = false;
15
16
  execOpts = {
16
17
  stream: {
17
18
  onClose: async () => {
18
- throw new Error('execOpts.stream.onClose needs to be set in the UC ServerMain');
19
+ if (streamedOnce) {
20
+ throw new Error('execOpts.stream.onClose needs to be set in the UC ServerMain');
21
+ }
19
22
  },
20
23
  onData: async (output) => {
24
+ streamedOnce = true;
21
25
  if (!output) {
22
26
  return;
23
27
  }
@@ -72,9 +76,10 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
72
76
  };
73
77
  return handler;
74
78
  }
75
- export function init(helmetMB, loggerLevel, serverTmpPath) {
79
+ export function init(corsMB, helmetMB, loggerLevel, serverTmpPath) {
76
80
  const app = express();
77
81
  app.use(helmetMB.exec({}));
82
+ app.use(corsMB.exec({}));
78
83
  app.use(fileUpload({
79
84
  createParentPath: true,
80
85
  debug: loggerLevel === 'trace',
@@ -0,0 +1,14 @@
1
+ import type { MiddlewareHandler } from 'hono';
2
+ import type { Configurable, SettingsManager, Worker } from '../../../std/index.js';
3
+ import type { ServerManagerSettings } from '../server/ServerManager.js';
4
+ interface Input {
5
+ }
6
+ type Output = MiddlewareHandler;
7
+ type S = Pick<ServerManagerSettings, 'server_cors_credentials' | 'server_cors_headers' | 'server_cors_methods' | 'server_cors_origins' | 'server_public_api_key_header_name'>;
8
+ export declare class CORSMiddlewareBuilder implements Configurable<S>, Worker<Input, Output> {
9
+ private settingsManager;
10
+ constructor(settingsManager: SettingsManager<S>);
11
+ s(): S;
12
+ exec(_input: Input): Output;
13
+ }
14
+ export {};
@@ -0,0 +1,46 @@
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 { cors } from 'hono/cors';
14
+ import { inject, injectable } from 'inversify';
15
+ let CORSMiddlewareBuilder = class CORSMiddlewareBuilder {
16
+ settingsManager;
17
+ constructor(settingsManager) {
18
+ this.settingsManager = settingsManager;
19
+ }
20
+ s() {
21
+ return {
22
+ server_cors_credentials: this.settingsManager.get()('server_cors_credentials'),
23
+ server_cors_headers: this.settingsManager.get()('server_cors_headers'),
24
+ server_cors_methods: this.settingsManager.get()('server_cors_methods'),
25
+ server_cors_origins: this.settingsManager.get()('server_cors_origins'),
26
+ server_public_api_key_header_name: this.settingsManager.get()('server_public_api_key_header_name'),
27
+ };
28
+ }
29
+ exec(_input) {
30
+ return cors({
31
+ allowHeaders: [
32
+ ...this.s().server_cors_headers,
33
+ this.s().server_public_api_key_header_name,
34
+ ],
35
+ allowMethods: this.s().server_cors_methods,
36
+ credentials: true,
37
+ origin: this.s().server_cors_origins,
38
+ });
39
+ }
40
+ };
41
+ CORSMiddlewareBuilder = __decorate([
42
+ injectable(),
43
+ __param(0, inject('SettingsManager')),
44
+ __metadata("design:paramtypes", [Object])
45
+ ], CORSMiddlewareBuilder);
46
+ export { CORSMiddlewareBuilder };
@@ -4,8 +4,9 @@ import type { AppManifest } from '../../../app/index.js';
4
4
  import type { UCDef, UCHTTPContract, UCInput, UCManager, UCOPIBase } from '../../../uc/index.js';
5
5
  import type { CustomerFacingErrorBuilder } from '../server/CustomerFacingErrorBuilder.js';
6
6
  import type { ServerRequestHandler, ServerRequestHandlerReq, ServerRequestHandlerRes } from '../server/ServerRequestHandler.js';
7
+ import type { CORSMiddlewareBuilder } from './CORSMiddlewareBuilder.js';
7
8
  export declare function buildHandler<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(appManifest: AppManifest, ucd: UCDef<I, OPI0, OPI1>, contract: UCHTTPContract, serverRequestHandler: ServerRequestHandler, ucManager: UCManager, beforeExec?: (c: Context) => Promise<void>): Handler;
8
- export declare function init<E extends Env = BlankEnv>(customerFacingErrorBuilder: CustomerFacingErrorBuilder): Hono<E>;
9
+ export declare function init<E extends Env = BlankEnv>(corsMB: CORSMiddlewareBuilder, customerFacingErrorBuilder: CustomerFacingErrorBuilder): Hono<E>;
9
10
  export declare function mountHandler(contract: UCHTTPContract, hono: Hono, handler: Handler): void;
10
11
  export declare function toReq(c: Context): ServerRequestHandlerReq;
11
12
  export declare function toRes(c: Context): ServerRequestHandlerRes;
@@ -86,9 +86,10 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
86
86
  };
87
87
  return handler;
88
88
  }
89
- export function init(customerFacingErrorBuilder) {
89
+ export function init(corsMB, customerFacingErrorBuilder) {
90
90
  const app = new Hono();
91
91
  app.use(secureHeaders());
92
+ app.use(corsMB.exec({}));
92
93
  app.use(logger());
93
94
  app.notFound((c) => {
94
95
  const error = new NotFoundError();
@@ -1,2 +1,6 @@
1
+ import type { SemVerVersion } from '../../dt/index.js';
2
+ import type { HTTPHeaderName } from '../../utils/index.js';
1
3
  export type AuthCookieName = 'auth';
2
4
  export type PublicApiKeyHeaderName = 'X-API-Key' | (string & {});
5
+ export declare const AUTHORIZATION_HEADER_NAME: HTTPHeaderName;
6
+ export declare const DEFAULT_VERSION: SemVerVersion;
@@ -1 +1,2 @@
1
- export {};
1
+ export const AUTHORIZATION_HEADER_NAME = 'Authorization';
2
+ export const DEFAULT_VERSION = '0.1.0';
@@ -1,6 +1,7 @@
1
1
  import type { AppManifest } from '../../app/index.js';
2
- import type { DirPath } from '../../dt/index.js';
2
+ import type { DirPath, URLPath } from '../../dt/index.js';
3
3
  import type { UCDef, UCHTTPContract, UCInput, UCManager, UCOPIBase } from '../../uc/index.js';
4
+ import type { OpenAPISpec } from '../lib/openapi/types.js';
4
5
  import type { ServerManager } from '../lib/server/ServerManager.js';
5
6
  export declare class NextJSServerManager implements ServerManager {
6
7
  overrideUCManager(_ucManager: UCManager): void;
@@ -8,6 +9,7 @@ export declare class NextJSServerManager implements ServerManager {
8
9
  initSync(): void;
9
10
  mount<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(_appManifest: AppManifest, _ucd: UCDef<I, OPI0, OPI1>, _contract: UCHTTPContract): Promise<void>;
10
11
  mountSync<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>(_appManifest: AppManifest, _ucd: UCDef<I, OPI0, OPI1>, _contract: UCHTTPContract): void;
12
+ mountOpenAPISpec(_spec: OpenAPISpec, _at: URLPath): Promise<void>;
11
13
  mountStaticDir(_dirPath: DirPath): Promise<void>;
12
14
  start(): Promise<void>;
13
15
  stop(): Promise<void>;