@platformatic/runtime 0.35.5 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,61 @@
1
+ 'use strict'
2
+
3
+ const { schema } = require('@platformatic/service')
4
+
5
+ /** @type {import('fastify').FastifyPluginAsync<{}>} */
6
+ async function foo (app) {
7
+ const text = app.platformatic.config.foo.text
8
+ app.get('/foo', async (request, reply) => {
9
+ return text
10
+ })
11
+ }
12
+
13
+ foo.configType = 'foo'
14
+ foo.schema = {
15
+ $id: 'https://example.com/schemas/foo.json',
16
+ title: 'Platformatic Service',
17
+ type: 'object',
18
+ properties: {
19
+ server: schema.server,
20
+ plugins: schema.plugins,
21
+ metrics: schema.metrics,
22
+ watch: {
23
+ anyOf: [schema.watch, {
24
+ type: 'boolean'
25
+ }, {
26
+ type: 'string'
27
+ }]
28
+ },
29
+ $schema: {
30
+ type: 'string'
31
+ },
32
+ module: {
33
+ type: 'string'
34
+ },
35
+ foo: {
36
+ type: 'object',
37
+ properties: {
38
+ text: {
39
+ type: 'string'
40
+ }
41
+ },
42
+ required: ['text']
43
+ }
44
+ },
45
+ additionalProperties: false,
46
+ required: ['server']
47
+ }
48
+
49
+ foo.configManagerConfig = {
50
+ schema: foo.schema,
51
+ envWhitelist: ['PORT', 'HOSTNAME'],
52
+ allowToWatch: ['.env'],
53
+ schemaOptions: {
54
+ useDefaults: true,
55
+ coerceTypes: true,
56
+ allErrors: true,
57
+ strict: false
58
+ }
59
+ }
60
+
61
+ module.exports = foo
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "foo",
3
+ "main": "foo.js"
4
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "$schema": "https://example.com/schemas/foo.json",
3
+ "module": "foo",
4
+ "server": {
5
+ "port": 0,
6
+ "hostname": "127.0.0.1"
7
+ },
8
+ "foo": {
9
+ "text": "Hello World"
10
+ }
11
+ }
package/lib/api.js CHANGED
@@ -193,7 +193,7 @@ class RuntimeApi {
193
193
  }
194
194
 
195
195
  if (typeof service.server.swagger !== 'function') {
196
- throw new Error(`Service with id '${id}' does not expose an OpenAPI schema`)
196
+ return null
197
197
  }
198
198
 
199
199
  try {
package/lib/app.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const { once } = require('node:events')
4
- const { dirname, basename } = require('node:path')
4
+ const { dirname } = require('node:path')
5
5
  const { FileWatcher } = require('@platformatic/utils')
6
6
  const debounce = require('debounce')
7
7
  const {
@@ -18,6 +18,7 @@ class PlatformaticApp {
18
18
  #fileWatcher
19
19
  #logger
20
20
  #telemetryConfig
21
+ #debouncedRestart
21
22
 
22
23
  constructor (appConfig, loaderPort, logger, telemetryConfig) {
23
24
  this.appConfig = appConfig
@@ -33,6 +34,12 @@ class PlatformaticApp {
33
34
  name: this.appConfig.id
34
35
  })
35
36
  this.#telemetryConfig = telemetryConfig
37
+
38
+ /* c8 ignore next 4 */
39
+ this.#debouncedRestart = debounce(() => {
40
+ this.server.log.info('files changed')
41
+ this.restart()
42
+ }, 100) // debounce restart for 100ms
36
43
  }
37
44
 
38
45
  getStatus () {
@@ -56,8 +63,9 @@ class PlatformaticApp {
56
63
  await once(this.#loaderPort, 'message')
57
64
  }
58
65
 
59
- this.#setuplogger(this.config.configManager)
60
66
  try {
67
+ await this.config.configManager.parseAndValidate()
68
+ this.#setuplogger(this.config.configManager)
61
69
  await this.server.restart()
62
70
  } catch (err) {
63
71
  this.#logAndExit(err)
@@ -90,6 +98,7 @@ class PlatformaticApp {
90
98
  // If this is a restart, have the fastify server restart itself. If this
91
99
  // is not a restart, then create a new server.
92
100
  this.server = await buildServer({
101
+ app: this.config.app,
93
102
  ...config,
94
103
  configManager
95
104
  })
@@ -157,8 +166,7 @@ class PlatformaticApp {
157
166
 
158
167
  let _config
159
168
  try {
160
- _config = await loadConfig({}, ['-c', appConfig.config], null, {
161
- watch: true,
169
+ _config = await loadConfig({}, ['-c', appConfig.config], {
162
170
  onMissingEnv (key) {
163
171
  return appConfig.localServiceEnvVars.get(key)
164
172
  }
@@ -172,30 +180,25 @@ class PlatformaticApp {
172
180
 
173
181
  function applyOverrides () {
174
182
  if (appConfig._configOverrides instanceof Map) {
175
- try {
176
- appConfig._configOverrides.forEach((value, key) => {
177
- if (typeof key !== 'string') {
178
- throw new Error('config path must be a string.')
179
- }
180
-
181
- const parts = key.split('.')
182
- let next = configManager.current
183
- let obj
184
- let i
185
-
186
- for (i = 0; next !== undefined && i < parts.length; ++i) {
187
- obj = next
188
- next = obj[parts[i]]
189
- }
190
-
191
- if (i === parts.length) {
192
- obj[parts.at(-1)] = value
193
- }
194
- })
195
- } catch (err) {
196
- configManager.stopWatching()
197
- throw err
198
- }
183
+ appConfig._configOverrides.forEach((value, key) => {
184
+ if (typeof key !== 'string') {
185
+ throw new Error('config path must be a string.')
186
+ }
187
+
188
+ const parts = key.split('.')
189
+ let next = configManager.current
190
+ let obj
191
+ let i
192
+
193
+ for (i = 0; next !== undefined && i < parts.length; ++i) {
194
+ obj = next
195
+ next = obj[parts[i]]
196
+ }
197
+
198
+ if (i === parts.length) {
199
+ obj[parts.at(-1)] = value
200
+ }
201
+ })
199
202
  }
200
203
  }
201
204
 
@@ -203,16 +206,6 @@ class PlatformaticApp {
203
206
 
204
207
  this.#hotReload = this.appConfig.hotReload
205
208
 
206
- configManager.on('update', async (newConfig) => {
207
- if (this.server) { // when we setup telemetry on config, we don't have a server yet
208
- this.server.platformatic.config = newConfig
209
- applyOverrides()
210
- this.server.log.debug('config changed')
211
- this.server.log.trace({ newConfig }, 'new config')
212
- await this.restart()
213
- }
214
- })
215
-
216
209
  configManager.on('error', (err) => {
217
210
  /* c8 ignore next */
218
211
  this.server.log.error({ err }, 'error reloading the configuration')
@@ -233,34 +226,22 @@ class PlatformaticApp {
233
226
  }
234
227
  const server = this.server
235
228
  const { configManager } = server.platformatic
236
- // TODO FileWatcher and ConfigManager both watch the configuration file
237
- // we should remove the watching from the ConfigManager
238
229
  const fileWatcher = new FileWatcher({
239
230
  path: dirname(configManager.fullPath),
240
231
  /* c8 ignore next 2 */
241
232
  allowToWatch: this.#originalWatch?.allow,
242
- watchIgnore: [...(this.#originalWatch?.ignore || []), basename(configManager.fullPath)]
233
+ watchIgnore: this.#originalWatch?.ignore || []
243
234
  })
244
235
 
245
- /* c8 ignore next 4 */
246
- const restart = debounce(() => {
247
- this.server.log.info('files changed')
248
- this.restart()
249
- }, 100) // debounce restart for 100ms
250
- fileWatcher.on('update', restart)
236
+ fileWatcher.on('update', this.#debouncedRestart)
251
237
 
252
238
  fileWatcher.startWatching()
253
239
  server.log.debug('start watching files')
254
240
  server.platformatic.fileWatcher = fileWatcher
255
- server.platformatic.configManager.startWatching()
256
241
  this.#fileWatcher = fileWatcher
257
242
  }
258
243
 
259
244
  async #stopFileWatching () {
260
- // The configManager automatically watches for the config file changes
261
- // therefore we need to stop it all the times.
262
- await this.config.configManager.stopWatching()
263
-
264
245
  const watcher = this.#fileWatcher
265
246
  if (watcher) {
266
247
  this.server.log.debug('stop watching files')
@@ -271,7 +252,6 @@ class PlatformaticApp {
271
252
  }
272
253
 
273
254
  #logAndExit (err) {
274
- this.config?.configManager?.stopWatching()
275
255
  this.#logger.error({ err })
276
256
  process.exit(1)
277
257
  }
package/lib/compile.js CHANGED
@@ -9,7 +9,7 @@ const pretty = require('pino-pretty')
9
9
  const { isatty } = require('node:tty')
10
10
 
11
11
  async function compile (argv, logger) {
12
- const { configManager, configType } = await loadConfig({}, argv, undefined, {
12
+ const { configManager, configType } = await loadConfig({}, argv, {
13
13
  watch: false
14
14
  })
15
15
 
@@ -33,7 +33,7 @@ async function compile (argv, logger) {
33
33
  for (const service of configManager.current.services) {
34
34
  const childLogger = logger.child({ name: service.id })
35
35
 
36
- const serviceConfig = await loadConfig({}, argv, undefined, {
36
+ const serviceConfig = await loadConfig({}, argv, {
37
37
  watch: false
38
38
  })
39
39
 
package/lib/start.js CHANGED
@@ -5,7 +5,7 @@ const { join } = require('node:path')
5
5
  const { pathToFileURL } = require('node:url')
6
6
  const { Worker } = require('node:worker_threads')
7
7
  const closeWithGrace = require('close-with-grace')
8
- const { loadConfig } = require('@platformatic/service')
8
+ const { loadConfig } = require('@platformatic/config')
9
9
  const { parseInspectorOptions, platformaticRuntime } = require('./config')
10
10
  const RuntimeApiClient = require('./api-client.js')
11
11
  const kLoaderFile = pathToFileURL(join(__dirname, 'loader.mjs')).href
@@ -1,112 +1,41 @@
1
1
  'use strict'
2
- const { resolve } = require('node:path')
3
- const parseArgs = require('minimist')
4
- const ConfigManager = require('@platformatic/config')
2
+ const { Store, loadConfig, printConfigValidationErrors } = require('@platformatic/config')
5
3
  const {
6
4
  platformaticService,
7
5
  buildServer,
8
- loadConfig,
9
- start,
10
- schema: serviceSchema
6
+ start
11
7
  } = require('@platformatic/service')
12
8
  const {
13
- schema: dbSchema,
14
9
  platformaticDB
15
10
  } = require('@platformatic/db')
16
11
  const {
17
- schema: composerSchema,
18
12
  platformaticComposer
19
13
  } = require('@platformatic/composer')
20
14
  const { buildServer: runtimeBuildServer } = require('./build-server')
21
15
  const { platformaticRuntime, wrapConfigInRuntimeConfig } = require('./config')
22
- const { schema: runtimeSchema } = require('./schema')
23
16
  const {
24
17
  start: runtimeStart,
25
18
  startWithConfig: runtimeStartWithConfig
26
19
  } = require('./start')
27
20
 
28
- const kSupportedAppTypes = new Set(['service', 'db', 'composer', 'runtime'])
21
+ const store = new Store()
22
+ store.add(platformaticService)
23
+ store.add(platformaticDB)
24
+ store.add(platformaticComposer)
25
+ store.add(platformaticRuntime)
29
26
 
30
- async function tryGetConfigTypeFromSchema (config) {
31
- /* c8 ignore next 6 - c8 is not seeing this as covered for some reason. */
32
- if (typeof config === 'string') {
33
- // Handle config file paths.
34
- const loadedConfig = await loadConfig({}, ['-c', config], platformaticService)
35
-
36
- config = loadedConfig.configManager.current
37
- }
38
-
39
- const schema = config?.$schema
40
-
41
- if (typeof schema !== 'string') {
42
- throw new Error('configuration is missing a schema')
43
- }
44
-
45
- const configType = schema.split('/').pop()
46
-
47
- if (!kSupportedAppTypes.has(configType)) {
48
- throw new Error(`unknown configuration type: '${configType}'`)
49
- }
50
-
51
- return configType
52
- }
53
-
54
- async function getConfigType (args = [], directory) {
55
- try {
56
- // The config type was not specified, so we need to figure it out.
57
- // Try to get the config file from the provided arguments.
58
- let { config } = parseArgs(args, { alias: { c: 'config' } })
59
-
60
- if (!config) {
61
- // Couldn't get the config file from the arguments, so look in the
62
- // provided directory (or current directory) for any recognized
63
- // config files.
64
- const searchDir = directory ?? process.cwd()
65
- const configFile = await ConfigManager.findConfigFile(searchDir)
66
-
67
- config = resolve(searchDir, configFile)
68
- }
69
-
70
- // At this point, we have the config file. However, several different
71
- // file formats are supported, so use the config manager to parse the
72
- // file (without worrying about the validity of the file). We can then
73
- // use the $schema field to determine the config type.
74
- const configManager = new ConfigManager({ source: config })
75
- const configString = await configManager.load()
76
- const parsedConfig = configManager._parser(configString)
77
-
78
- return await tryGetConfigTypeFromSchema(parsedConfig)
79
- } catch (err) {
80
- const configFiles = ConfigManager.listConfigFiles()
81
- const msg = `
82
- Missing config file!
83
- Be sure to have a config file with one of the following names:
84
- ${configFiles.map((s) => ' * ' + s).join('\n')}
85
- Alternatively run "npm create platformatic@latest" to generate a basic plt service config.
86
- `
87
-
88
- throw new Error(msg, { cause: err })
89
- }
90
- }
91
-
92
- async function getCurrentSchema (configType) {
93
- if (configType === 'service') {
94
- return serviceSchema.schema
95
- } else if (configType === 'db') {
96
- return dbSchema
97
- } else if (configType === 'composer') {
98
- return composerSchema
99
- } else if (configType === 'runtime') {
100
- return runtimeSchema
27
+ /* c8 ignore next 10 - for some reason c8 is not seeing this as covered. */
28
+ async function _buildServer (options) {
29
+ if (typeof options === 'string') {
30
+ const config = await _loadConfig({}, ['-c', options])
31
+ options = config.configManager.current
32
+ options.configManager = config.configManager
33
+ options.app = config.app
101
34
  }
102
35
 
103
- throw new Error(`unknown configuration type: '${configType}'`)
104
- }
36
+ const app = options.app
105
37
 
106
- /* c8 ignore next 10 - for some reason c8 is not seeing this as covered. */
107
- async function _buildServer (options) {
108
- const configType = await tryGetConfigTypeFromSchema(options)
109
- const app = getApp(configType)
38
+ delete options.app
110
39
 
111
40
  if (app === platformaticRuntime) {
112
41
  return runtimeBuildServer(options)
@@ -115,51 +44,26 @@ async function _buildServer (options) {
115
44
  return buildServer(options, app)
116
45
  }
117
46
 
118
- function getApp (configType) {
119
- if (configType === 'service') {
120
- return platformaticService
121
- } else if (configType === 'db') {
122
- return platformaticDB
123
- } else if (configType === 'composer') {
124
- return platformaticComposer
125
- } else if (configType === 'runtime') {
126
- return platformaticRuntime
127
- }
128
-
129
- throw new Error('unknown kind: ' + configType)
130
- }
131
-
132
- async function _loadConfig (minimistConfig, args, configType, overrides) {
133
- // If the config type was specified, then use that. Otherwise, compute it.
134
- if (typeof configType !== 'string') {
135
- configType = await getConfigType(args)
136
- }
137
-
138
- const app = getApp(configType)
139
- const res = await loadConfig(minimistConfig, args, app, overrides)
140
- res.configType = configType
141
- res.app = app
142
-
143
- return res
47
+ function _loadConfig (minimistConfig, args, overrides) {
48
+ return loadConfig(minimistConfig, args, store, overrides)
144
49
  }
145
50
 
146
51
  async function _start (args) {
147
- const configType = await getConfigType(args)
52
+ const config = await _loadConfig({}, args)
148
53
 
149
- if (configType === 'runtime') {
54
+ if (config.configType === 'runtime') {
150
55
  return runtimeStart(args)
151
56
  }
152
57
 
153
- return start(getApp(configType), args)
58
+ return start(config.app, args)
154
59
  }
155
60
 
156
61
  async function startCommand (args) {
157
62
  try {
158
- const configType = await getConfigType(args)
159
- const config = await _loadConfig({}, args, configType)
63
+ const config = await _loadConfig({}, args)
160
64
  let runtime
161
65
 
162
- if (configType === 'runtime') {
66
+ if (config.configType === 'runtime') {
163
67
  config.configManager.args = config.args
164
68
  runtime = await runtimeStartWithConfig(config.configManager)
165
69
  } else {
@@ -175,6 +79,19 @@ async function startCommand (args) {
175
79
  }
176
80
 
177
81
  function logErrorAndExit (err) {
82
+ if (err.filenames) {
83
+ console.error(`Missing config file!
84
+ Be sure to have a config file with one of the following names:
85
+
86
+ ${err.filenames.map((s) => ' * ' + s).join('\n')}
87
+
88
+ In alternative run "npm create platformatic@latest" to generate a basic plt service config.`)
89
+ process.exit(1)
90
+ } else if (err.validationErrors) {
91
+ printConfigValidationErrors(err)
92
+ process.exit(1)
93
+ }
94
+
178
95
  delete err?.stack
179
96
  console.error(err?.message)
180
97
 
@@ -187,10 +104,7 @@ function logErrorAndExit (err) {
187
104
 
188
105
  module.exports = {
189
106
  buildServer: _buildServer,
190
- getConfigType,
191
- getCurrentSchema,
192
107
  loadConfig: _loadConfig,
193
108
  start: _start,
194
- startCommand,
195
- getApp
109
+ startCommand
196
110
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/runtime",
3
- "version": "0.35.5",
3
+ "version": "0.37.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -24,8 +24,8 @@
24
24
  "standard": "^17.1.0",
25
25
  "tsd": "^0.28.1",
26
26
  "typescript": "^5.1.6",
27
- "@platformatic/sql-graphql": "0.35.5",
28
- "@platformatic/sql-mapper": "0.35.5"
27
+ "@platformatic/sql-graphql": "0.37.0",
28
+ "@platformatic/sql-mapper": "0.37.0"
29
29
  },
30
30
  "dependencies": {
31
31
  "@hapi/topo": "^6.0.2",
@@ -42,12 +42,12 @@
42
42
  "pino": "^8.14.1",
43
43
  "pino-pretty": "^10.0.0",
44
44
  "undici": "^5.22.1",
45
- "@platformatic/composer": "0.35.5",
46
- "@platformatic/config": "0.35.5",
47
- "@platformatic/db": "0.35.5",
48
- "@platformatic/service": "0.35.5",
49
- "@platformatic/telemetry": "0.35.5",
50
- "@platformatic/utils": "0.35.5"
45
+ "@platformatic/composer": "0.37.0",
46
+ "@platformatic/config": "0.37.0",
47
+ "@platformatic/db": "0.37.0",
48
+ "@platformatic/service": "0.37.0",
49
+ "@platformatic/telemetry": "0.37.0",
50
+ "@platformatic/utils": "0.37.0"
51
51
  },
52
52
  "standard": {
53
53
  "ignore": [
package/test/api.test.js CHANGED
@@ -4,7 +4,7 @@ const assert = require('node:assert')
4
4
  const { join } = require('node:path')
5
5
  const { test } = require('node:test')
6
6
 
7
- const { loadConfig } = require('@platformatic/service')
7
+ const { loadConfig } = require('@platformatic/config')
8
8
  const { buildServer, platformaticRuntime } = require('..')
9
9
  const fixturesDir = join(__dirname, '..', 'fixtures')
10
10
 
@@ -349,9 +349,6 @@ test('should fail to get a service openapi schema if service does not expose it'
349
349
  await app.close()
350
350
  })
351
351
 
352
- try {
353
- await app.getServiceOpenapiSchema('without-openapi')
354
- } catch (err) {
355
- assert.strictEqual(err.message, 'Service with id \'without-openapi\' does not expose an OpenAPI schema')
356
- }
352
+ const openapiSchema = await app.getServiceOpenapiSchema('without-openapi')
353
+ assert.strictEqual(openapiSchema, null)
357
354
  })
@@ -48,6 +48,10 @@ test('handles startup errors', async (t) => {
48
48
  }
49
49
 
50
50
  assert(found)
51
+
52
+ // if we do not await this, the test will crash because the event loop has nothing to do
53
+ // but there is still a promise waiting
54
+ await child.catch(() => {})
51
55
  })
52
56
 
53
57
  test('exits on error', async () => {
@@ -115,3 +119,13 @@ test('starts the inspector', async (t) => {
115
119
  assert(found)
116
120
  child.kill('SIGINT')
117
121
  })
122
+
123
+ test('stackable', async () => {
124
+ const config = join(import.meta.url, '..', '..', 'fixtures', 'stackables', 'platformatic.json')
125
+ const { child, url } = await start('start', '-c', config)
126
+ const res = await request(url + '/foo')
127
+
128
+ assert.strictEqual(res.statusCode, 200)
129
+ assert.deepStrictEqual(await res.body.text(), 'Hello World')
130
+ child.kill('SIGINT')
131
+ })
@@ -3,7 +3,8 @@
3
3
  const assert = require('node:assert')
4
4
  const { join } = require('node:path')
5
5
  const { test } = require('node:test')
6
- const { loadConfig, platformaticService } = require('@platformatic/service')
6
+ const { loadConfig } = require('@platformatic/config')
7
+ const { platformaticService } = require('@platformatic/service')
7
8
  const { parseInspectorOptions, platformaticRuntime } = require('../lib/config')
8
9
  const fixturesDir = join(__dirname, '..', 'fixtures')
9
10
 
@@ -6,7 +6,8 @@ const { join } = require('node:path')
6
6
  const { test } = require('node:test')
7
7
  const { MessageChannel } = require('node:worker_threads')
8
8
  const { request } = require('undici')
9
- const { loadConfig } = require('@platformatic/service')
9
+ const { loadConfig } = require('@platformatic/config')
10
+ const { platformaticDB } = require('@platformatic/db')
10
11
  const { buildServer, platformaticRuntime } = require('..')
11
12
  const { wrapConfigInRuntimeConfig } = require('../lib/config')
12
13
  const { startWithConfig } = require('../lib/start')
@@ -160,7 +161,7 @@ test('handles uncaught exceptions with db app', async (t) => {
160
161
 
161
162
  test('logs errors during db migrations', async (t) => {
162
163
  const configFile = join(fixturesDir, 'dbAppWithMigrationError', 'platformatic.db.json')
163
- const config = await loadConfig({}, ['-c', configFile], 'db')
164
+ const config = await loadConfig({}, ['-c', configFile], platformaticDB)
164
165
  const runtimeConfig = await wrapConfigInRuntimeConfig(config)
165
166
  const { port1, port2 } = new MessageChannel()
166
167
  runtimeConfig.current.loggingPort = port2
@@ -4,7 +4,7 @@ const assert = require('node:assert')
4
4
  const { request } = require('undici')
5
5
  const { test } = require('node:test')
6
6
  const { join } = require('node:path')
7
- const { loadConfig } = require('@platformatic/service')
7
+ const { loadConfig } = require('@platformatic/config')
8
8
  const { platformaticRuntime } = require('..')
9
9
  const { startWithConfig } = require('../lib/start')
10
10
  const fixturesDir = join(__dirname, '..', 'fixtures')
@@ -6,117 +6,10 @@ const { join } = require('node:path')
6
6
  const { test } = require('node:test')
7
7
  const {
8
8
  buildServer,
9
- getConfigType,
10
- getCurrentSchema,
11
9
  loadConfig
12
10
  } = require('../lib/unified-api')
13
- const { version } = require('../package.json')
14
11
  const fixturesDir = join(__dirname, '..', 'fixtures')
15
12
 
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
13
  test('loadConfig()', async (t) => {
121
14
  await t.test('can explicitly provide config type', async () => {
122
15
  const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
@@ -128,18 +21,6 @@ test('loadConfig()', async (t) => {
128
21
  assert.strictEqual(config.configManager.schemaOptions.useDefaults, true)
129
22
  })
130
23
 
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
24
  await t.test('can load a platformatic service project', async () => {
144
25
  const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
145
26
  const config = await loadConfig({}, ['-c', configFile])
@@ -182,7 +63,10 @@ test('buildServer()', async (t) => {
182
63
  await t.test('can build a service server', async (t) => {
183
64
  const configFile = join(fixturesDir, 'monorepo', 'serviceAppWithLogger', 'platformatic.service.json')
184
65
  const config = await loadConfig({}, ['-c', configFile])
185
- const server = await buildServer(config.configManager.current)
66
+ const server = await buildServer({
67
+ app: config.app,
68
+ ...config.configManager.current
69
+ })
186
70
 
187
71
  t.after(async () => {
188
72
  await server.close()
@@ -196,7 +80,10 @@ test('buildServer()', async (t) => {
196
80
  await t.test('can build a db server', async (t) => {
197
81
  const configFile = join(fixturesDir, 'dbApp', 'platformatic.db.json')
198
82
  const config = await loadConfig({}, ['-c', configFile])
199
- const server = await buildServer(config.configManager.current)
83
+ const server = await buildServer({
84
+ app: config.app,
85
+ ...config.configManager.current
86
+ })
200
87
 
201
88
  t.after(async () => {
202
89
  await server.close()
@@ -210,7 +97,10 @@ test('buildServer()', async (t) => {
210
97
  await t.test('can build a composer server', async (t) => {
211
98
  const configFile = join(fixturesDir, 'composerApp', 'platformatic.composer.json')
212
99
  const config = await loadConfig({}, ['-c', configFile])
213
- const server = await buildServer(config.configManager.current)
100
+ const server = await buildServer({
101
+ app: config.app,
102
+ ...config.configManager.current
103
+ })
214
104
 
215
105
  t.after(async () => {
216
106
  await server.close()
@@ -224,7 +114,10 @@ test('buildServer()', async (t) => {
224
114
  await t.test('can build a runtime application', async (t) => {
225
115
  const configFile = join(fixturesDir, 'configs', 'monorepo.json')
226
116
  const config = await loadConfig({}, ['-c', configFile])
227
- const server = await buildServer(config.configManager.current)
117
+ const server = await buildServer({
118
+ app: config.app,
119
+ ...config.configManager.current
120
+ })
228
121
 
229
122
  t.after(async () => {
230
123
  await server.close()
@@ -244,6 +137,9 @@ test('buildServer()', async (t) => {
244
137
  })
245
138
 
246
139
  const address = await server.start()
140
+
141
+ assert.strictEqual(server.platformatic.configManager.fullPath, configFile)
142
+
247
143
  // The address should be a valid URL.
248
144
  new URL(address) // eslint-disable-line no-new
249
145
  })