@platformatic/service 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.
Files changed (37) hide show
  1. package/fixtures/hello/platformatic.service.json +1 -2
  2. package/fixtures/hello/warn-log.service.json +1 -2
  3. package/fixtures/hello-client/platformatic.service.json +2 -3
  4. package/fixtures/hello-client-ts/platformatic.service.json +2 -3
  5. package/index.d.ts +17 -11
  6. package/index.js +4 -21
  7. package/index.test-d.ts +14 -22
  8. package/lib/compile.js +14 -38
  9. package/lib/gen-schema.js +1 -0
  10. package/lib/load-config.js +1 -2
  11. package/lib/plugins/openapi.js +1 -0
  12. package/lib/plugins/plugins.js +1 -19
  13. package/lib/plugins/typescript.js +1 -31
  14. package/lib/root-endpoint/public/background_frame.svg +614 -0
  15. package/lib/root-endpoint/public/background_polygon_14.svg +3 -0
  16. package/lib/root-endpoint/public/background_polygon_28.svg +3 -0
  17. package/lib/root-endpoint/public/dark_mode.svg +3 -0
  18. package/lib/root-endpoint/public/index.html +174 -35
  19. package/lib/root-endpoint/public/light_mode.svg +11 -0
  20. package/lib/root-endpoint/public/platformatic-logo-dark.svg +8 -0
  21. package/lib/root-endpoint/public/platformatic-logo-light.svg +8 -0
  22. package/lib/schema.js +3 -10
  23. package/lib/start.js +2 -26
  24. package/lib/utils.js +8 -0
  25. package/package.json +28 -20
  26. package/test/autoload.test.js +0 -182
  27. package/test/cli/compile.test.mjs +1 -1
  28. package/test/cli/helper.mjs +3 -2
  29. package/test/fixtures/bad-typescript-plugin/platformatic.service.json +1 -1
  30. package/test/fixtures/nested-directories/modules/inventory/routes/product.js +0 -1
  31. package/test/load-and-reload-files.test.js +7 -278
  32. package/test/utils.test.js +7 -0
  33. package/tsconfig.json +12 -0
  34. package/lib/plugins/file-watcher.js +0 -44
  35. package/lib/root-endpoint/public/logo-512x512.png +0 -0
  36. package/test/cli/watch.test.mjs +0 -289
  37. package/test/watch.test.js +0 -248
@@ -8,8 +8,7 @@
8
8
  }
9
9
  },
10
10
  "plugins": {
11
- "paths": ["./plugin.js"],
12
- "hotReload": false
11
+ "paths": ["./plugin.js"]
13
12
  },
14
13
  "service": {
15
14
  "openapi": true
@@ -8,8 +8,7 @@
8
8
  }
9
9
  },
10
10
  "plugins": {
11
- "paths": ["./plugin.js"],
12
- "hotReload": false
11
+ "paths": ["./plugin.js"]
13
12
  },
14
13
  "service": {
15
14
  "openapi": true
@@ -8,11 +8,10 @@
8
8
  }
9
9
  },
10
10
  "plugins": {
11
- "paths": ["./plugin.js"],
12
- "hotReload": false
11
+ "paths": ["./plugin.js"]
13
12
  },
14
13
  "clients": [{
15
- "path": "./hello",
14
+ "path": "hello",
16
15
  "url": "{PLT_CLIENT_URL}"
17
16
  }],
18
17
  "metrics": false,
@@ -10,11 +10,10 @@
10
10
  },
11
11
  "plugins": {
12
12
  "paths": ["./plugin.ts"],
13
- "typescript": true,
14
- "hotReload": false
13
+ "typescript": true
15
14
  },
16
15
  "clients": [{
17
- "path": "./hello",
16
+ "path": "hello",
18
17
  "url": "{PLT_CLIENT_URL}"
19
18
  }],
20
19
  "metrics": false,
package/index.d.ts CHANGED
@@ -1,15 +1,21 @@
1
- import { FastifyInstance } from "fastify"
1
+ /* eslint-disable @typescript-eslint/triple-slash-reference */
2
+ /// <reference types="@platformatic/types" />
3
+ /// <reference types="mercurius" />
4
+ /// <reference types="@fastify/swagger" />
5
+ import { FastifyInstance } from 'fastify'
6
+ import ConfigManager from '@platformatic/config'
2
7
 
3
- export type pltServiceHandlerBuildServer = {
4
- app: FastifyInstance
5
- address: string
6
- port: number
7
- restart: () => Promise<void>
8
- listen: FastifyInstance['listen']
9
- close: FastifyInstance['close']
10
- inject: FastifyInstance['inject']
8
+ declare module '@platformatic/types' {
9
+ interface PlatformaticApp {
10
+ configManager: ConfigManager
11
+ config: object
12
+ }
11
13
  }
12
14
 
13
- declare module '@platformatic/service' {
14
- export function buildServer(opts: object, app?: object, ConfigManagerContructor?: object): Promise<pltServiceHandlerBuildServer>
15
+ export function buildServer (opts: object, app?: object, ConfigManagerContructor?: object): Promise<FastifyInstance>
16
+
17
+ declare module 'fastify' {
18
+ interface FastifyInstance {
19
+ restart: () => Promise<void>
20
+ }
15
21
  }
package/index.js CHANGED
@@ -9,7 +9,6 @@ const setupGraphQL = require('./lib/plugins/graphql.js')
9
9
  const setupClients = require('./lib/plugins/clients')
10
10
  const setupMetrics = require('./lib/plugins/metrics')
11
11
  const setupTsCompiler = require('./lib/plugins/typescript')
12
- const setupFileWatcher = require('./lib/plugins/file-watcher')
13
12
  const setupHealthCheck = require('./lib/plugins/health-check')
14
13
  const loadPlugins = require('./lib/plugins/plugins')
15
14
 
@@ -54,7 +53,10 @@ async function platformaticService (app, opts, toLoad = []) {
54
53
  }
55
54
 
56
55
  if (isKeyEnabled('watch', config)) {
57
- await app.register(setupFileWatcher, { onFilesUpdated })
56
+ // If file watching is enabled here, that means the service was started
57
+ // without the runtime because the runtime explicitly disables watching on
58
+ // services that it starts. Warn the user that things will not go as planned.
59
+ app.log.warn('service was started with file watching enabled but watching is only available via the runtime')
58
60
  }
59
61
 
60
62
  if (config.server.cors) {
@@ -70,25 +72,6 @@ async function platformaticService (app, opts, toLoad = []) {
70
72
  }
71
73
  }
72
74
 
73
- async function onFilesUpdated (app) {
74
- // Reload the config as well, otherwise we will have problems
75
- // in case the files watcher triggers the config watcher too
76
- const configManager = app.platformatic.configManager
77
- try {
78
- app.log.debug('files changed')
79
- await configManager.parse()
80
- await app.restart()
81
- /* c8 ignore next 8 */
82
- } catch (err) {
83
- app.log.error({
84
- err: {
85
- message: err.message,
86
- stack: err.stack
87
- }
88
- }, 'failed to reload server')
89
- }
90
- }
91
-
92
75
  platformaticService[Symbol.for('skip-override')] = true
93
76
  platformaticService.schema = schema
94
77
  platformaticService.configType = 'service'
package/index.test-d.ts CHANGED
@@ -1,24 +1,16 @@
1
- import { expectError, expectType } from 'tsd';
2
- import { FastifyInstance } from 'fastify';
3
- import { pltServiceHandlerBuildServer } from '.';
1
+ import { expectType } from 'tsd'
2
+ import { FastifyInstance } from 'fastify'
3
+ import { buildServer } from '.'
4
+ import ConfigManager from '@platformatic/config'
5
+ import { OpenAPI } from 'openapi-types'
6
+ import type { MercuriusPlugin } from 'mercurius'
4
7
 
5
- const server: pltServiceHandlerBuildServer = {
6
- app: {} as FastifyInstance,
7
- address: 'localhost',
8
- port: 3000,
9
- restart: async () => {},
10
- listen: async () => '',
11
- close: (async () => undefined) as unknown as FastifyInstance['close'],
12
- inject: (async () => undefined) as unknown as FastifyInstance['inject']
13
- };
8
+ const server = await buildServer({
9
+ })
14
10
 
15
- expectType<pltServiceHandlerBuildServer>(server);
16
- expectError<pltServiceHandlerBuildServer>({...server, app: 'WRONG' });
17
- expectError<pltServiceHandlerBuildServer>({...server, address: 42 });
18
- expectError<pltServiceHandlerBuildServer>({...server, port: 'WRONG' });
19
- expectError<pltServiceHandlerBuildServer>({...server, restart: 'WRONG' });
20
- expectError<pltServiceHandlerBuildServer>({...server, listen: 'WRONG' });
21
- expectError<pltServiceHandlerBuildServer>({...server, listen: async () => ({ address: 42, port: 3000 }), });
22
- expectError<pltServiceHandlerBuildServer>({...server, listen: async () => ({ address: 'localhost', port: 'WRONG' }), });
23
- expectError<pltServiceHandlerBuildServer>({...server, stop: 'WRONG' });
24
- expectError<pltServiceHandlerBuildServer>({...server, inject: 'WRONG' });
11
+ expectType<FastifyInstance>(server)
12
+ expectType<ConfigManager>(server.platformatic.configManager)
13
+ expectType<ConfigManager>(server.platformatic.configManager)
14
+ expectType<OpenAPI.Document>(server.swagger())
15
+ expectType<MercuriusPlugin>(server.graphql)
16
+ expectType<Promise<void>>(server.restart())
package/lib/compile.js CHANGED
@@ -28,16 +28,18 @@ async function getTSCExecutablePath (cwd) {
28
28
  }
29
29
  }
30
30
 
31
- async function setup (cwd, config) {
32
- const logger = pino(
33
- pretty({
34
- translateTime: 'SYS:HH:MM:ss',
35
- ignore: 'hostname,pid'
36
- })
37
- )
38
-
39
- if (config?.server.logger) {
40
- logger.level = config.server.logger.level
31
+ async function setup (cwd, config, logger) {
32
+ if (!logger) {
33
+ logger = pino(
34
+ pretty({
35
+ translateTime: 'SYS:HH:MM:ss',
36
+ ignore: 'hostname,pid'
37
+ })
38
+ )
39
+
40
+ if (config?.server.logger) {
41
+ logger.level = config.server.logger.level
42
+ }
41
43
  }
42
44
 
43
45
  const { execa } = await import('execa')
@@ -60,8 +62,8 @@ async function setup (cwd, config) {
60
62
  return { execa, logger, tscExecutablePath }
61
63
  }
62
64
 
63
- async function compile (cwd, config) {
64
- const { execa, logger, tscExecutablePath } = await setup(cwd, config)
65
+ async function compile (cwd, config, originalLogger) {
66
+ const { execa, logger, tscExecutablePath } = await setup(cwd, config, originalLogger)
65
67
  /* c8 ignore next 3 */
66
68
  if (!tscExecutablePath) {
67
69
  return false
@@ -77,31 +79,6 @@ async function compile (cwd, config) {
77
79
  }
78
80
  }
79
81
 
80
- // This path is tested but C8 does not see it that way given it needs to work
81
- // through execa.
82
- /* c8 ignore next 20 */
83
- async function compileWatch (cwd, config) {
84
- const { execa, logger, tscExecutablePath } = await setup(cwd, config)
85
- if (!tscExecutablePath) {
86
- return false
87
- }
88
-
89
- try {
90
- await execa(tscExecutablePath, ['--project', 'tsconfig.json', '--incremental', '--rootDir', '.'], { cwd })
91
- logger.info('Typescript compilation completed successfully. Starting watch mode.')
92
- } catch (error) {
93
- throw new Error('Failed to compile typescript files: ' + error)
94
- }
95
-
96
- const child = execa(tscExecutablePath, ['--project', 'tsconfig.json', '--watch', '--incremental'], { cwd })
97
- child.stdout.resume()
98
- child.stderr.on('data', (data) => {
99
- logger.error(data.toString())
100
- })
101
-
102
- return { child }
103
- }
104
-
105
82
  function buildCompileCmd (app) {
106
83
  return async function compileCmd (_args) {
107
84
  let fullPath = null
@@ -124,5 +101,4 @@ function buildCompileCmd (app) {
124
101
  }
125
102
 
126
103
  module.exports.compile = compile
127
- module.exports.compileWatch = compileWatch
128
104
  module.exports.buildCompileCmd = buildCompileCmd
package/lib/gen-schema.js CHANGED
@@ -1,3 +1,4 @@
1
+ 'use strict'
1
2
 
2
3
  const { writeFile } = require('fs/promises')
3
4
  const { schema: platformaticServiceSchema } = require('./schema.js')
@@ -18,8 +18,7 @@ async function loadConfig (minimistConfig, _args, app, overrides = {}) {
18
18
  const args = parseArgs(_args, deepmerge({ all: true })({
19
19
  string: ['allow-env'],
20
20
  default: {
21
- allowEnv: '', // The default is set in ConfigManager
22
- hotReload: true
21
+ allowEnv: '' // The default is set in ConfigManager
23
22
  },
24
23
  alias: {
25
24
  v: 'version',
@@ -37,6 +37,7 @@ async function setupOpenAPI (app, opts) {
37
37
  app.register(SwaggerUI, {
38
38
  ...theme,
39
39
  ...opts,
40
+ logLevel: 'warn',
40
41
  prefix: '/documentation'
41
42
  })
42
43
  }
@@ -2,8 +2,6 @@
2
2
 
3
3
  const { join, resolve } = require('path')
4
4
  const { readFile } = require('fs/promises')
5
-
6
- const sandbox = require('fastify-sandbox')
7
5
  const fp = require('fastify-plugin')
8
6
 
9
7
  const { getJSPluginPath, isFileAccessible } = require('../utils')
@@ -34,23 +32,7 @@ async function loadPlugins (app) {
34
32
  })
35
33
  }
36
34
 
37
- if (config.plugins.hotReload !== false) {
38
- await app.register(sandbox, {
39
- path: wrapperPath,
40
- options: { paths: config.plugins.paths },
41
- customizeGlobalThis (_globalThis) {
42
- // Taken from https://github.com/nodejs/undici/blob/fa9fd9066569b6357acacffb806aa804b688c9d8/lib/global.js#L5
43
- const globalDispatcher = Symbol.for('undici.globalDispatcher.1')
44
- const dispatcher = globalThis[globalDispatcher]
45
- /* istanbul ignore else */
46
- if (dispatcher) {
47
- _globalThis[globalDispatcher] = dispatcher
48
- }
49
- }
50
- })
51
- } else {
52
- await app.register(require(wrapperPath), { paths: config.plugins.paths })
53
- }
35
+ await app.register(require(wrapperPath), { paths: config.plugins.paths })
54
36
  }
55
37
 
56
38
  module.exports = fp(loadPlugins)
@@ -1,8 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const { isKeyEnabled } = require('@platformatic/utils')
4
3
  const fp = require('fastify-plugin')
5
-
6
4
  const compiler = require('../compile')
7
5
 
8
6
  async function setupTsCompiler (app) {
@@ -10,37 +8,9 @@ async function setupTsCompiler (app) {
10
8
 
11
9
  const configManager = app.platformatic.configManager
12
10
  const config = configManager.current
13
-
14
- const isRestartableApp = app.restarted !== undefined
15
-
16
- // to run the plugin without restartable
17
- /* c8 ignore next 1 */
18
- const persistentRef = isRestartableApp ? app.persistentRef : app
19
-
20
11
  const workingDir = configManager.dirname
21
12
 
22
- if (isKeyEnabled('watch', config)) {
23
- let tsCompilerWatcher = persistentRef.tsCompilerWatcher
24
- if (!tsCompilerWatcher) {
25
- /* c8 ignore next 5 */
26
- const { child } = await compiler.compileWatch(workingDir, config)
27
- app.log.debug('start watching typescript files')
28
- tsCompilerWatcher = child
29
- }
30
- app.decorate('tsCompilerWatcher', tsCompilerWatcher)
31
- } else {
32
- await compiler.compile(workingDir, config)
33
- }
34
-
35
- app.addHook('onClose', async () => {
36
- if (!isRestartableApp || app.closingRestartable) {
37
- /* c8 ignore next 4 */
38
- if (app.tsCompilerWatcher) {
39
- app.tsCompilerWatcher.kill('SIGTERM')
40
- app.log.debug('stop watching typescript files')
41
- }
42
- }
43
- })
13
+ await compiler.compile(workingDir, config, app.log)
44
14
  }
45
15
 
46
16
  module.exports = fp(setupTsCompiler)