@contember/engine-server 1.1.0-alpha.3 → 1.1.0-alpha.6

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 (41) hide show
  1. package/alpine.dockerfile +1 -1
  2. package/debian.dockerfile +1 -1
  3. package/dist/src/bootstrap/index.js +5 -1
  4. package/dist/src/bootstrap/index.js.map +1 -1
  5. package/dist/src/config/config.js.map +1 -1
  6. package/dist/src/config/configSchema.d.ts +10 -8
  7. package/dist/src/config/configSchema.d.ts.map +1 -1
  8. package/dist/src/config/configSchema.js +74 -51
  9. package/dist/src/config/configSchema.js.map +1 -1
  10. package/dist/src/config/projectConfigResolver.d.ts.map +1 -1
  11. package/dist/src/config/projectConfigResolver.js +30 -2
  12. package/dist/src/config/projectConfigResolver.js.map +1 -1
  13. package/dist/src/http/index.js +5 -1
  14. package/dist/src/http/index.js.map +1 -1
  15. package/dist/src/project/index.js +5 -1
  16. package/dist/src/project/index.js.map +1 -1
  17. package/dist/src/start.js +5 -1
  18. package/dist/src/start.js.map +1 -1
  19. package/dist/src/tsconfig.tsbuildinfo +1 -1
  20. package/dist/src/utils/cluster.js.map +1 -1
  21. package/dist/src/utils/index.js +5 -1
  22. package/dist/src/utils/index.js.map +1 -1
  23. package/dist/src/utils/sentry.js +5 -1
  24. package/dist/src/utils/sentry.js.map +1 -1
  25. package/dist/tests/e2e/http.test.d.ts +2 -0
  26. package/dist/tests/e2e/http.test.d.ts.map +1 -0
  27. package/dist/tests/e2e/http.test.js +275 -0
  28. package/dist/tests/e2e/http.test.js.map +1 -0
  29. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +22 -23
  31. package/src/config/configSchema.ts +9 -8
  32. package/src/config/projectConfigResolver.ts +7 -4
  33. package/src/tsconfig.json +3 -0
  34. package/tests/e2e/http.test.ts +303 -0
  35. package/tests/start-server.sh +16 -0
  36. package/vite.config.js +3 -0
  37. package/dist/tests/cases/http.d.ts +0 -2
  38. package/dist/tests/cases/http.d.ts.map +0 -1
  39. package/dist/tests/cases/http.js +0 -298
  40. package/dist/tests/cases/http.js.map +0 -1
  41. package/tests/cases/http.ts +0 -340
@@ -1,298 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
- Object.defineProperty(o, "default", { enumerable: true, value: v });
11
- }) : function(o, v) {
12
- o["default"] = v;
13
- });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
20
- };
21
- var __importDefault = (this && this.__importDefault) || function (mod) {
22
- return (mod && mod.__esModule) ? mod : { "default": mod };
23
- };
24
- Object.defineProperty(exports, "__esModule", { value: true });
25
- const supertest_1 = __importDefault(require("supertest"));
26
- const src_1 = require("../../src");
27
- const engine_api_tester_1 = require("@contember/engine-api-tester");
28
- const nodeAssert = __importStar(require("assert"));
29
- const assert = __importStar(require("uvu/assert"));
30
- const uvu_1 = require("uvu");
31
- const prom_client_1 = __importDefault(require("prom-client"));
32
- const schema_migrations_1 = require("@contember/schema-migrations");
33
- const engine_common_1 = require("@contember/engine-common");
34
- const dbCredentials = (dbName) => {
35
- return {
36
- host: String(process.env.TEST_DB_HOST),
37
- port: Number(process.env.TEST_DB_PORT),
38
- user: String(process.env.TEST_DB_USER),
39
- password: String(process.env.TEST_DB_PASSWORD),
40
- database: dbName,
41
- };
42
- };
43
- const rootToken = String(process.env.CONTEMBER_ROOT_TOKEN);
44
- const loginToken = String(process.env.CONTEMBER_LOGIN_TOKEN);
45
- // Used to allow prettier formatting of GraphQL queries
46
- const gql = (strings) => {
47
- nodeAssert.strictEqual(strings.length, 1);
48
- return strings[0];
49
- };
50
- const projectConfig = {
51
- db: dbCredentials(String(process.env.TEST_DB_NAME)),
52
- name: 'test',
53
- slug: 'test',
54
- stages: [{ name: 'prod', slug: 'prod' }],
55
- };
56
- const createContainer = (debug) => {
57
- prom_client_1.default.register.clear();
58
- const tenantConfig = {
59
- db: dbCredentials(String(process.env.TEST_DB_NAME_TENANT)),
60
- mailer: {},
61
- credentials: {
62
- rootToken,
63
- loginToken,
64
- },
65
- secrets: {},
66
- };
67
- return new src_1.MasterContainerFactory().createBuilder({
68
- debugMode: debug,
69
- serverConfig: {
70
- logging: {},
71
- port: 0,
72
- monitoringPort: 0,
73
- http: {},
74
- },
75
- projectConfigResolver: () => projectConfig,
76
- tenantConfigResolver: () => tenantConfig,
77
- plugins: [],
78
- processType: src_1.ProcessType.singleNode,
79
- }).build();
80
- };
81
- const executeGraphql = (query, options = {}) => {
82
- const container = createContainer(options.debug || false);
83
- return (0, supertest_1.default)(container.koa.callback())
84
- .post(options.path || '/content/test/prod')
85
- .set('Authorization', 'Bearer ' + (options.authorizationToken || rootToken))
86
- .send({
87
- query,
88
- variables: options.variables || {},
89
- });
90
- };
91
- const signIn = async (email, password) => {
92
- const response2 = await executeGraphql(gql `
93
- mutation ($email: String!, $password: String!) {
94
- signIn(email: $email, password: $password) {
95
- ok
96
- result {
97
- token
98
- }
99
- }
100
- }
101
- `, {
102
- variables: { email, password },
103
- authorizationToken: loginToken,
104
- path: '/tenant',
105
- });
106
- return response2.body.data.signIn.result.token;
107
- };
108
- uvu_1.test.before(async () => {
109
- try {
110
- const connection = await (0, engine_api_tester_1.recreateDatabase)(String(process.env.TEST_DB_NAME));
111
- await connection.end();
112
- const tenantConnection = await (0, engine_api_tester_1.recreateDatabase)(String(process.env.TEST_DB_NAME_TENANT));
113
- const migrationsResolver = new schema_migrations_1.MigrationsResolver(schema_migrations_1.MigrationFilesManager.createForProject((0, engine_api_tester_1.getExampleProjectDirectory)(), 'sample'));
114
- const container = createContainer(false);
115
- await container.initializer.initialize();
116
- const { slug, name, ...config } = projectConfig;
117
- const groupContainer = await container.projectGroupContainerResolver.getProjectGroupContainer(undefined);
118
- const tenantContainer = groupContainer.tenantContainer;
119
- const result = await tenantContainer.projectManager.createProject(tenantContainer.databaseContext, { slug, name, config: config, secrets: {} }, undefined);
120
- if (!result) {
121
- throw new Error('Project already exists');
122
- }
123
- const projectContainer = await groupContainer.projectContainerResolver.getProjectContainer(slug);
124
- if (!projectContainer) {
125
- throw new Error('Should not happen');
126
- }
127
- await groupContainer.systemContainer.projectInitializer.initialize(projectContainer.systemDatabaseContextFactory, projectConfig, new engine_common_1.Logger(() => null), await migrationsResolver.getMigrations());
128
- await tenantConnection.end();
129
- }
130
- catch (e) {
131
- // eslint-disable-next-line no-console
132
- console.error(e);
133
- process.exit(1);
134
- }
135
- });
136
- (0, uvu_1.test)('show homepage', async () => {
137
- await (0, supertest_1.default)(createContainer(false).koa.callback()) //
138
- .get('/')
139
- .expect(200)
140
- .expect('App is running');
141
- });
142
- (0, uvu_1.test)('Content API: create & read tag', async () => {
143
- await executeGraphql(gql `
144
- mutation {
145
- createTag(data: { label: "graphql" }) {
146
- ok
147
- }
148
- }
149
- `)
150
- .expect(response => {
151
- assert.equal(response.body.data, {
152
- createTag: {
153
- ok: true,
154
- },
155
- });
156
- })
157
- .expect(200);
158
- await executeGraphql(gql `
159
- query {
160
- listTag(filter: { label: { eq: "graphql" } }) {
161
- label
162
- }
163
- }
164
- `)
165
- .expect(response => {
166
- assert.equal(response.body.data, {
167
- listTag: [
168
- {
169
- label: 'graphql',
170
- },
171
- ],
172
- });
173
- })
174
- .expect(200);
175
- });
176
- (0, uvu_1.test)('Content API: X-Contember-Ref header', async () => {
177
- await executeGraphql(gql `
178
- mutation {
179
- createTag(data: { label: "typescript" }) {
180
- ok
181
- }
182
- }
183
- `).expect(200);
184
- const response = await executeGraphql(gql `
185
- query {
186
- listTag(filter: { label: { eq: "typescript" } }) {
187
- label
188
- }
189
- }
190
- `)
191
- .set('X-Contember-Ref', 'None')
192
- .expect(response => {
193
- assert.equal(response.body.data, {
194
- listTag: [
195
- {
196
- label: 'typescript',
197
- },
198
- ],
199
- });
200
- })
201
- .expect(200);
202
- const eventKey = response.get('X-Contember-Ref');
203
- await executeGraphql(gql `
204
- query {
205
- listTag {
206
- label
207
- }
208
- }
209
- `)
210
- .set('X-Contember-Ref', eventKey)
211
- .expect(304);
212
- // ignored for mutation
213
- await executeGraphql(gql `
214
- mutation {
215
- createTag(data: { label: "typescript" }) {
216
- ok
217
- }
218
- }
219
- `)
220
- .set('X-Contember-Ref', eventKey)
221
- .expect(200);
222
- });
223
- (0, uvu_1.test)('Content API: invalid schema error', async () => {
224
- await executeGraphql(gql `
225
- mutation {
226
- createFoo(data: { label: "graphql" }) {
227
- ok
228
- }
229
- }
230
- `)
231
- .expect(400)
232
- .expect(response => {
233
- assert.equal(response.body.errors[0].message, 'Cannot query field "createFoo" on type "Mutation". Did you mean "createPost" or "createTag"?');
234
- });
235
- });
236
- (0, uvu_1.test)('Tenant API: sign up, add to a project and check project access', async () => {
237
- const signUpResponse = await executeGraphql(gql `
238
- mutation {
239
- signUp(email: "john@doe.com", password: "123456") {
240
- ok
241
- result {
242
- person {
243
- identity {
244
- id
245
- }
246
- }
247
- }
248
- }
249
- }
250
- `, { path: '/tenant' }).expect(200);
251
- const identityId = signUpResponse.body.data.signUp.result.person.identity.id;
252
- const authKey = await signIn('john@doe.com', '123456');
253
- await executeGraphql(gql `
254
- query {
255
- listTag {
256
- id
257
- }
258
- }
259
- `, { authorizationToken: authKey })
260
- .expect(404)
261
- .expect({ errors: [{ message: 'Project test NOT found', code: 404 }] });
262
- await executeGraphql(gql `
263
- query {
264
- listTag {
265
- id
266
- }
267
- }
268
- `, { authorizationToken: authKey, debug: true })
269
- .expect(403)
270
- .expect({
271
- errors: [{ message: 'You are not allowed to access project test', code: 403 }],
272
- identity: { roles: ['person'] },
273
- });
274
- await executeGraphql(gql `
275
- mutation ($identity: String!) {
276
- addProjectMember(identityId: $identity, projectSlug: "test", memberships: [{ role: "admin", variables: [] }]) {
277
- ok
278
- }
279
- }
280
- `, { path: '/tenant', variables: { identity: identityId } })
281
- .expect(200)
282
- .expect(response => {
283
- assert.equal(response.body.data, { addProjectMember: { ok: true } });
284
- });
285
- await executeGraphql(gql `
286
- query {
287
- listAuthor {
288
- id
289
- }
290
- }
291
- `, { authorizationToken: authKey })
292
- .expect(response => {
293
- assert.equal(response.body.data, { listAuthor: [] });
294
- })
295
- .expect(200);
296
- });
297
- uvu_1.test.run();
298
- //# sourceMappingURL=http.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../tests/cases/http.ts"],"names":[],"mappings":"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"}
@@ -1,340 +0,0 @@
1
- import supertest from 'supertest'
2
- import { MasterContainerFactory, ProcessType } from '../../src'
3
- import { getExampleProjectDirectory, recreateDatabase } from '@contember/engine-api-tester'
4
- import * as nodeAssert from 'assert'
5
- import * as assert from 'uvu/assert'
6
- import { test } from 'uvu'
7
- import prom from 'prom-client'
8
- import { MigrationFilesManager, MigrationsResolver } from '@contember/schema-migrations'
9
- import { Logger } from '@contember/engine-common'
10
-
11
- const dbCredentials = (dbName: string) => {
12
- return {
13
- host: String(process.env.TEST_DB_HOST),
14
- port: Number(process.env.TEST_DB_PORT),
15
- user: String(process.env.TEST_DB_USER),
16
- password: String(process.env.TEST_DB_PASSWORD),
17
- database: dbName,
18
- }
19
- }
20
-
21
- const rootToken = String(process.env.CONTEMBER_ROOT_TOKEN)
22
- const loginToken = String(process.env.CONTEMBER_LOGIN_TOKEN)
23
-
24
- // Used to allow prettier formatting of GraphQL queries
25
- const gql = (strings: TemplateStringsArray) => {
26
- nodeAssert.strictEqual(strings.length, 1)
27
- return strings[0]
28
- }
29
-
30
- const projectConfig = {
31
- db: dbCredentials(String(process.env.TEST_DB_NAME)),
32
- name: 'test',
33
- slug: 'test',
34
- stages: [{ name: 'prod', slug: 'prod' }],
35
- }
36
- const createContainer = (debug: boolean) => {
37
- prom.register.clear()
38
- const tenantConfig = {
39
- db: dbCredentials(String(process.env.TEST_DB_NAME_TENANT)),
40
- mailer: {},
41
- credentials: {
42
- rootToken,
43
- loginToken,
44
- },
45
- secrets: {},
46
- }
47
- return new MasterContainerFactory().createBuilder({
48
- debugMode: debug,
49
- serverConfig: {
50
- logging: {},
51
- port: 0,
52
- monitoringPort: 0,
53
- http: {},
54
- },
55
- projectConfigResolver: () => projectConfig,
56
- tenantConfigResolver: () => tenantConfig,
57
- plugins: [],
58
- processType: ProcessType.singleNode,
59
- }).build()
60
- }
61
-
62
- const executeGraphql = (
63
- query: string,
64
- options: { authorizationToken?: string; path?: string; variables?: Record<string, any>; debug?: boolean } = {},
65
- ) => {
66
- const container = createContainer(options.debug || false)
67
- return supertest(container.koa.callback())
68
- .post(options.path || '/content/test/prod')
69
- .set('Authorization', 'Bearer ' + (options.authorizationToken || rootToken))
70
- .send({
71
- query,
72
- variables: options.variables || {},
73
- })
74
- }
75
-
76
- const signIn = async (email: string, password: string): Promise<string> => {
77
- const response2 = await executeGraphql(
78
- gql`
79
- mutation ($email: String!, $password: String!) {
80
- signIn(email: $email, password: $password) {
81
- ok
82
- result {
83
- token
84
- }
85
- }
86
- }
87
- `,
88
- {
89
- variables: { email, password },
90
- authorizationToken: loginToken,
91
- path: '/tenant',
92
- },
93
- )
94
-
95
- return response2.body.data.signIn.result.token
96
- }
97
-
98
- test.before(async () => {
99
- try {
100
- const connection = await recreateDatabase(String(process.env.TEST_DB_NAME))
101
- await connection.end()
102
- const tenantConnection = await recreateDatabase(String(process.env.TEST_DB_NAME_TENANT))
103
- const migrationsResolver = new MigrationsResolver(
104
- MigrationFilesManager.createForProject(getExampleProjectDirectory(), 'sample'),
105
- )
106
- const container = createContainer(false)
107
- await container.initializer.initialize()
108
-
109
- const { slug, name, ...config } = projectConfig
110
- const groupContainer = await container.projectGroupContainerResolver.getProjectGroupContainer(undefined)
111
- const tenantContainer = groupContainer.tenantContainer
112
- const result = await tenantContainer.projectManager.createProject(tenantContainer.databaseContext, { slug, name, config: config as any, secrets: {} }, undefined)
113
- if (!result) {
114
- throw new Error('Project already exists')
115
- }
116
- const projectContainer = await groupContainer.projectContainerResolver.getProjectContainer(slug)
117
- if (!projectContainer) {
118
- throw new Error('Should not happen')
119
- }
120
- await groupContainer.systemContainer.projectInitializer.initialize(
121
- projectContainer.systemDatabaseContextFactory,
122
- projectConfig,
123
- new Logger(() => null),
124
- await migrationsResolver.getMigrations(),
125
- )
126
- await tenantConnection.end()
127
- } catch (e) {
128
- // eslint-disable-next-line no-console
129
- console.error(e)
130
- process.exit(1)
131
- }
132
- })
133
-
134
- test('show homepage', async () => {
135
- await supertest(createContainer(false).koa.callback()) //
136
- .get('/')
137
- .expect(200)
138
- .expect('App is running')
139
- })
140
-
141
- test('Content API: create & read tag', async () => {
142
- await executeGraphql(
143
- gql`
144
- mutation {
145
- createTag(data: { label: "graphql" }) {
146
- ok
147
- }
148
- }
149
- `,
150
- )
151
- .expect(response => {
152
- assert.equal(response.body.data, {
153
- createTag: {
154
- ok: true,
155
- },
156
- })
157
- })
158
- .expect(200)
159
-
160
- await executeGraphql(
161
- gql`
162
- query {
163
- listTag(filter: { label: { eq: "graphql" } }) {
164
- label
165
- }
166
- }
167
- `,
168
- )
169
- .expect(response => {
170
- assert.equal(response.body.data, {
171
- listTag: [
172
- {
173
- label: 'graphql',
174
- },
175
- ],
176
- })
177
- })
178
- .expect(200)
179
- })
180
-
181
- test('Content API: X-Contember-Ref header', async () => {
182
- await executeGraphql(
183
- gql`
184
- mutation {
185
- createTag(data: { label: "typescript" }) {
186
- ok
187
- }
188
- }
189
- `,
190
- ).expect(200)
191
-
192
- const response = await executeGraphql(
193
- gql`
194
- query {
195
- listTag(filter: { label: { eq: "typescript" } }) {
196
- label
197
- }
198
- }
199
- `,
200
- )
201
- .set('X-Contember-Ref', 'None')
202
- .expect(response => {
203
- assert.equal(response.body.data, {
204
- listTag: [
205
- {
206
- label: 'typescript',
207
- },
208
- ],
209
- })
210
- })
211
- .expect(200)
212
- const eventKey = response.get('X-Contember-Ref')
213
- await executeGraphql(
214
- gql`
215
- query {
216
- listTag {
217
- label
218
- }
219
- }
220
- `,
221
- )
222
- .set('X-Contember-Ref', eventKey)
223
- .expect(304)
224
-
225
- // ignored for mutation
226
- await executeGraphql(
227
- gql`
228
- mutation {
229
- createTag(data: { label: "typescript" }) {
230
- ok
231
- }
232
- }
233
- `,
234
- )
235
- .set('X-Contember-Ref', eventKey)
236
- .expect(200)
237
- })
238
-
239
- test('Content API: invalid schema error', async () => {
240
- await executeGraphql(
241
- gql`
242
- mutation {
243
- createFoo(data: { label: "graphql" }) {
244
- ok
245
- }
246
- }
247
- `,
248
- )
249
- .expect(400)
250
- .expect(response => {
251
- assert.equal(
252
- response.body.errors[0].message,
253
- 'Cannot query field "createFoo" on type "Mutation". Did you mean "createPost" or "createTag"?',
254
- )
255
- })
256
- })
257
-
258
- test('Tenant API: sign up, add to a project and check project access', async () => {
259
- const signUpResponse = await executeGraphql(
260
- gql`
261
- mutation {
262
- signUp(email: "john@doe.com", password: "123456") {
263
- ok
264
- result {
265
- person {
266
- identity {
267
- id
268
- }
269
- }
270
- }
271
- }
272
- }
273
- `,
274
- { path: '/tenant' },
275
- ).expect(200)
276
-
277
- const identityId = signUpResponse.body.data.signUp.result.person.identity.id
278
-
279
- const authKey = await signIn('john@doe.com', '123456')
280
- await executeGraphql(
281
- gql`
282
- query {
283
- listTag {
284
- id
285
- }
286
- }
287
- `,
288
- { authorizationToken: authKey },
289
- )
290
- .expect(404)
291
- .expect({ errors: [{ message: 'Project test NOT found', code: 404 }] })
292
-
293
- await executeGraphql(
294
- gql`
295
- query {
296
- listTag {
297
- id
298
- }
299
- }
300
- `,
301
- { authorizationToken: authKey, debug: true },
302
- )
303
- .expect(403)
304
- .expect({
305
- errors: [{ message: 'You are not allowed to access project test', code: 403 }],
306
- identity: { roles: ['person'] },
307
- })
308
-
309
- await executeGraphql(
310
- gql`
311
- mutation ($identity: String!) {
312
- addProjectMember(identityId: $identity, projectSlug: "test", memberships: [{ role: "admin", variables: [] }]) {
313
- ok
314
- }
315
- }
316
- `,
317
- { path: '/tenant', variables: { identity: identityId } },
318
- )
319
- .expect(200)
320
- .expect(response => {
321
- assert.equal(response.body.data, { addProjectMember: { ok: true } })
322
- })
323
-
324
- await executeGraphql(
325
- gql`
326
- query {
327
- listAuthor {
328
- id
329
- }
330
- }
331
- `,
332
- { authorizationToken: authKey },
333
- )
334
- .expect(response => {
335
- assert.equal(response.body.data, { listAuthor: [] })
336
- })
337
- .expect(200)
338
- })
339
-
340
- test.run()