@platformatic/runtime 0.26.1 → 0.28.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.
@@ -29,14 +29,14 @@ test('handles startup errors', async (t) => {
29
29
  const { execa } = await import('execa')
30
30
  const config = join(import.meta.url, '..', '..', 'fixtures', 'configs', 'service-throws-on-start.json')
31
31
  const child = execa(process.execPath, [cliPath, 'start', '-c', config], { encoding: 'utf8' })
32
- let stderr = ''
32
+ let stdout = ''
33
33
  let found = false
34
34
 
35
- for await (const messages of on(child.stderr, 'data')) {
35
+ for await (const messages of on(child.stdout, 'data')) {
36
36
  for (const message of messages) {
37
- stderr += message
37
+ stdout += message
38
38
 
39
- if (/Error: boom/.test(stderr)) {
39
+ if (/Error: boom/.test(stdout)) {
40
40
  found = true
41
41
  break
42
42
  }
@@ -56,3 +56,12 @@ test('performs a topological sort on services depending on allowCycles', async (
56
56
  })
57
57
  })
58
58
  })
59
+
60
+ test('can resolve service id from client package.json if not provided', async () => {
61
+ const configFile = join(fixturesDir, 'configs', 'monorepo-client-without-id.json')
62
+ const config = await loadConfig({}, ['-c', configFile], platformaticRuntime)
63
+ const entry = config.configManager.current.serviceMap.get('serviceApp')
64
+
65
+ assert.strictEqual(entry.dependencies.length, 1)
66
+ assert.strictEqual(entry.dependencies[0].id, 'with-logger')
67
+ })
@@ -0,0 +1,354 @@
1
+ 'use strict'
2
+ const assert = require('node:assert')
3
+ const { spawn } = require('node:child_process')
4
+ const { once } = require('node:events')
5
+ const { join } = require('node:path')
6
+ const { test } = require('node:test')
7
+ const {
8
+ buildServer,
9
+ getConfigType,
10
+ getCurrentSchema,
11
+ loadConfig
12
+ } = require('../lib/unified-api')
13
+ const { version } = require('../package.json')
14
+ const fixturesDir = join(__dirname, '..', 'fixtures')
15
+
16
+ test('getConfigType()', async (t) => {
17
+ await t.test('throws if there is no $schema', async () => {
18
+ const configFile = join(fixturesDir, 'configs', 'no-schema.config.json')
19
+ let err
20
+
21
+ try {
22
+ await getConfigType(['-c', configFile])
23
+ } catch (error) {
24
+ err = error
25
+ }
26
+
27
+ assert(err)
28
+ assert.strictEqual(err.cause.message, 'configuration is missing a schema')
29
+ })
30
+
31
+ await t.test('throws if the schema type is unsupported', async () => {
32
+ const configFile = join(fixturesDir, 'configs', 'invalid-schema-type.config.json')
33
+ let err
34
+
35
+ try {
36
+ await getConfigType(['-c', configFile])
37
+ } catch (error) {
38
+ err = error
39
+ }
40
+
41
+ assert(err)
42
+ assert.strictEqual(err.cause.message, 'unknown configuration type: \'trickortreat\'')
43
+ })
44
+
45
+ await t.test('gets type from config via args', async () => {
46
+ const configFile = join(fixturesDir, 'monorepo', 'serviceApp', 'platformatic.service.json')
47
+ const type = await getConfigType(['-c', configFile])
48
+
49
+ assert.strictEqual(type, 'service')
50
+ })
51
+
52
+ await t.test('gets type from config in provided directory', async () => {
53
+ const configDir = join(fixturesDir, 'monorepo', 'serviceApp')
54
+ const type = await getConfigType(undefined, configDir)
55
+
56
+ assert.strictEqual(type, 'service')
57
+ })
58
+
59
+ await t.test('gets db type from config in cwd', async (t) => {
60
+ const cwd = process.cwd()
61
+
62
+ t.after(() => {
63
+ process.chdir(cwd)
64
+ })
65
+
66
+ const configDir = join(fixturesDir, 'dbApp')
67
+ process.chdir(configDir)
68
+ const type = await getConfigType()
69
+
70
+ assert.strictEqual(type, 'db')
71
+ })
72
+
73
+ await t.test('gets composer type from config in cwd', async (t) => {
74
+ const cwd = process.cwd()
75
+
76
+ t.after(() => {
77
+ process.chdir(cwd)
78
+ })
79
+
80
+ const configDir = join(fixturesDir, 'monorepo', 'composerApp')
81
+ process.chdir(configDir)
82
+ const type = await getConfigType()
83
+
84
+ assert.strictEqual(type, 'composer')
85
+ })
86
+ })
87
+
88
+ test('getCurrentSchema()', async (t) => {
89
+ await t.test('gets service schema', async () => {
90
+ const schema = await getCurrentSchema('service')
91
+
92
+ assert(schema.$id.endsWith(`/v${version}/service`))
93
+ })
94
+
95
+ await t.test('gets db schema', async () => {
96
+ const schema = await getCurrentSchema('db')
97
+
98
+ assert(schema.$id.endsWith(`/v${version}/db`))
99
+ })
100
+
101
+ await t.test('gets composer schema', async () => {
102
+ const schema = await getCurrentSchema('composer')
103
+
104
+ assert(schema.$id.endsWith(`/v${version}/composer`))
105
+ })
106
+
107
+ await t.test('gets runtime schema', async () => {
108
+ const schema = await getCurrentSchema('runtime')
109
+
110
+ assert(schema.$id.endsWith(`/v${version}/runtime`))
111
+ })
112
+
113
+ await t.test('throws for unknown types', async () => {
114
+ await assert.rejects(async () => {
115
+ await getCurrentSchema('not-a-real-type')
116
+ }, /unknown configuration type/)
117
+ })
118
+ })
119
+
120
+ test('loadConfig()', async (t) => {
121
+ await t.test('can explicitly provide config type', async () => {
122
+ const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
123
+ const config = await loadConfig({}, ['-c', configFile], undefined, 'service')
124
+
125
+ assert.strictEqual(config.args.config, configFile)
126
+ assert.strictEqual(config.configManager.fullPath, configFile)
127
+ assert.strictEqual(config.configManager.current.server.logger.name, 'service-with-logger')
128
+ assert.strictEqual(config.configManager.schemaOptions.useDefaults, true)
129
+ })
130
+
131
+ await t.test('throws if explicit type is wrong', async () => {
132
+ // Prevent the failed validation from logging and exiting the process.
133
+ t.mock.method(process, 'exit', () => {})
134
+ t.mock.method(console, 'table', () => {})
135
+
136
+ const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
137
+
138
+ await assert.rejects(async () => {
139
+ await loadConfig({}, ['-c', configFile], 'kaboom')
140
+ })
141
+ })
142
+
143
+ await t.test('can load a platformatic service project', async () => {
144
+ const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
145
+ const config = await loadConfig({}, ['-c', configFile])
146
+
147
+ assert.strictEqual(config.args.config, configFile)
148
+ assert.strictEqual(config.configManager.fullPath, configFile)
149
+ assert.strictEqual(config.configManager.current.server.logger.name, 'service-with-logger')
150
+ assert.strictEqual(config.configManager.schemaOptions.useDefaults, true)
151
+ })
152
+
153
+ await t.test('can load a platformatic db project', async () => {
154
+ const configFile = join(fixturesDir, 'dbApp', 'platformatic.db.json')
155
+ const config = await loadConfig({}, ['-c', configFile])
156
+
157
+ assert.strictEqual(config.args.config, configFile)
158
+ assert.strictEqual(config.configManager.fullPath, configFile)
159
+ assert.strictEqual(config.configManager.current.db.graphql, true)
160
+ })
161
+
162
+ await t.test('can load a platformatic composer project', async () => {
163
+ const configFile = join(fixturesDir, 'composerApp', 'platformatic.composer.json')
164
+ const config = await loadConfig({}, ['-c', configFile])
165
+
166
+ assert.strictEqual(config.args.config, configFile)
167
+ assert.strictEqual(config.configManager.fullPath, configFile)
168
+ assert.strictEqual(config.configManager.current.composer.refreshTimeout, 1000)
169
+ })
170
+
171
+ await t.test('can load a platformatic runtime project', async () => {
172
+ const configFile = join(fixturesDir, 'configs', 'monorepo.json')
173
+ const config = await loadConfig({}, ['-c', configFile])
174
+
175
+ assert.strictEqual(config.args.config, configFile)
176
+ assert.strictEqual(config.configManager.fullPath, configFile)
177
+ assert.strictEqual(config.configManager.current.entrypoint, 'serviceApp')
178
+ })
179
+ })
180
+
181
+ test('buildServer()', async (t) => {
182
+ await t.test('can build a service server', async (t) => {
183
+ const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
184
+ const config = await loadConfig({}, ['-c', configFile])
185
+ const server = await buildServer(config.configManager.current)
186
+
187
+ t.after(async () => {
188
+ await server.close()
189
+ })
190
+
191
+ const address = await server.start()
192
+ // The address should be a valid URL.
193
+ new URL(address) // eslint-disable-line no-new
194
+ })
195
+
196
+ await t.test('can build a db server', async (t) => {
197
+ const configFile = join(fixturesDir, 'dbApp', 'platformatic.db.json')
198
+ const config = await loadConfig({}, ['-c', configFile])
199
+ const server = await buildServer(config.configManager.current)
200
+
201
+ t.after(async () => {
202
+ await server.close()
203
+ })
204
+
205
+ const address = await server.start()
206
+ // The address should be a valid URL.
207
+ new URL(address) // eslint-disable-line no-new
208
+ })
209
+
210
+ await t.test('can build a composer server', async (t) => {
211
+ const configFile = join(fixturesDir, 'composerApp', 'platformatic.composer.json')
212
+ const config = await loadConfig({}, ['-c', configFile])
213
+ const server = await buildServer(config.configManager.current)
214
+
215
+ t.after(async () => {
216
+ await server.close()
217
+ })
218
+
219
+ const address = await server.start()
220
+ // The address should be a valid URL.
221
+ new URL(address) // eslint-disable-line no-new
222
+ })
223
+
224
+ await t.test('can build a runtime application', async (t) => {
225
+ const configFile = join(fixturesDir, 'configs', 'monorepo.json')
226
+ const config = await loadConfig({}, ['-c', configFile])
227
+ const server = await buildServer(config.configManager.current)
228
+
229
+ t.after(async () => {
230
+ await server.close()
231
+ })
232
+
233
+ const address = await server.start()
234
+ // The address should be a valid URL.
235
+ new URL(address) // eslint-disable-line no-new
236
+ })
237
+
238
+ await t.test('input can be a filename', async (t) => {
239
+ const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
240
+ const server = await buildServer(configFile)
241
+
242
+ t.after(async () => {
243
+ await server.close()
244
+ })
245
+
246
+ const address = await server.start()
247
+ // The address should be a valid URL.
248
+ new URL(address) // eslint-disable-line no-new
249
+ })
250
+ })
251
+
252
+ test('start()', async (t) => {
253
+ await t.test('can start a service server', async (t) => {
254
+ const scriptFile = join(fixturesDir, 'starter.js')
255
+ const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
256
+ const child = spawn(process.execPath, [scriptFile, configFile])
257
+ child.stdout.pipe(process.stdout)
258
+ child.stderr.pipe(process.stderr)
259
+ const [exitCode] = await once(child, 'exit')
260
+
261
+ assert.strictEqual(exitCode, 42)
262
+ })
263
+
264
+ await t.test('can start a db server', async (t) => {
265
+ const scriptFile = join(fixturesDir, 'starter.js')
266
+ const configFile = join(fixturesDir, 'dbApp', 'platformatic.db.json')
267
+ const child = spawn(process.execPath, [scriptFile, configFile])
268
+ const [exitCode] = await once(child, 'exit')
269
+
270
+ assert.strictEqual(exitCode, 42)
271
+ })
272
+
273
+ await t.test('can start a composer server', async () => {
274
+ const scriptFile = join(fixturesDir, 'starter.js')
275
+ const configFile = join(fixturesDir, 'composerApp', 'platformatic.composer.json')
276
+ const child = spawn(process.execPath, [scriptFile, configFile])
277
+ const [exitCode] = await once(child, 'exit')
278
+
279
+ assert.strictEqual(exitCode, 42)
280
+ })
281
+
282
+ await t.test('can start a runtime application', async () => {
283
+ const scriptFile = join(fixturesDir, 'starter.js')
284
+ const configFile = join(fixturesDir, 'configs', 'monorepo.json')
285
+ const child = spawn(process.execPath, [scriptFile, configFile])
286
+ const [exitCode] = await once(child, 'exit')
287
+
288
+ assert.strictEqual(exitCode, 42)
289
+ })
290
+ })
291
+
292
+ test('startCommand()', async (t) => {
293
+ await t.test('can start a server', async (t) => {
294
+ const scriptFile = join(fixturesDir, 'start-command.js')
295
+ const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
296
+ const child = spawn(process.execPath, [scriptFile, configFile])
297
+ child.stderr.pipe(process.stderr)
298
+ const [exitCode] = await once(child, 'exit')
299
+
300
+ assert.strictEqual(exitCode, 42)
301
+ })
302
+
303
+ await t.test('exits on error', async (t) => {
304
+ const scriptFile = join(fixturesDir, 'start-command.js')
305
+ const configFile = join(fixturesDir, 'serviceApp', 'platformatic.not-found.json')
306
+ const child = spawn(process.execPath, [scriptFile, configFile])
307
+ const [exitCode] = await once(child, 'exit')
308
+
309
+ assert.strictEqual(exitCode, 1)
310
+ })
311
+
312
+ await t.test('can start a runtime application', async (t) => {
313
+ const scriptFile = join(fixturesDir, 'start-command.js')
314
+ const configFile = join(fixturesDir, 'configs', 'monorepo.json')
315
+ const child = spawn(process.execPath, [scriptFile, configFile])
316
+ child.stderr.pipe(process.stderr)
317
+ const [exitCode] = await once(child, 'exit')
318
+
319
+ assert.strictEqual(exitCode, 42)
320
+ })
321
+ })
322
+
323
+ test('startCommandInRuntime()', async (t) => {
324
+ await t.test('can start a non-runtime application', async (t) => {
325
+ const scriptFile = join(fixturesDir, 'start-command-in-runtime.js')
326
+ const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
327
+ const child = spawn(process.execPath, [scriptFile, configFile])
328
+ child.stdout.pipe(process.stdout)
329
+ child.stderr.pipe(process.stderr)
330
+ const [exitCode] = await once(child, 'exit')
331
+
332
+ assert.strictEqual(exitCode, 42)
333
+ })
334
+
335
+ await t.test('can start a runtime application', async (t) => {
336
+ const scriptFile = join(fixturesDir, 'start-command-in-runtime.js')
337
+ const configFile = join(fixturesDir, 'configs', 'monorepo.json')
338
+ const child = spawn(process.execPath, [scriptFile, configFile])
339
+ child.stdout.pipe(process.stdout)
340
+ child.stderr.pipe(process.stderr)
341
+ const [exitCode] = await once(child, 'exit')
342
+
343
+ assert.strictEqual(exitCode, 42)
344
+ })
345
+
346
+ await t.test('exits on error', async (t) => {
347
+ const scriptFile = join(fixturesDir, 'start-command-in-runtime.js')
348
+ const configFile = join(fixturesDir, 'serviceApp', 'platformatic.not-found.json')
349
+ const child = spawn(process.execPath, [scriptFile, configFile])
350
+ const [exitCode] = await once(child, 'exit')
351
+
352
+ assert.strictEqual(exitCode, 1)
353
+ })
354
+ })
@@ -1,21 +0,0 @@
1
- 'use strict'
2
-
3
- const assert = require('node:assert')
4
- const { once } = require('node:events')
5
- const { join } = require('node:path')
6
- const { test } = require('node:test')
7
- const { Worker } = require('node:worker_threads')
8
-
9
- test('throws if unknown messages are received', async (t) => {
10
- const workerFile = join(__dirname, '..', 'lib', 'worker.js')
11
- const worker = new Worker(workerFile, {
12
- execArgv: [],
13
- workerData: { config: { services: [] } }
14
- })
15
-
16
- const [msg] = await once(worker, 'message')
17
- assert.strictEqual(msg, 'plt:init')
18
- worker.postMessage({ msg: 'unknown-message-type' })
19
- const [err] = await once(worker, 'error')
20
- assert.strictEqual(err.message, 'unknown message type: \'unknown-message-type\'')
21
- })