@contember/engine-server 1.1.2 → 1.2.0-alpha.11

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 (173) hide show
  1. package/dist/src/MasterContainer.d.ts +27 -25
  2. package/dist/src/MasterContainer.d.ts.map +1 -1
  3. package/dist/src/MasterContainer.js +54 -80
  4. package/dist/src/MasterContainer.js.map +1 -1
  5. package/dist/src/bootstrap/Initializer.d.ts +3 -3
  6. package/dist/src/bootstrap/Initializer.d.ts.map +1 -1
  7. package/dist/src/bootstrap/Initializer.js +15 -8
  8. package/dist/src/bootstrap/Initializer.js.map +1 -1
  9. package/dist/src/config/config.d.ts +5 -4
  10. package/dist/src/config/config.d.ts.map +1 -1
  11. package/dist/src/config/config.js +2 -2
  12. package/dist/src/config/config.js.map +1 -1
  13. package/dist/src/config/configSchema.d.ts +45 -11
  14. package/dist/src/config/configSchema.d.ts.map +1 -1
  15. package/dist/src/config/configSchema.js +20 -18
  16. package/dist/src/config/configSchema.js.map +1 -1
  17. package/dist/src/config/configTemplate.d.ts.map +1 -1
  18. package/dist/src/config/configTemplate.js +23 -0
  19. package/dist/src/config/configTemplate.js.map +1 -1
  20. package/dist/src/index.d.ts +9 -3
  21. package/dist/src/index.d.ts.map +1 -1
  22. package/dist/src/index.js +23 -4
  23. package/dist/src/index.js.map +1 -1
  24. package/dist/src/project/ProjectContainer.js +1 -1
  25. package/dist/src/project/ProjectContainer.js.map +1 -1
  26. package/dist/src/project/ProjectContainerResolver.d.ts +6 -3
  27. package/dist/src/project/ProjectContainerResolver.d.ts.map +1 -1
  28. package/dist/src/project/ProjectContainerResolver.js +4 -16
  29. package/dist/src/project/ProjectContainerResolver.js.map +1 -1
  30. package/dist/src/projectGroup/ProjectGroupContainer.d.ts +2 -1
  31. package/dist/src/projectGroup/ProjectGroupContainer.d.ts.map +1 -1
  32. package/dist/src/projectGroup/ProjectGroupContainer.js +8 -4
  33. package/dist/src/projectGroup/ProjectGroupContainer.js.map +1 -1
  34. package/dist/src/projectGroup/ProjectGroupResolver.d.ts +7 -0
  35. package/dist/src/projectGroup/ProjectGroupResolver.d.ts.map +1 -0
  36. package/dist/src/projectGroup/ProjectGroupResolver.js +13 -0
  37. package/dist/src/projectGroup/ProjectGroupResolver.js.map +1 -0
  38. package/dist/src/start.js +15 -112
  39. package/dist/src/start.js.map +1 -1
  40. package/dist/src/tsconfig.tsbuildinfo +1 -1
  41. package/dist/src/utils/index.d.ts +0 -4
  42. package/dist/src/utils/index.d.ts.map +1 -1
  43. package/dist/src/utils/index.js +0 -4
  44. package/dist/src/utils/index.js.map +1 -1
  45. package/dist/src/utils/sentry.d.ts +1 -1
  46. package/dist/src/utils/sentry.d.ts.map +1 -1
  47. package/dist/src/utils/sentry.js +1 -1
  48. package/dist/src/utils/sentry.js.map +1 -1
  49. package/dist/src/utils/serverStartup.d.ts +31 -0
  50. package/dist/src/utils/serverStartup.d.ts.map +1 -0
  51. package/dist/src/utils/serverStartup.js +42 -0
  52. package/dist/src/utils/serverStartup.js.map +1 -0
  53. package/dist/src/utils/serverTermination.d.ts +12 -0
  54. package/dist/src/utils/serverTermination.d.ts.map +1 -0
  55. package/dist/src/utils/serverTermination.js +26 -0
  56. package/dist/src/utils/serverTermination.js.map +1 -0
  57. package/dist/tests/e2e/acl-condition-variable.test.d.ts +2 -0
  58. package/dist/tests/e2e/acl-condition-variable.test.d.ts.map +1 -0
  59. package/dist/tests/e2e/acl-condition-variable.test.js +77 -0
  60. package/dist/tests/e2e/acl-condition-variable.test.js.map +1 -0
  61. package/dist/tests/e2e/assume-identity.test.d.ts +2 -0
  62. package/dist/tests/e2e/assume-identity.test.d.ts.map +1 -0
  63. package/dist/tests/e2e/assume-identity.test.js +109 -0
  64. package/dist/tests/e2e/assume-identity.test.js.map +1 -0
  65. package/dist/tests/e2e/assume-membership.test.d.ts +2 -0
  66. package/dist/tests/e2e/assume-membership.test.d.ts.map +1 -0
  67. package/dist/tests/e2e/assume-membership.test.js +58 -0
  68. package/dist/tests/e2e/assume-membership.test.js.map +1 -0
  69. package/dist/tests/e2e/content-api-basic.test.d.ts +2 -0
  70. package/dist/tests/e2e/content-api-basic.test.d.ts.map +1 -0
  71. package/dist/tests/e2e/content-api-basic.test.js +50 -0
  72. package/dist/tests/e2e/content-api-basic.test.js.map +1 -0
  73. package/dist/tests/e2e/content-invalid-schema.test.d.ts +2 -0
  74. package/dist/tests/e2e/content-invalid-schema.test.d.ts.map +1 -0
  75. package/dist/tests/e2e/content-invalid-schema.test.js +29 -0
  76. package/dist/tests/e2e/content-invalid-schema.test.js.map +1 -0
  77. package/dist/tests/e2e/homepage.test.d.ts +2 -0
  78. package/dist/tests/e2e/homepage.test.d.ts.map +1 -0
  79. package/dist/tests/e2e/homepage.test.js +15 -0
  80. package/dist/tests/e2e/homepage.test.js.map +1 -0
  81. package/dist/tests/e2e/tenant-member-access.test.d.ts +2 -0
  82. package/dist/tests/e2e/tenant-member-access.test.d.ts.map +1 -0
  83. package/dist/tests/e2e/tenant-member-access.test.js +43 -0
  84. package/dist/tests/e2e/tenant-member-access.test.js.map +1 -0
  85. package/dist/tests/e2e/x-contember-ref.test.d.ts +2 -0
  86. package/dist/tests/e2e/x-contember-ref.test.d.ts.map +1 -0
  87. package/dist/tests/e2e/x-contember-ref.test.js +63 -0
  88. package/dist/tests/e2e/x-contember-ref.test.js.map +1 -0
  89. package/dist/tests/src/requests.d.ts +5 -0
  90. package/dist/tests/src/requests.d.ts.map +1 -0
  91. package/dist/tests/src/requests.js +68 -0
  92. package/dist/tests/src/requests.js.map +1 -0
  93. package/dist/tests/src/tester.d.ts +19 -0
  94. package/dist/tests/src/tester.d.ts.map +1 -0
  95. package/dist/tests/src/tester.js +99 -0
  96. package/dist/tests/src/tester.js.map +1 -0
  97. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  98. package/esbuild.js +7 -14
  99. package/package.json +23 -23
  100. package/src/MasterContainer.ts +94 -110
  101. package/src/bootstrap/Initializer.ts +16 -8
  102. package/src/config/config.ts +7 -5
  103. package/src/config/configSchema.ts +30 -33
  104. package/src/config/configTemplate.ts +23 -0
  105. package/src/index.ts +15 -2
  106. package/src/project/ProjectContainer.ts +1 -1
  107. package/src/project/ProjectContainerResolver.ts +4 -17
  108. package/src/projectGroup/ProjectGroupContainer.ts +12 -3
  109. package/src/projectGroup/ProjectGroupResolver.ts +12 -0
  110. package/src/start.ts +18 -127
  111. package/src/utils/index.ts +0 -4
  112. package/src/utils/sentry.ts +1 -1
  113. package/src/utils/serverStartup.ts +42 -0
  114. package/src/utils/serverTermination.ts +20 -0
  115. package/tests/e2e/acl-condition-variable.test.ts +74 -0
  116. package/tests/e2e/assume-identity.test.ts +127 -0
  117. package/tests/e2e/assume-membership.test.ts +64 -0
  118. package/tests/e2e/content-api-basic.test.ts +51 -0
  119. package/tests/e2e/content-invalid-schema.test.ts +31 -0
  120. package/tests/e2e/homepage.test.ts +10 -0
  121. package/tests/e2e/tenant-member-access.test.ts +51 -0
  122. package/tests/e2e/x-contember-ref.test.ts +71 -0
  123. package/tests/src/requests.ts +81 -0
  124. package/tests/src/tester.ts +118 -0
  125. package/alpine.dockerfile +0 -30
  126. package/debian.dockerfile +0 -27
  127. package/dist/src/http/CollectHttpMetricsMiddelware.d.ts +0 -5
  128. package/dist/src/http/CollectHttpMetricsMiddelware.d.ts.map +0 -1
  129. package/dist/src/http/CollectHttpMetricsMiddelware.js +0 -36
  130. package/dist/src/http/CollectHttpMetricsMiddelware.js.map +0 -1
  131. package/dist/src/http/ShowMetricsMiddleware.d.ts +0 -4
  132. package/dist/src/http/ShowMetricsMiddleware.d.ts.map +0 -1
  133. package/dist/src/http/ShowMetricsMiddleware.js +0 -20
  134. package/dist/src/http/ShowMetricsMiddleware.js.map +0 -1
  135. package/dist/src/http/index.d.ts +0 -3
  136. package/dist/src/http/index.d.ts.map +0 -1
  137. package/dist/src/http/index.js +0 -19
  138. package/dist/src/http/index.js.map +0 -1
  139. package/dist/src/projectGroup/ProjectGroupContainerResolver.d.ts +0 -12
  140. package/dist/src/projectGroup/ProjectGroupContainerResolver.d.ts.map +0 -1
  141. package/dist/src/projectGroup/ProjectGroupContainerResolver.js +0 -36
  142. package/dist/src/projectGroup/ProjectGroupContainerResolver.js.map +0 -1
  143. package/dist/src/utils/cluster.d.ts +0 -9
  144. package/dist/src/utils/cluster.d.ts.map +0 -1
  145. package/dist/src/utils/cluster.js +0 -47
  146. package/dist/src/utils/cluster.js.map +0 -1
  147. package/dist/src/utils/dbMetrics.d.ts +0 -16
  148. package/dist/src/utils/dbMetrics.d.ts.map +0 -1
  149. package/dist/src/utils/dbMetrics.js +0 -98
  150. package/dist/src/utils/dbMetrics.js.map +0 -1
  151. package/dist/src/utils/timeout.d.ts +0 -2
  152. package/dist/src/utils/timeout.d.ts.map +0 -1
  153. package/dist/src/utils/timeout.js +0 -8
  154. package/dist/src/utils/timeout.js.map +0 -1
  155. package/dist/src/utils/tuple.d.ts +0 -2
  156. package/dist/src/utils/tuple.d.ts.map +0 -1
  157. package/dist/src/utils/tuple.js +0 -6
  158. package/dist/src/utils/tuple.js.map +0 -1
  159. package/dist/tests/e2e/http.test.d.ts +0 -2
  160. package/dist/tests/e2e/http.test.d.ts.map +0 -1
  161. package/dist/tests/e2e/http.test.js +0 -275
  162. package/dist/tests/e2e/http.test.js.map +0 -1
  163. package/jasmine.json +0 -7
  164. package/src/http/CollectHttpMetricsMiddelware.ts +0 -32
  165. package/src/http/ShowMetricsMiddleware.ts +0 -12
  166. package/src/http/index.ts +0 -2
  167. package/src/projectGroup/ProjectGroupContainerResolver.ts +0 -47
  168. package/src/utils/cluster.ts +0 -40
  169. package/src/utils/dbMetrics.ts +0 -111
  170. package/src/utils/timeout.ts +0 -4
  171. package/src/utils/tuple.ts +0 -1
  172. package/tests/e2e/http.test.ts +0 -303
  173. package/tslint.json +0 -14
package/esbuild.js CHANGED
@@ -1,14 +1,7 @@
1
- const esbuild = require('esbuild')
2
- const { resolvePlugin } = require('../../scripts/esbuild/esbuild')
3
- esbuild.build({
4
- entryPoints: ['./packages/engine-server/src/start.ts'],
5
- bundle: true,
6
- platform: 'node',
7
- sourcemap: 'external',
8
- outfile: './server/server.js',
9
- plugins: [resolvePlugin],
10
- external: ['pg-native', 'mock-aws-s3', 'aws-sdk', 'nock', 'bcrypt', 'heapdump'],
11
- }).catch(e => {
12
- console.error(e)
13
- process.exit(1)
14
- })
1
+ const buildServer = require('../../scripts/esbuild/esbuild').buildServer
2
+
3
+ buildServer('./packages/engine-server/src/start.ts')
4
+ .catch(e => {
5
+ console.error(e)
6
+ process.exit(1)
7
+ })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/engine-server",
3
- "version": "1.1.2",
3
+ "version": "1.2.0-alpha.11",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/src/index.js",
6
6
  "typings": "dist/src/index.d.ts",
@@ -8,27 +8,27 @@
8
8
  "test-e2e": "vitest --no-threads tests/e2e"
9
9
  },
10
10
  "dependencies": {
11
- "@contember/authorization": "^1.1.2",
12
- "@contember/config-loader": "^1.1.2",
13
- "@contember/database": "^1.1.2",
14
- "@contember/database-migrations": "^1.1.2",
15
- "@contember/dic": "^1.1.2",
16
- "@contember/typesafe": "^1.1.2",
17
- "@contember/engine-content-api": "^1.1.2",
18
- "@contember/engine-http": "^1.1.2",
19
- "@contember/engine-plugins": "^1.1.2",
20
- "@contember/engine-s3-plugin": "^1.1.2",
21
- "@contember/engine-system-api": "^1.1.2",
22
- "@contember/engine-tenant-api": "^1.1.2",
23
- "@contember/engine-vimeo-plugin": "^1.1.2",
24
- "@contember/queryable": "^1.1.2",
25
- "@contember/schema": "^1.1.2",
26
- "@contember/schema-definition": "^1.1.2",
27
- "@contember/schema-migrations": "^1.1.2",
28
- "@contember/schema-utils": "^1.1.2",
11
+ "@contember/authorization": "^1.2.0-alpha.11",
12
+ "@contember/config-loader": "^1.2.0-alpha.11",
13
+ "@contember/database": "^1.2.0-alpha.11",
14
+ "@contember/database-migrations": "^1.2.0-alpha.11",
15
+ "@contember/dic": "^1.2.0-alpha.11",
16
+ "@contember/typesafe": "^1.2.0-alpha.11",
17
+ "@contember/engine-content-api": "^1.2.0-alpha.11",
18
+ "@contember/engine-http": "^1.2.0-alpha.11",
19
+ "@contember/engine-plugins": "^1.2.0-alpha.11",
20
+ "@contember/engine-s3-plugin": "^1.2.0-alpha.11",
21
+ "@contember/engine-system-api": "^1.2.0-alpha.11",
22
+ "@contember/engine-tenant-api": "^1.2.0-alpha.11",
23
+ "@contember/engine-vimeo-plugin": "^1.2.0-alpha.11",
24
+ "@contember/queryable": "^1.2.0-alpha.11",
25
+ "@contember/schema": "^1.2.0-alpha.11",
26
+ "@contember/schema-definition": "^1.2.0-alpha.11",
27
+ "@contember/schema-migrations": "^1.2.0-alpha.11",
28
+ "@contember/schema-utils": "^1.2.0-alpha.11",
29
29
  "@koa/cors": "^3.1.0",
30
- "@sentry/node": "^6.8.0",
31
- "graphql": "^15.4.0",
30
+ "@sentry/node": "^7.1.1",
31
+ "graphql": "^16.5.0",
32
32
  "heapdump": "^0.3.15",
33
33
  "koa-bodyparser": "^4.3.0",
34
34
  "koa-compress": "^5.0.1",
@@ -37,9 +37,9 @@
37
37
  "uuid": "^8.3.1"
38
38
  },
39
39
  "devDependencies": {
40
- "@contember/engine-api-tester": "^1.1.2",
40
+ "@contember/engine-api-tester": "^1.2.0-alpha.11",
41
41
  "@types/koa-compress": "^4.0.1",
42
- "@types/node": "^17.0.5",
42
+ "@types/node": "^18",
43
43
  "@types/supertest": "^2.0.8",
44
44
  "supertest": "^6.0.1"
45
45
  }
@@ -2,47 +2,53 @@ import { SystemContainerFactory } from '@contember/engine-system-api'
2
2
  import { TenantContainerFactory } from '@contember/engine-tenant-api'
3
3
  import { Builder } from '@contember/dic'
4
4
  import { ServerConfig } from './config/config'
5
- import { createDbMetricsRegistrar, logSentryError, ProcessType } from './utils'
5
+ import { logSentryError } from './utils'
6
6
  import { ModificationHandlerFactory } from '@contember/schema-migrations'
7
7
  import { Initializer } from './bootstrap'
8
8
  import { Plugin } from '@contember/engine-plugins'
9
- import { createColllectHttpMetricsMiddleware, createShowMetricsMiddleware } from './http'
10
9
  import {
11
10
  compose,
12
11
  ContentApiMiddlewareFactory,
13
12
  ContentGraphQLContextFactory,
14
13
  ContentQueryHandlerFactory,
14
+ ContentSchemaTransferMappingFactory,
15
15
  createHomepageMiddleware,
16
16
  createModuleInfoMiddleware,
17
17
  createPlaygroundMiddleware,
18
18
  createPoweredByHeaderMiddleware,
19
19
  createProviders,
20
20
  createTimerMiddleware,
21
- CryptoWrapper,
22
21
  ErrorMiddlewareFactory,
22
+ ExportApiMiddlewareFactory,
23
+ ExportExecutor,
24
+ ImportApiMiddlewareFactory,
25
+ ImportExecutor,
23
26
  Koa,
24
27
  NotModifiedChecker,
25
- ProjectGroupResolver,
26
28
  Providers,
27
- route, SystemApiMiddlewareFactory, SystemGraphQLContextFactory,
28
- SystemGraphQLHandlerFactory, TenantApiMiddlewareFactory, TenantGraphQLContextFactory,
29
+ route,
30
+ SystemApiMiddlewareFactory,
31
+ SystemGraphQLContextFactory,
32
+ SystemGraphQLHandlerFactory,
33
+ SystemSchemaTransferMappingFactory,
34
+ TenantApiMiddlewareFactory,
35
+ TenantGraphQLContextFactory,
29
36
  TenantGraphQLHandlerFactory,
30
37
  } from '@contember/engine-http'
31
- import prom from 'prom-client'
32
38
  import { ProjectContainerFactoryFactory } from './project'
33
- import { createSecretKey } from 'crypto'
34
39
  import koaCompress from 'koa-compress'
35
40
  import bodyParser from 'koa-bodyparser'
36
41
  import { ProjectConfigResolver } from './config/projectConfigResolver'
37
42
  import { TenantConfigResolver } from './config/tenantConfigResolver'
38
- import { ProjectGroupContainerResolver } from './projectGroup/ProjectGroupContainerResolver'
39
43
  import { ProjectGroupContainerFactory } from './projectGroup/ProjectGroupContainer'
40
44
  import corsMiddleware from '@koa/cors'
45
+ import { ProjectGroupResolver } from './projectGroup/ProjectGroupResolver'
46
+ import { ProjectGroupResolver as ProjectGroupResolverInterface } from '@contember/engine-http'
47
+ import { Logger } from '@contember/engine-common'
41
48
 
42
49
  export interface MasterContainer {
43
50
  initializer: Initializer
44
51
  koa: Koa
45
- monitoringKoa: Koa
46
52
  providers: Providers
47
53
  }
48
54
 
@@ -52,7 +58,6 @@ export interface MasterContainerArgs {
52
58
  projectConfigResolver: ProjectConfigResolver
53
59
  tenantConfigResolver: TenantConfigResolver
54
60
  plugins: Plugin[]
55
- processType: ProcessType
56
61
  version?: string
57
62
  }
58
63
 
@@ -63,7 +68,6 @@ export class MasterContainerFactory {
63
68
  plugins,
64
69
  projectConfigResolver,
65
70
  tenantConfigResolver,
66
- processType,
67
71
  version,
68
72
  }: MasterContainerArgs) {
69
73
  return new Builder({})
@@ -71,8 +75,6 @@ export class MasterContainerFactory {
71
75
  serverConfig)
72
76
  .addService('debugMode', () =>
73
77
  debugMode)
74
- .addService('processType', () =>
75
- processType)
76
78
  .addService('version', () =>
77
79
  version)
78
80
  .addService('projectConfigResolver', () =>
@@ -95,62 +97,22 @@ export class MasterContainerFactory {
95
97
  new TenantGraphQLHandlerFactory(logSentryError))
96
98
  .addService('systemGraphQLHandlerFactory', ({ debugMode }) =>
97
99
  new SystemGraphQLHandlerFactory(logSentryError, debugMode))
98
- .addService('projectGroupContainerFactory', ({ providers, systemContainerFactory, tenantContainerFactory, projectContainerFactoryFactory, projectConfigResolver, tenantGraphQLHandlerFactory, systemGraphQLHandlerFactory }) =>
99
- new ProjectGroupContainerFactory(providers, systemContainerFactory, tenantContainerFactory, projectContainerFactoryFactory, projectConfigResolver, tenantGraphQLHandlerFactory, systemGraphQLHandlerFactory))
100
- .addService('projectGroupContainerResolver', ({ tenantConfigResolver, projectGroupContainerFactory }) =>
101
- new ProjectGroupContainerResolver(tenantConfigResolver, projectGroupContainerFactory))
102
- .addService('promRegistry', ({ processType, projectGroupContainerResolver }) => {
103
- if (processType === ProcessType.clusterMaster) {
104
- const register = new prom.AggregatorRegistry()
105
- prom.collectDefaultMetrics({ register })
106
- return register
107
- }
108
- const register = prom.register
109
- prom.collectDefaultMetrics({ register })
110
- const registrar = createDbMetricsRegistrar(register)
111
- projectGroupContainerResolver.onCreate.push((groupContainer, slug) => {
112
- groupContainer.projectContainerResolver.onCreate.push(projectContainer =>
113
- registrar({
114
- connection: projectContainer.connection,
115
- labels: {
116
- contember_module: 'content',
117
- contember_project: projectContainer.project.slug,
118
- contember_project_group: slug ?? 'unknown',
119
- },
120
- }),
121
- )
122
- return registrar({
123
- connection: groupContainer.tenantContainer.connection,
124
- labels: {
125
- contember_module: 'tenant',
126
- contember_project_group: slug ?? 'unknown',
127
- contember_project: 'unknown',
128
- },
129
- })
130
- })
131
- return register
132
- })
100
+ .addService('projectGroupContainerFactory', ({ debugMode, providers, systemContainerFactory, tenantContainerFactory, projectContainerFactoryFactory, projectConfigResolver, tenantGraphQLHandlerFactory, systemGraphQLHandlerFactory }) =>
101
+ new ProjectGroupContainerFactory(debugMode, providers, systemContainerFactory, tenantContainerFactory, projectContainerFactoryFactory, projectConfigResolver, tenantGraphQLHandlerFactory, systemGraphQLHandlerFactory))
102
+ .addService('projectGroupContainer', ({ tenantConfigResolver, projectGroupContainerFactory }) =>
103
+ projectGroupContainerFactory.create({ slug: undefined, config: tenantConfigResolver(undefined, {}) }))
133
104
  .addService('httpErrorMiddlewareFactory', ({ debugMode }) =>
134
105
  new ErrorMiddlewareFactory(debugMode))
135
- .addService('projectGroupResolver', ({ projectGroupContainerResolver, serverConfig }) => {
136
- const encryptionKey = serverConfig.projectGroup?.configEncryptionKey
137
- ? createSecretKey(Buffer.from(serverConfig.projectGroup?.configEncryptionKey, 'hex'))
138
- : undefined
139
- return new ProjectGroupResolver(
140
- serverConfig.projectGroup?.domainMapping,
141
- serverConfig.projectGroup?.configHeader,
142
- serverConfig.projectGroup?.configEncryptionKey ? new CryptoWrapper(encryptionKey) : undefined,
143
- projectGroupContainerResolver,
144
- )
145
- })
106
+ .addService('projectGroupResolver', ({ projectGroupContainer }): ProjectGroupResolverInterface =>
107
+ new ProjectGroupResolver(projectGroupContainer))
146
108
  .addService('notModifiedChecker', () =>
147
109
  new NotModifiedChecker())
148
110
  .addService('contentGraphqlContextFactory', ({ providers }) =>
149
111
  new ContentGraphQLContextFactory(providers))
150
112
  .addService('contentQueryHandlerFactory', ({ debugMode }) =>
151
113
  new ContentQueryHandlerFactory(debugMode, logSentryError))
152
- .addService('contentApiMiddlewareFactory', ({ debugMode, projectGroupResolver, notModifiedChecker, contentGraphqlContextFactory, contentQueryHandlerFactory }) =>
153
- new ContentApiMiddlewareFactory(debugMode, projectGroupResolver, notModifiedChecker, contentGraphqlContextFactory, contentQueryHandlerFactory))
114
+ .addService('contentApiMiddlewareFactory', ({ projectGroupResolver, notModifiedChecker, contentGraphqlContextFactory, contentQueryHandlerFactory }) =>
115
+ new ContentApiMiddlewareFactory(projectGroupResolver, notModifiedChecker, contentGraphqlContextFactory, contentQueryHandlerFactory))
154
116
  .addService('tenantGraphQLContextFactory', () =>
155
117
  new TenantGraphQLContextFactory())
156
118
  .addService('tenantApiMiddlewareFactory', ({ debugMode, projectGroupResolver, tenantGraphQLContextFactory }) =>
@@ -159,62 +121,84 @@ export class MasterContainerFactory {
159
121
  new SystemGraphQLContextFactory())
160
122
  .addService('systemApiMiddlewareFactory', ({ debugMode, projectGroupResolver, systemGraphQLContextFactory }) =>
161
123
  new SystemApiMiddlewareFactory(debugMode, projectGroupResolver, systemGraphQLContextFactory))
162
- .addService('koa', ({ contentApiMiddlewareFactory, tenantApiMiddlewareFactory, systemApiMiddlewareFactory, httpErrorMiddlewareFactory, promRegistry, debugMode, version, serverConfig }) => {
163
- const app = new Koa()
164
- app.use(
165
- compose([
166
- koaCompress({
167
- br: false,
168
- }),
169
- bodyParser({
170
- jsonLimit: serverConfig.http.requestBodySize || '1mb',
171
- }),
172
- createPoweredByHeaderMiddleware(debugMode, version ?? 'unknown'),
173
- httpErrorMiddlewareFactory.create(),
174
- createColllectHttpMetricsMiddleware(promRegistry),
175
- createTimerMiddleware(),
176
- route('/playground$', createPlaygroundMiddleware()),
177
- createHomepageMiddleware(),
178
- corsMiddleware(),
179
- route(
180
- '/content/:projectSlug/:stageSlug$',
181
- compose([
182
- createModuleInfoMiddleware('content'),
183
- contentApiMiddlewareFactory.create(),
184
- ]),
185
- ),
186
- route(
187
- '/tenant$',
188
- compose([
189
- createModuleInfoMiddleware('tenant'),
190
- tenantApiMiddlewareFactory.create(),
191
- ]),
192
- ),
193
- route(
194
- '/system/:projectSlug$',
195
- compose([
196
- createModuleInfoMiddleware('system'),
197
- systemApiMiddlewareFactory.create(),
198
- ]),
199
- ),
200
- ]),
201
- )
202
-
203
- return app
204
- })
205
- .addService('monitoringKoa', ({ promRegistry }) => {
124
+ .addService('logger', () =>
125
+ // eslint-disable-next-line no-console
126
+ new Logger(console.log))
127
+ .addService('contentSchemaTransferMappingFactory', () =>
128
+ new ContentSchemaTransferMappingFactory())
129
+ .addService('systemSchemaTransferMappingFactory', () =>
130
+ new SystemSchemaTransferMappingFactory())
131
+ .addService('importExecutor', ({ contentSchemaTransferMappingFactory, systemSchemaTransferMappingFactory, logger }) =>
132
+ new ImportExecutor(contentSchemaTransferMappingFactory, systemSchemaTransferMappingFactory, logger))
133
+ .addService('exportExecutor', ({ contentSchemaTransferMappingFactory, systemSchemaTransferMappingFactory }) =>
134
+ new ExportExecutor(contentSchemaTransferMappingFactory, systemSchemaTransferMappingFactory))
135
+ .addService('importApiMiddlewareFactory', ({ projectGroupResolver, importExecutor }) =>
136
+ new ImportApiMiddlewareFactory(projectGroupResolver, importExecutor))
137
+ .addService('exportApiMiddlewareFactory', ({ projectGroupResolver, exportExecutor }) =>
138
+ new ExportApiMiddlewareFactory(projectGroupResolver, exportExecutor))
139
+ .addService('koaMiddlewares', ({ contentApiMiddlewareFactory, tenantApiMiddlewareFactory, systemApiMiddlewareFactory, importApiMiddlewareFactory, exportApiMiddlewareFactory, httpErrorMiddlewareFactory, debugMode, version, serverConfig }) =>
140
+ compose([
141
+ koaCompress({
142
+ br: false,
143
+ }),
144
+ bodyParser({
145
+ jsonLimit: serverConfig.http.requestBodySize || '1mb',
146
+ }),
147
+ createPoweredByHeaderMiddleware(debugMode, version ?? 'unknown'),
148
+ createTimerMiddleware(),
149
+ httpErrorMiddlewareFactory.create(),
150
+ route('/playground$', createPlaygroundMiddleware()),
151
+ createHomepageMiddleware(),
152
+ corsMiddleware(),
153
+ route(
154
+ '/content/:projectSlug/:stageSlug$',
155
+ compose([
156
+ createModuleInfoMiddleware('content'),
157
+ contentApiMiddlewareFactory.create(),
158
+ ]),
159
+ ),
160
+ route(
161
+ '/tenant$',
162
+ compose([
163
+ createModuleInfoMiddleware('tenant'),
164
+ tenantApiMiddlewareFactory.create(),
165
+ ]),
166
+ ),
167
+ route(
168
+ '/system/:projectSlug$',
169
+ compose([
170
+ createModuleInfoMiddleware('system'),
171
+ systemApiMiddlewareFactory.create(),
172
+ ]),
173
+ ),
174
+ route(
175
+ '/import$',
176
+ compose([
177
+ createModuleInfoMiddleware('transfer'),
178
+ importApiMiddlewareFactory.create(),
179
+ ]),
180
+ ),
181
+ route(
182
+ '/export$',
183
+ compose([
184
+ createModuleInfoMiddleware('transfer'),
185
+ exportApiMiddlewareFactory.create(),
186
+ ]),
187
+ ),
188
+ ]))
189
+ .addService('koa', ({ koaMiddlewares }) => {
206
190
  const app = new Koa()
207
- app.use(createShowMetricsMiddleware(promRegistry))
191
+ app.use(koaMiddlewares)
208
192
 
209
193
  return app
210
194
  })
211
- .addService('initializer', ({ projectGroupContainerResolver }) =>
212
- new Initializer(projectGroupContainerResolver))
195
+ .addService('initializer', ({ projectGroupContainer }) =>
196
+ new Initializer(projectGroupContainer))
213
197
 
214
198
  }
215
199
 
216
200
  create(args: MasterContainerArgs): MasterContainer {
217
201
  const container = this.createBuilder(args).build()
218
- return container.pick('initializer', 'koa', 'monitoringKoa', 'providers')
202
+ return container.pick('initializer', 'koa', 'providers')
219
203
  }
220
204
  }
@@ -1,9 +1,9 @@
1
1
  import { Logger } from '@contember/engine-common'
2
- import { ProjectGroupContainerResolver } from '../projectGroup/ProjectGroupContainerResolver'
2
+ import { ProjectGroupContainer } from '@contember/engine-http'
3
3
 
4
4
  export class Initializer {
5
5
  constructor(
6
- private readonly projectGroupContainerResolver: ProjectGroupContainerResolver,
6
+ private readonly projectGroupContainer: ProjectGroupContainer,
7
7
  ) {}
8
8
 
9
9
  public async initialize(): Promise<string[]> {
@@ -11,18 +11,26 @@ export class Initializer {
11
11
  const logger = new Logger(console.log)
12
12
  logger.group('\nInitializing tenant database')
13
13
  // todo
14
- const groupContainer = await this.projectGroupContainerResolver.getProjectGroupContainer(undefined)
14
+ const groupContainer = await this.projectGroupContainer
15
15
 
16
- await groupContainer.tenantContainer.migrationsRunner.run(logger.write.bind(logger))
16
+ const tenantContainer = groupContainer.tenantContainer
17
+ await tenantContainer.migrationsRunner.run(logger.write.bind(logger))
17
18
  logger.groupEnd()
18
19
 
19
- const systemContainer = groupContainer.systemContainer
20
20
  const projects: string[] = []
21
- for (const projectContainer of await groupContainer.projectContainerResolver.getAllProjectContainers()) {
21
+
22
+ const tenantProjects = await tenantContainer.projectManager.getProjects(tenantContainer.databaseContext)
23
+ for (const { slug: projectSlug } of tenantProjects) {
24
+ logger.group(`\nUpdating project ${projectSlug}`)
25
+ const projectContainer = await groupContainer.projectContainerResolver.getProjectContainer(projectSlug, {
26
+ alias: false,
27
+ logger,
28
+ })
29
+ if (!projectContainer) {
30
+ throw new Error()
31
+ }
22
32
  const project = projectContainer.project
23
33
  projects.push(project.slug)
24
- logger.group(`\nUpdating project ${project.slug}`)
25
- await systemContainer.projectInitializer.initialize(projectContainer.systemDatabaseContextFactory, project, logger)
26
34
  logger.groupEnd()
27
35
  }
28
36
  // eslint-disable-next-line no-console
@@ -1,22 +1,24 @@
1
1
  import { ConfigLoader, createObjectParametersResolver, Merger, resolveParameters } from '@contember/config-loader'
2
2
  import { ConfigProcessor } from '@contember/engine-plugins'
3
- import { serverConfigSchema, tenantConfigSchema } from './configSchema'
3
+ import { serverConfigSchema as defaultServerConfigSchema, tenantConfigSchema } from './configSchema'
4
4
  import { configTemplate } from './configTemplate'
5
5
  import { createProjectConfigResolver, ProjectConfigResolver } from './projectConfigResolver'
6
6
  import { createTenantConfigResolver, TenantConfigResolver } from './tenantConfigResolver'
7
+ import { Type } from '@contember/typesafe'
7
8
 
8
- export type ServerConfig = ReturnType<typeof serverConfigSchema>
9
+ export type ServerConfig = ReturnType<typeof defaultServerConfigSchema>
9
10
  export type TenantConfig = ReturnType<typeof tenantConfigSchema>
10
11
 
11
12
  export type ConfigSource = { data: string; type: 'file' | 'json' | 'yaml' }
12
13
 
13
14
  type Env = Record<string, string>
14
15
 
15
- export async function readConfig(
16
- configSources: ConfigSource[],
16
+ export async function readConfig<T extends ServerConfig>(
17
+ configSources: ConfigSource[] = [],
17
18
  configProcessors: ConfigProcessor[] = [],
19
+ serverConfigSchema: Type<T> = defaultServerConfigSchema as Type<T>,
18
20
  ): Promise<{
19
- serverConfig: ServerConfig
21
+ serverConfig: T
20
22
  projectConfigResolver: ProjectConfigResolver
21
23
  tenantConfigResolver: TenantConfigResolver
22
24
  }> {
@@ -3,7 +3,7 @@ import { MailerOptions } from '@contember/engine-tenant-api'
3
3
  import { upperCaseFirst } from '../utils'
4
4
 
5
5
 
6
- export const dbCredentialsSchema = Typesafe.intersection(
6
+ export const dbConfigSchema = Typesafe.intersection(
7
7
  Typesafe.object({
8
8
  host: Typesafe.string,
9
9
  port: Typesafe.number,
@@ -13,12 +13,25 @@ export const dbCredentialsSchema = Typesafe.intersection(
13
13
  }),
14
14
  Typesafe.partial({
15
15
  ssl: Typesafe.boolean,
16
+ queryTimeoutMs: Typesafe.number,
17
+ statementTimeoutMs: Typesafe.number,
18
+ connectionTimeoutMs: Typesafe.number,
19
+ pool: Typesafe.partial({
20
+ maxConnections: Typesafe.number,
21
+ maxConnecting: Typesafe.number,
22
+ maxIdle: Typesafe.number,
23
+ reconnectIntervalMs: Typesafe.number,
24
+ idleTimeoutMs: Typesafe.number,
25
+ acquireTimeoutMs: Typesafe.number,
26
+ maxUses: Typesafe.number,
27
+ maxAgeMs: Typesafe.number,
28
+ }),
16
29
  }),
17
30
  )
18
31
 
19
32
  export const tenantConfigSchema = Typesafe.intersection(
20
33
  Typesafe.object({
21
- db: dbCredentialsSchema,
34
+ db: dbConfigSchema,
22
35
  mailer: Typesafe.transform(Typesafe.partial({
23
36
  from: Typesafe.string,
24
37
  host: Typesafe.string,
@@ -46,37 +59,21 @@ export const tenantConfigSchema = Typesafe.intersection(
46
59
  }),
47
60
  }),
48
61
  )
49
- export const serverConfigSchema = Typesafe.intersection(
50
- Typesafe.object({
51
- port: Typesafe.number,
52
- monitoringPort: Typesafe.number,
53
- http: Typesafe.partial({
54
- requestBodySize: Typesafe.string,
55
- }),
56
- logging: Typesafe.union(
57
- val => Typesafe.valueAt(val, ['sentry', 'dsn']) === undefined ? {} : Typesafe.fail([]),
58
- Typesafe.partial({
59
- sentry: Typesafe.object({
60
- dsn: Typesafe.string,
61
- }),
62
- }),
63
- ),
64
- }),
65
- Typesafe.partial({
66
- workerCount: Typesafe.union(Typesafe.number, Typesafe.string),
67
- projectGroup: (val: unknown, path: PropertyKey[] = []) => Typesafe.valueAt(val, ['domainMapping']) === undefined
68
- ? undefined
69
- : Typesafe.intersection(
70
- Typesafe.object({
71
- domainMapping: Typesafe.string,
72
- }),
73
- Typesafe.partial({
74
- configHeader: Typesafe.string,
75
- configEncryptionKey: Typesafe.string,
76
- }),
77
- )(val, path),
62
+
63
+ export const serverConfigSchema = Typesafe.object({
64
+ port: Typesafe.number,
65
+ http: Typesafe.partial({
66
+ requestBodySize: Typesafe.string,
78
67
  }),
79
- )
68
+ logging: Typesafe.union(
69
+ (val): { sentry?: { dsn: string } } => Typesafe.valueAt(val, ['sentry', 'dsn']) === undefined ? {} : Typesafe.fail([]),
70
+ Typesafe.partial({
71
+ sentry: Typesafe.object({
72
+ dsn: Typesafe.string,
73
+ }),
74
+ }),
75
+ ),
76
+ })
80
77
 
81
78
  export const stageConfig = Typesafe.record(
82
79
  Typesafe.string,
@@ -106,7 +103,7 @@ export const projectConfigSchema = Typesafe.object({
106
103
  Typesafe.object({
107
104
  useTenantDb: Typesafe.literal(true),
108
105
  }),
109
- dbCredentialsSchema,
106
+ dbConfigSchema,
110
107
  ),
111
108
  Typesafe.partial({
112
109
  systemSchema: Typesafe.string,
@@ -7,6 +7,19 @@ export const configTemplate: any = {
7
7
  password: `%tenant.env.DB_PASSWORD%`,
8
8
  database: `%tenant.env.DB_NAME%`,
9
9
  ssl: `%?tenant.env.DB_SSL::bool%`,
10
+ queryTimeoutMs: '%?tenant.env.DB_QUERY_TIMEOUT_MS::number%',
11
+ statementTimeoutMs: '%?tenant.env.DB_STATEMENT_TIMEOUT_MS::number%',
12
+ connectionTimeoutMs: '%?tenant.env.DB_CONNECTION_TIMEOUT_MS::number%',
13
+ pool: {
14
+ maxConnections: '%?tenant.env.DB_POOL_MAX_CONNECTIONS::number%',
15
+ maxConnecting: '%?tenant.env.DB_POOL_MAX_CONNECTING::number%',
16
+ maxIdle: '%?tenant.env.DB_POOL_MAX_IDLE::number%',
17
+ reconnectIntervalMs: '%?tenant.env.DB_POOL_RECONNECT_INTERVAL_MS::number%',
18
+ idleTimeoutMs: '%?tenant.env.DB_POOL_IDLE_TIMEOUT_MS::number%',
19
+ acquireTimeoutMs: '%?tenant.env.DB_POOL_ACQUIRE_TIMEOUT_MS::number%',
20
+ maxUses: '%?tenant.env.DB_POOL_MAX_USES::number%',
21
+ maxAgeMs: '%?tenant.env.DB_POOL_MAX_AGE_MS::number%',
22
+ },
10
23
  },
11
24
  mailer: {
12
25
  from: '%?tenant.env.MAILER_FROM%',
@@ -35,6 +48,16 @@ export const configTemplate: any = {
35
48
  password: `%?project.secret.db.password||project.env.DB_PASSWORD%`,
36
49
  database: `%?project.env.DB_NAME||project.slug%`,
37
50
  ssl: `%?project.env.DB_SSL::bool%`,
51
+ pool: {
52
+ maxConnections: '%?project.env.DB_POOL_MAX_CONNECTIONS%',
53
+ maxConnecting: '%?project.env.DB_POOL_MAX_CONNECTING%',
54
+ maxIdle: '%?project.env.DB_POOL_MAX_IDLE%',
55
+ reconnectIntervalMs: '%?project.env.DB_POOL_RECONNECT_INTERVAL_MS%',
56
+ idleTimeoutMs: '%?project.env.DB_POOL_IDLE_TIMEOUT_MS%',
57
+ acquireTimeoutMs: '%?project.env.DB_POOL_ACQUIRE_TIMEOUT_MS%',
58
+ maxUses: '%?project.env.DB_POOL_MAX_USES%',
59
+ maxAgeMs: '%?project.env.DB_POOL_MAX_AGE_MS%',
60
+ },
38
61
  },
39
62
  },
40
63
  server: {
package/src/index.ts CHANGED
@@ -1,9 +1,22 @@
1
1
  import { MasterContainerFactory, MasterContainerArgs } from './MasterContainer'
2
2
  import { ProjectConfig } from '@contember/engine-http'
3
3
  import { readConfig } from './config/config'
4
- import { ProcessType } from './utils'
4
+ import { serverConfigSchema } from './config/configSchema'
5
+ import { TenantConfigResolver } from './config/tenantConfigResolver'
6
+ import { ProjectGroupContainerFactory } from './projectGroup/ProjectGroupContainer'
5
7
 
6
- export { MasterContainerFactory, ProjectConfig, readConfig, ProcessType }
8
+ export * from './utils/serverStartup'
9
+ export * from './utils/serverTermination'
10
+ export * from './utils/sentry'
11
+ export * from './MasterContainer'
12
+
13
+ export {
14
+ ProjectConfig,
15
+ readConfig,
16
+ serverConfigSchema,
17
+ TenantConfigResolver,
18
+ ProjectGroupContainerFactory,
19
+ }
7
20
 
8
21
  export const createContainer = (args: MasterContainerArgs) => {
9
22
  return new MasterContainerFactory().create(args)
@@ -57,7 +57,7 @@ export class ProjectContainerFactory {
57
57
  .addService('project', () =>
58
58
  project)
59
59
  .addService('connection', ({ project }) =>
60
- new Connection(project.db, { timing: true }))
60
+ Connection.create(project.db))
61
61
  .addService('graphQlSchemaBuilderFactory', () =>
62
62
  new GraphQlSchemaBuilderFactory())
63
63
  .addService('permissionsByIdentityFactory', ({}) =>