@contember/engine-server 1.1.0-beta.3 → 1.2.0-alpha.1
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/dist/src/MasterContainer.d.ts +12 -25
- package/dist/src/MasterContainer.d.ts.map +1 -1
- package/dist/src/MasterContainer.js +36 -80
- package/dist/src/MasterContainer.js.map +1 -1
- package/dist/src/bootstrap/Initializer.d.ts +3 -3
- package/dist/src/bootstrap/Initializer.d.ts.map +1 -1
- package/dist/src/bootstrap/Initializer.js +15 -6
- package/dist/src/bootstrap/Initializer.js.map +1 -1
- package/dist/src/config/config.d.ts +5 -4
- package/dist/src/config/config.d.ts.map +1 -1
- package/dist/src/config/config.js +2 -2
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/configSchema.d.ts +45 -11
- package/dist/src/config/configSchema.d.ts.map +1 -1
- package/dist/src/config/configSchema.js +20 -18
- package/dist/src/config/configSchema.js.map +1 -1
- package/dist/src/config/configTemplate.d.ts.map +1 -1
- package/dist/src/config/configTemplate.js +23 -0
- package/dist/src/config/configTemplate.js.map +1 -1
- package/dist/src/index.d.ts +9 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +23 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/project/ProjectContainer.js +1 -1
- package/dist/src/project/ProjectContainer.js.map +1 -1
- package/dist/src/project/ProjectContainerResolver.d.ts +6 -3
- package/dist/src/project/ProjectContainerResolver.d.ts.map +1 -1
- package/dist/src/project/ProjectContainerResolver.js +4 -16
- package/dist/src/project/ProjectContainerResolver.js.map +1 -1
- package/dist/src/projectGroup/ProjectGroupContainer.d.ts +2 -1
- package/dist/src/projectGroup/ProjectGroupContainer.d.ts.map +1 -1
- package/dist/src/projectGroup/ProjectGroupContainer.js +8 -4
- package/dist/src/projectGroup/ProjectGroupContainer.js.map +1 -1
- package/dist/src/projectGroup/ProjectGroupResolver.d.ts +7 -0
- package/dist/src/projectGroup/ProjectGroupResolver.d.ts.map +1 -0
- package/dist/src/projectGroup/ProjectGroupResolver.js +13 -0
- package/dist/src/projectGroup/ProjectGroupResolver.js.map +1 -0
- package/dist/src/start.js +15 -112
- package/dist/src/start.js.map +1 -1
- package/dist/src/tsconfig.tsbuildinfo +1 -1
- package/dist/src/utils/index.d.ts +0 -4
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +0 -4
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/serverStartup.d.ts +31 -0
- package/dist/src/utils/serverStartup.d.ts.map +1 -0
- package/dist/src/utils/serverStartup.js +42 -0
- package/dist/src/utils/serverStartup.js.map +1 -0
- package/dist/src/utils/serverTermination.d.ts +12 -0
- package/dist/src/utils/serverTermination.d.ts.map +1 -0
- package/dist/src/utils/serverTermination.js +26 -0
- package/dist/src/utils/serverTermination.js.map +1 -0
- package/dist/tests/e2e/http.test.js +74 -157
- package/dist/tests/e2e/http.test.js.map +1 -1
- package/dist/tests/e2e/requests.d.ts +4 -0
- package/dist/tests/e2e/requests.d.ts.map +1 -0
- package/dist/tests/e2e/requests.js +59 -0
- package/dist/tests/e2e/requests.js.map +1 -0
- package/dist/tests/e2e/tester.d.ts +19 -0
- package/dist/tests/e2e/tester.d.ts.map +1 -0
- package/dist/tests/e2e/tester.js +99 -0
- package/dist/tests/e2e/tester.js.map +1 -0
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/esbuild.js +7 -14
- package/package.json +20 -20
- package/src/MasterContainer.ts +58 -110
- package/src/bootstrap/Initializer.ts +16 -6
- package/src/config/config.ts +7 -5
- package/src/config/configSchema.ts +30 -33
- package/src/config/configTemplate.ts +23 -0
- package/src/index.ts +15 -2
- package/src/project/ProjectContainer.ts +1 -1
- package/src/project/ProjectContainerResolver.ts +4 -17
- package/src/projectGroup/ProjectGroupContainer.ts +12 -3
- package/src/projectGroup/ProjectGroupResolver.ts +12 -0
- package/src/start.ts +18 -127
- package/src/utils/index.ts +0 -4
- package/src/utils/serverStartup.ts +42 -0
- package/src/utils/serverTermination.ts +20 -0
- package/tests/e2e/http.test.ts +84 -150
- package/tests/e2e/requests.ts +71 -0
- package/tests/e2e/tester.ts +118 -0
- package/alpine.dockerfile +0 -30
- package/debian.dockerfile +0 -27
- package/dist/src/http/CollectHttpMetricsMiddelware.d.ts +0 -5
- package/dist/src/http/CollectHttpMetricsMiddelware.d.ts.map +0 -1
- package/dist/src/http/CollectHttpMetricsMiddelware.js +0 -36
- package/dist/src/http/CollectHttpMetricsMiddelware.js.map +0 -1
- package/dist/src/http/ShowMetricsMiddleware.d.ts +0 -4
- package/dist/src/http/ShowMetricsMiddleware.d.ts.map +0 -1
- package/dist/src/http/ShowMetricsMiddleware.js +0 -20
- package/dist/src/http/ShowMetricsMiddleware.js.map +0 -1
- package/dist/src/http/index.d.ts +0 -3
- package/dist/src/http/index.d.ts.map +0 -1
- package/dist/src/http/index.js +0 -19
- package/dist/src/http/index.js.map +0 -1
- package/dist/src/projectGroup/ProjectGroupContainerResolver.d.ts +0 -12
- package/dist/src/projectGroup/ProjectGroupContainerResolver.d.ts.map +0 -1
- package/dist/src/projectGroup/ProjectGroupContainerResolver.js +0 -36
- package/dist/src/projectGroup/ProjectGroupContainerResolver.js.map +0 -1
- package/dist/src/utils/cluster.d.ts +0 -9
- package/dist/src/utils/cluster.d.ts.map +0 -1
- package/dist/src/utils/cluster.js +0 -47
- package/dist/src/utils/cluster.js.map +0 -1
- package/dist/src/utils/dbMetrics.d.ts +0 -16
- package/dist/src/utils/dbMetrics.d.ts.map +0 -1
- package/dist/src/utils/dbMetrics.js +0 -98
- package/dist/src/utils/dbMetrics.js.map +0 -1
- package/dist/src/utils/timeout.d.ts +0 -2
- package/dist/src/utils/timeout.d.ts.map +0 -1
- package/dist/src/utils/timeout.js +0 -8
- package/dist/src/utils/timeout.js.map +0 -1
- package/dist/src/utils/tuple.d.ts +0 -2
- package/dist/src/utils/tuple.d.ts.map +0 -1
- package/dist/src/utils/tuple.js +0 -6
- package/dist/src/utils/tuple.js.map +0 -1
- package/jasmine.json +0 -7
- package/src/http/CollectHttpMetricsMiddelware.ts +0 -32
- package/src/http/ShowMetricsMiddleware.ts +0 -12
- package/src/http/index.ts +0 -2
- package/src/projectGroup/ProjectGroupContainerResolver.ts +0 -47
- package/src/utils/cluster.ts +0 -40
- package/src/utils/dbMetrics.ts +0 -111
- package/src/utils/timeout.ts +0 -4
- package/src/utils/tuple.ts +0 -1
- package/tslint.json +0 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contember/engine-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-alpha.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"typings": "dist/src/index.d.ts",
|
|
@@ -8,24 +8,24 @@
|
|
|
8
8
|
"test-e2e": "vitest --no-threads tests/e2e"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@contember/authorization": "^1.
|
|
12
|
-
"@contember/config-loader": "^1.
|
|
13
|
-
"@contember/database": "^1.
|
|
14
|
-
"@contember/database-migrations": "^1.
|
|
15
|
-
"@contember/dic": "^1.
|
|
16
|
-
"@contember/typesafe": "^1.
|
|
17
|
-
"@contember/engine-content-api": "^1.
|
|
18
|
-
"@contember/engine-http": "^1.
|
|
19
|
-
"@contember/engine-plugins": "^1.
|
|
20
|
-
"@contember/engine-s3-plugin": "^1.
|
|
21
|
-
"@contember/engine-system-api": "^1.
|
|
22
|
-
"@contember/engine-tenant-api": "^1.
|
|
23
|
-
"@contember/engine-vimeo-plugin": "^1.
|
|
24
|
-
"@contember/queryable": "^1.
|
|
25
|
-
"@contember/schema": "^1.
|
|
26
|
-
"@contember/schema-definition": "^1.
|
|
27
|
-
"@contember/schema-migrations": "^1.
|
|
28
|
-
"@contember/schema-utils": "^1.
|
|
11
|
+
"@contember/authorization": "^1.2.0-alpha.1",
|
|
12
|
+
"@contember/config-loader": "^1.2.0-alpha.1",
|
|
13
|
+
"@contember/database": "^1.2.0-alpha.1",
|
|
14
|
+
"@contember/database-migrations": "^1.2.0-alpha.1",
|
|
15
|
+
"@contember/dic": "^1.2.0-alpha.1",
|
|
16
|
+
"@contember/typesafe": "^1.2.0-alpha.1",
|
|
17
|
+
"@contember/engine-content-api": "^1.2.0-alpha.1",
|
|
18
|
+
"@contember/engine-http": "^1.2.0-alpha.1",
|
|
19
|
+
"@contember/engine-plugins": "^1.2.0-alpha.1",
|
|
20
|
+
"@contember/engine-s3-plugin": "^1.2.0-alpha.1",
|
|
21
|
+
"@contember/engine-system-api": "^1.2.0-alpha.1",
|
|
22
|
+
"@contember/engine-tenant-api": "^1.2.0-alpha.1",
|
|
23
|
+
"@contember/engine-vimeo-plugin": "^1.2.0-alpha.1",
|
|
24
|
+
"@contember/queryable": "^1.2.0-alpha.1",
|
|
25
|
+
"@contember/schema": "^1.2.0-alpha.1",
|
|
26
|
+
"@contember/schema-definition": "^1.2.0-alpha.1",
|
|
27
|
+
"@contember/schema-migrations": "^1.2.0-alpha.1",
|
|
28
|
+
"@contember/schema-utils": "^1.2.0-alpha.1",
|
|
29
29
|
"@koa/cors": "^3.1.0",
|
|
30
30
|
"@sentry/node": "^6.8.0",
|
|
31
31
|
"graphql": "^15.4.0",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"uuid": "^8.3.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@contember/engine-api-tester": "^1.
|
|
40
|
+
"@contember/engine-api-tester": "^1.2.0-alpha.1",
|
|
41
41
|
"@types/koa-compress": "^4.0.1",
|
|
42
42
|
"@types/node": "^17.0.5",
|
|
43
43
|
"@types/supertest": "^2.0.8",
|
package/src/MasterContainer.ts
CHANGED
|
@@ -2,11 +2,10 @@ 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 {
|
|
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,
|
|
@@ -18,31 +17,31 @@ import {
|
|
|
18
17
|
createPoweredByHeaderMiddleware,
|
|
19
18
|
createProviders,
|
|
20
19
|
createTimerMiddleware,
|
|
21
|
-
CryptoWrapper,
|
|
22
20
|
ErrorMiddlewareFactory,
|
|
23
21
|
Koa,
|
|
24
22
|
NotModifiedChecker,
|
|
25
|
-
ProjectGroupResolver,
|
|
26
23
|
Providers,
|
|
27
|
-
route,
|
|
28
|
-
|
|
24
|
+
route,
|
|
25
|
+
SystemApiMiddlewareFactory,
|
|
26
|
+
SystemGraphQLContextFactory,
|
|
27
|
+
SystemGraphQLHandlerFactory,
|
|
28
|
+
TenantApiMiddlewareFactory,
|
|
29
|
+
TenantGraphQLContextFactory,
|
|
29
30
|
TenantGraphQLHandlerFactory,
|
|
30
31
|
} from '@contember/engine-http'
|
|
31
|
-
import prom from 'prom-client'
|
|
32
32
|
import { ProjectContainerFactoryFactory } from './project'
|
|
33
|
-
import { createSecretKey } from 'crypto'
|
|
34
33
|
import koaCompress from 'koa-compress'
|
|
35
34
|
import bodyParser from 'koa-bodyparser'
|
|
36
35
|
import { ProjectConfigResolver } from './config/projectConfigResolver'
|
|
37
36
|
import { TenantConfigResolver } from './config/tenantConfigResolver'
|
|
38
|
-
import { ProjectGroupContainerResolver } from './projectGroup/ProjectGroupContainerResolver'
|
|
39
37
|
import { ProjectGroupContainerFactory } from './projectGroup/ProjectGroupContainer'
|
|
40
38
|
import corsMiddleware from '@koa/cors'
|
|
39
|
+
import { ProjectGroupResolver } from './projectGroup/ProjectGroupResolver'
|
|
40
|
+
import { ProjectGroupContainer, ProjectGroupResolver as ProjectGroupResolverInterface } from '@contember/engine-http'
|
|
41
41
|
|
|
42
42
|
export interface MasterContainer {
|
|
43
43
|
initializer: Initializer
|
|
44
44
|
koa: Koa
|
|
45
|
-
monitoringKoa: Koa
|
|
46
45
|
providers: Providers
|
|
47
46
|
}
|
|
48
47
|
|
|
@@ -52,7 +51,6 @@ export interface MasterContainerArgs {
|
|
|
52
51
|
projectConfigResolver: ProjectConfigResolver
|
|
53
52
|
tenantConfigResolver: TenantConfigResolver
|
|
54
53
|
plugins: Plugin[]
|
|
55
|
-
processType: ProcessType
|
|
56
54
|
version?: string
|
|
57
55
|
}
|
|
58
56
|
|
|
@@ -63,7 +61,6 @@ export class MasterContainerFactory {
|
|
|
63
61
|
plugins,
|
|
64
62
|
projectConfigResolver,
|
|
65
63
|
tenantConfigResolver,
|
|
66
|
-
processType,
|
|
67
64
|
version,
|
|
68
65
|
}: MasterContainerArgs) {
|
|
69
66
|
return new Builder({})
|
|
@@ -71,8 +68,6 @@ export class MasterContainerFactory {
|
|
|
71
68
|
serverConfig)
|
|
72
69
|
.addService('debugMode', () =>
|
|
73
70
|
debugMode)
|
|
74
|
-
.addService('processType', () =>
|
|
75
|
-
processType)
|
|
76
71
|
.addService('version', () =>
|
|
77
72
|
version)
|
|
78
73
|
.addService('projectConfigResolver', () =>
|
|
@@ -95,62 +90,22 @@ export class MasterContainerFactory {
|
|
|
95
90
|
new TenantGraphQLHandlerFactory(logSentryError))
|
|
96
91
|
.addService('systemGraphQLHandlerFactory', ({ debugMode }) =>
|
|
97
92
|
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('
|
|
101
|
-
|
|
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
|
-
})
|
|
93
|
+
.addService('projectGroupContainerFactory', ({ debugMode, providers, systemContainerFactory, tenantContainerFactory, projectContainerFactoryFactory, projectConfigResolver, tenantGraphQLHandlerFactory, systemGraphQLHandlerFactory }) =>
|
|
94
|
+
new ProjectGroupContainerFactory(debugMode, providers, systemContainerFactory, tenantContainerFactory, projectContainerFactoryFactory, projectConfigResolver, tenantGraphQLHandlerFactory, systemGraphQLHandlerFactory))
|
|
95
|
+
.addService('projectGroupContainer', ({ tenantConfigResolver, projectGroupContainerFactory }) =>
|
|
96
|
+
projectGroupContainerFactory.create({ slug: undefined, config: tenantConfigResolver(undefined, {}) }))
|
|
133
97
|
.addService('httpErrorMiddlewareFactory', ({ debugMode }) =>
|
|
134
98
|
new ErrorMiddlewareFactory(debugMode))
|
|
135
|
-
.addService('projectGroupResolver', ({
|
|
136
|
-
|
|
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
|
-
})
|
|
99
|
+
.addService('projectGroupResolver', ({ projectGroupContainer }): ProjectGroupResolverInterface =>
|
|
100
|
+
new ProjectGroupResolver(projectGroupContainer))
|
|
146
101
|
.addService('notModifiedChecker', () =>
|
|
147
102
|
new NotModifiedChecker())
|
|
148
103
|
.addService('contentGraphqlContextFactory', ({ providers }) =>
|
|
149
104
|
new ContentGraphQLContextFactory(providers))
|
|
150
105
|
.addService('contentQueryHandlerFactory', ({ debugMode }) =>
|
|
151
106
|
new ContentQueryHandlerFactory(debugMode, logSentryError))
|
|
152
|
-
.addService('contentApiMiddlewareFactory', ({
|
|
153
|
-
new ContentApiMiddlewareFactory(
|
|
107
|
+
.addService('contentApiMiddlewareFactory', ({ projectGroupResolver, notModifiedChecker, contentGraphqlContextFactory, contentQueryHandlerFactory }) =>
|
|
108
|
+
new ContentApiMiddlewareFactory(projectGroupResolver, notModifiedChecker, contentGraphqlContextFactory, contentQueryHandlerFactory))
|
|
154
109
|
.addService('tenantGraphQLContextFactory', () =>
|
|
155
110
|
new TenantGraphQLContextFactory())
|
|
156
111
|
.addService('tenantApiMiddlewareFactory', ({ debugMode, projectGroupResolver, tenantGraphQLContextFactory }) =>
|
|
@@ -159,62 +114,55 @@ export class MasterContainerFactory {
|
|
|
159
114
|
new SystemGraphQLContextFactory())
|
|
160
115
|
.addService('systemApiMiddlewareFactory', ({ debugMode, projectGroupResolver, systemGraphQLContextFactory }) =>
|
|
161
116
|
new SystemApiMiddlewareFactory(debugMode, projectGroupResolver, systemGraphQLContextFactory))
|
|
162
|
-
.addService('
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
),
|
|
200
|
-
]),
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
return app
|
|
204
|
-
})
|
|
205
|
-
.addService('monitoringKoa', ({ promRegistry }) => {
|
|
117
|
+
.addService('koaMiddlewares', ({ contentApiMiddlewareFactory, tenantApiMiddlewareFactory, systemApiMiddlewareFactory, httpErrorMiddlewareFactory, debugMode, version, serverConfig }) =>
|
|
118
|
+
compose([
|
|
119
|
+
koaCompress({
|
|
120
|
+
br: false,
|
|
121
|
+
}),
|
|
122
|
+
bodyParser({
|
|
123
|
+
jsonLimit: serverConfig.http.requestBodySize || '1mb',
|
|
124
|
+
}),
|
|
125
|
+
createPoweredByHeaderMiddleware(debugMode, version ?? 'unknown'),
|
|
126
|
+
httpErrorMiddlewareFactory.create(),
|
|
127
|
+
createTimerMiddleware(),
|
|
128
|
+
route('/playground$', createPlaygroundMiddleware()),
|
|
129
|
+
createHomepageMiddleware(),
|
|
130
|
+
corsMiddleware(),
|
|
131
|
+
route(
|
|
132
|
+
'/content/:projectSlug/:stageSlug$',
|
|
133
|
+
compose([
|
|
134
|
+
createModuleInfoMiddleware('content'),
|
|
135
|
+
contentApiMiddlewareFactory.create(),
|
|
136
|
+
]),
|
|
137
|
+
),
|
|
138
|
+
route(
|
|
139
|
+
'/tenant$',
|
|
140
|
+
compose([
|
|
141
|
+
createModuleInfoMiddleware('tenant'),
|
|
142
|
+
tenantApiMiddlewareFactory.create(),
|
|
143
|
+
]),
|
|
144
|
+
),
|
|
145
|
+
route(
|
|
146
|
+
'/system/:projectSlug$',
|
|
147
|
+
compose([
|
|
148
|
+
createModuleInfoMiddleware('system'),
|
|
149
|
+
systemApiMiddlewareFactory.create(),
|
|
150
|
+
]),
|
|
151
|
+
),
|
|
152
|
+
]))
|
|
153
|
+
.addService('koa', ({ koaMiddlewares }) => {
|
|
206
154
|
const app = new Koa()
|
|
207
|
-
app.use(
|
|
155
|
+
app.use(koaMiddlewares)
|
|
208
156
|
|
|
209
157
|
return app
|
|
210
158
|
})
|
|
211
|
-
.addService('initializer', ({
|
|
212
|
-
new Initializer(
|
|
159
|
+
.addService('initializer', ({ projectGroupContainer }) =>
|
|
160
|
+
new Initializer(projectGroupContainer))
|
|
213
161
|
|
|
214
162
|
}
|
|
215
163
|
|
|
216
164
|
create(args: MasterContainerArgs): MasterContainer {
|
|
217
165
|
const container = this.createBuilder(args).build()
|
|
218
|
-
return container.pick('initializer', 'koa', '
|
|
166
|
+
return container.pick('initializer', 'koa', 'providers')
|
|
219
167
|
}
|
|
220
168
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Logger } from '@contember/engine-common'
|
|
2
|
-
import {
|
|
2
|
+
import { ProjectGroupContainer } from '@contember/engine-http'
|
|
3
3
|
|
|
4
4
|
export class Initializer {
|
|
5
5
|
constructor(
|
|
6
|
-
private readonly
|
|
6
|
+
private readonly projectGroupContainer: ProjectGroupContainer,
|
|
7
7
|
) {}
|
|
8
8
|
|
|
9
9
|
public async initialize(): Promise<string[]> {
|
|
@@ -11,17 +11,27 @@ 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.
|
|
14
|
+
const groupContainer = await this.projectGroupContainer
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
const tenantContainer = groupContainer.tenantContainer
|
|
17
|
+
await tenantContainer.migrationsRunner.run(logger.write.bind(logger))
|
|
17
18
|
logger.groupEnd()
|
|
18
19
|
|
|
19
20
|
const systemContainer = groupContainer.systemContainer
|
|
20
21
|
const projects: string[] = []
|
|
21
|
-
|
|
22
|
+
|
|
23
|
+
const tenantProjects = await tenantContainer.projectManager.getProjects(tenantContainer.databaseContext)
|
|
24
|
+
for (const { slug: projectSlug } of tenantProjects) {
|
|
25
|
+
logger.group(`\nUpdating project ${projectSlug}`)
|
|
26
|
+
const projectContainer = await groupContainer.projectContainerResolver.getProjectContainer(projectSlug, {
|
|
27
|
+
alias: false,
|
|
28
|
+
logger,
|
|
29
|
+
})
|
|
30
|
+
if (!projectContainer) {
|
|
31
|
+
throw new Error()
|
|
32
|
+
}
|
|
22
33
|
const project = projectContainer.project
|
|
23
34
|
projects.push(project.slug)
|
|
24
|
-
logger.group(`\nUpdating project ${project.slug}`)
|
|
25
35
|
await systemContainer.projectInitializer.initialize(projectContainer.systemDatabaseContextFactory, project, logger)
|
|
26
36
|
logger.groupEnd()
|
|
27
37
|
}
|
package/src/config/config.ts
CHANGED
|
@@ -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
|
|
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:
|
|
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
|
|
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:
|
|
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
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
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 {
|
|
4
|
+
import { serverConfigSchema } from './config/configSchema'
|
|
5
|
+
import { TenantConfigResolver } from './config/tenantConfigResolver'
|
|
6
|
+
import { ProjectGroupContainerFactory } from './projectGroup/ProjectGroupContainer'
|
|
5
7
|
|
|
6
|
-
export
|
|
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
|
-
|
|
60
|
+
Connection.create(project.db, { timing: true }))
|
|
61
61
|
.addService('graphQlSchemaBuilderFactory', () =>
|
|
62
62
|
new GraphQlSchemaBuilderFactory())
|
|
63
63
|
.addService('permissionsByIdentityFactory', ({}) =>
|
|
@@ -21,20 +21,8 @@ export class ProjectContainerResolver {
|
|
|
21
21
|
private readonly tenantConfig: TenantConfig,
|
|
22
22
|
) {}
|
|
23
23
|
|
|
24
|
-
public async getAllProjectContainers(): Promise<ProjectContainer[]> {
|
|
25
|
-
const projects = await this.projectManager.getProjects(this.tenantDatabase)
|
|
26
|
-
return await Promise.all(
|
|
27
|
-
projects.map(async it => {
|
|
28
|
-
const container = await this.getProjectContainer(it.slug)
|
|
29
|
-
if (!container) {
|
|
30
|
-
throw new Error('should not happen')
|
|
31
|
-
}
|
|
32
|
-
return container
|
|
33
|
-
}),
|
|
34
|
-
)
|
|
35
|
-
}
|
|
36
24
|
|
|
37
|
-
public async getProjectContainer(slug: string, alias: boolean =
|
|
25
|
+
public async getProjectContainer(slug: string, { alias = false, logger }: {alias?: boolean; logger?: Logger} = {}): Promise<ProjectContainer | undefined> {
|
|
38
26
|
const realSlug = this.projectContainers.resolveAlias(slug)
|
|
39
27
|
if (realSlug) {
|
|
40
28
|
slug = realSlug
|
|
@@ -55,14 +43,14 @@ export class ProjectContainerResolver {
|
|
|
55
43
|
if (!project) {
|
|
56
44
|
return undefined
|
|
57
45
|
}
|
|
58
|
-
const container = await this.createProjectContainer(project)
|
|
46
|
+
const container = await this.createProjectContainer(project, logger)
|
|
59
47
|
if (slug !== project.slug) {
|
|
60
48
|
this.projectContainers.setAlias(project.slug, slug)
|
|
61
49
|
}
|
|
62
50
|
return container
|
|
63
51
|
}
|
|
64
52
|
|
|
65
|
-
public async createProjectContainer(project: ProjectWithSecrets): Promise<ProjectContainer> {
|
|
53
|
+
public async createProjectContainer(project: ProjectWithSecrets, logger?: Logger): Promise<ProjectContainer> {
|
|
66
54
|
const projectConfig = this.projectConfigResolver(project.slug, project.config, project.secrets, this.tenantConfig)
|
|
67
55
|
return (await this.projectContainers.fetchContainer(project.slug, async slug => {
|
|
68
56
|
const projectContainer = this.projectContainerFactory.createContainer({
|
|
@@ -71,8 +59,7 @@ export class ProjectContainerResolver {
|
|
|
71
59
|
await this.systemProjectInitializer.initialize(
|
|
72
60
|
projectContainer.systemDatabaseContextFactory,
|
|
73
61
|
projectContainer.project,
|
|
74
|
-
|
|
75
|
-
new Logger(console.log),
|
|
62
|
+
logger ?? new Logger(() => null),
|
|
76
63
|
)
|
|
77
64
|
const cleanups = this.onCreate.map(it => it(projectContainer) || (() => null))
|
|
78
65
|
return {
|