@platformatic/service 0.28.1 → 0.30.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.
Files changed (44) hide show
  1. package/fixtures/hello-client-ts/tsconfig.json +3 -2
  2. package/fixtures/hello-client-ts-without-deps/hello.d.ts +34 -0
  3. package/fixtures/hello-client-ts-without-deps/hello.openapi.json +22 -0
  4. package/fixtures/hello-client-ts-without-deps/platformatic.service.json +23 -0
  5. package/fixtures/hello-client-ts-without-deps/plugin.ts +8 -0
  6. package/fixtures/hello-client-ts-without-deps/tsconfig.json +22 -0
  7. package/fixtures/hello-client-without-deps/hello.d.ts +34 -0
  8. package/fixtures/hello-client-without-deps/hello.openapi.json +22 -0
  9. package/fixtures/hello-client-without-deps/platformatic.service.json +21 -0
  10. package/fixtures/hello-client-without-deps/plugin.js +8 -0
  11. package/help/compile.txt +2 -1
  12. package/index.js +9 -1
  13. package/lib/compile.js +14 -11
  14. package/lib/plugins/clients.js +7 -3
  15. package/lib/plugins/plugins.js +20 -8
  16. package/lib/schema.js +50 -4
  17. package/package.json +6 -6
  18. package/test/cli/compile-1.test.mjs +500 -0
  19. package/test/cli/{compile.test.mjs → compile-2.test.mjs} +173 -149
  20. package/test/cli/helper.mjs +15 -0
  21. package/test/cli/tap-parallel-not-ok +0 -0
  22. package/test/clients.test.js +27 -2
  23. package/test/fixtures/bad-typescript-plugin/platformatic.service.json +1 -1
  24. package/test/fixtures/bad-typescript-plugin/tsconfig.json +1 -1
  25. package/test/fixtures/typescript-autoload/tsconfig.json +3 -3
  26. package/test/fixtures/typescript-compiled/compiled/plugin.js +6 -0
  27. package/test/fixtures/typescript-compiled/platformatic.service.json +18 -0
  28. package/test/fixtures/typescript-plugin-custom-flags/platformatic.service.json +18 -0
  29. package/test/fixtures/typescript-plugin-custom-flags/plugin.ts +5 -0
  30. package/test/fixtures/typescript-plugin-custom-flags/tsconfig.json +22 -0
  31. package/test/fixtures/typescript-plugin-custom-tsconfig/a-config-for-ts.json +22 -0
  32. package/test/fixtures/typescript-plugin-custom-tsconfig/platformatic.service.json +18 -0
  33. package/test/fixtures/typescript-plugin-custom-tsconfig/plugin.ts +5 -0
  34. package/test/fixtures/typescript-plugin-nocompile/tsconfig.json +3 -3
  35. package/test/fixtures/typescript-plugin-nocompile-enabled/platformatic.service.json +18 -0
  36. package/test/fixtures/typescript-plugin-nocompile-enabled/plugin.ts +5 -0
  37. package/test/fixtures/typescript-plugin-nocompile-enabled/tsconfig.json +22 -0
  38. package/test/fixtures/typescript-plugin-nocompile-string/platformatic.service.json +16 -0
  39. package/test/fixtures/typescript-plugin-nocompile-string/plugin.ts +5 -0
  40. package/test/fixtures/typescript-plugin-nocompile-string/tsconfig.json +22 -0
  41. package/test/fixtures/typescript-plugin-string/platformatic.service.json +16 -0
  42. package/test/fixtures/typescript-plugin-string/plugin.ts +5 -0
  43. package/test/fixtures/typescript-plugin-string/tsconfig.json +22 -0
  44. package/test/tap-parallel-ok +0 -0
@@ -2,9 +2,10 @@
2
2
  "compilerOptions": {
3
3
  "module": "commonjs",
4
4
  "esModuleInterop": true,
5
- "target": "es6",
5
+ "target": "es2020",
6
6
  "moduleResolution": "node",
7
- "sourceMap": true,
7
+ "sourceMap": false,
8
+ "incremental": true,
8
9
  "pretty": true,
9
10
  "noEmitOnError": true,
10
11
  "outDir": "dist"
@@ -0,0 +1,34 @@
1
+ import { FastifyPluginAsync } from 'fastify'
2
+
3
+ interface GetRequest {
4
+ }
5
+
6
+ interface GetResponse {
7
+ }
8
+
9
+ interface Hello {
10
+ get(req: GetRequest): Promise<GetResponse>;
11
+ }
12
+
13
+ type HelloPlugin = FastifyPluginAsync<NonNullable<hello.HelloOptions>>
14
+
15
+ declare module 'fastify' {
16
+ interface FastifyInstance {
17
+ 'hello': Hello;
18
+ }
19
+
20
+ interface FastifyRequest {
21
+ 'hello': Hello;
22
+ }
23
+ }
24
+
25
+ declare namespace hello {
26
+ export interface HelloOptions {
27
+ url: string
28
+ }
29
+ export const hello: HelloPlugin;
30
+ export { hello as default };
31
+ }
32
+
33
+ declare function hello(...params: Parameters<HelloPlugin>): ReturnType<HelloPlugin>;
34
+ export = hello;
@@ -0,0 +1,22 @@
1
+ {
2
+ "openapi": "3.0.3",
3
+ "info": {
4
+ "title": "Platformatic",
5
+ "description": "This is a service built on top of Platformatic",
6
+ "version": "1.0.0"
7
+ },
8
+ "components": {
9
+ "schemas": {}
10
+ },
11
+ "paths": {
12
+ "/": {
13
+ "get": {
14
+ "responses": {
15
+ "200": {
16
+ "description": "Default Response"
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "server": {
3
+ "hostname": "127.0.0.1",
4
+ "port": 0,
5
+ "logger": {
6
+ "level": "warn",
7
+ "name": "hello client ts"
8
+ },
9
+ "pluginTimeout": 30000
10
+ },
11
+ "plugins": {
12
+ "paths": ["./plugin.ts"],
13
+ "typescript": true
14
+ },
15
+ "clients": [{
16
+ "schema": "./hello.openapi.json",
17
+ "name": "hello",
18
+ "type": "openapi",
19
+ "url": "{PLT_CLIENT_URL}"
20
+ }],
21
+ "metrics": false,
22
+ "watch": false
23
+ }
@@ -0,0 +1,8 @@
1
+ import { FastifyInstance } from 'fastify'
2
+ /// <reference path="./hello" />
3
+
4
+ export default async function (app: FastifyInstance) {
5
+ app.get('/', async () => {
6
+ return app.hello.get({})
7
+ })
8
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "esModuleInterop": true,
5
+ "target": "es6",
6
+ "moduleResolution": "node",
7
+ "sourceMap": true,
8
+ "pretty": true,
9
+ "noEmitOnError": true,
10
+ "outDir": "dist"
11
+ },
12
+ "watchOptions": {
13
+ "watchFile": "fixedPollingInterval",
14
+ "watchDirectory": "fixedPollingInterval",
15
+ "fallbackPolling": "dynamicPriority",
16
+ "synchronousWatchDirectory": true,
17
+ "excludeDirectories": [
18
+ "**/node_modules",
19
+ "dist"
20
+ ]
21
+ }
22
+ }
@@ -0,0 +1,34 @@
1
+ import { FastifyPluginAsync } from 'fastify'
2
+
3
+ interface GetRequest {
4
+ }
5
+
6
+ interface GetResponse {
7
+ }
8
+
9
+ interface Hello {
10
+ get(req: GetRequest): Promise<GetResponse>;
11
+ }
12
+
13
+ type HelloPlugin = FastifyPluginAsync<NonNullable<hello.HelloOptions>>
14
+
15
+ declare module 'fastify' {
16
+ interface FastifyInstance {
17
+ 'hello': Hello;
18
+ }
19
+
20
+ interface FastifyRequest {
21
+ 'hello': Hello;
22
+ }
23
+ }
24
+
25
+ declare namespace hello {
26
+ export interface HelloOptions {
27
+ url: string
28
+ }
29
+ export const hello: HelloPlugin;
30
+ export { hello as default };
31
+ }
32
+
33
+ declare function hello(...params: Parameters<HelloPlugin>): ReturnType<HelloPlugin>;
34
+ export = hello;
@@ -0,0 +1,22 @@
1
+ {
2
+ "openapi": "3.0.3",
3
+ "info": {
4
+ "title": "Platformatic",
5
+ "description": "This is a service built on top of Platformatic",
6
+ "version": "1.0.0"
7
+ },
8
+ "components": {
9
+ "schemas": {}
10
+ },
11
+ "paths": {
12
+ "/": {
13
+ "get": {
14
+ "responses": {
15
+ "200": {
16
+ "description": "Default Response"
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "server": {
3
+ "hostname": "127.0.0.1",
4
+ "port": 0,
5
+ "logger": {
6
+ "level": "warn",
7
+ "name": "hello client"
8
+ }
9
+ },
10
+ "plugins": {
11
+ "paths": ["./plugin.js"]
12
+ },
13
+ "clients": [{
14
+ "schema": "./hello.openapi.json",
15
+ "name": "hello",
16
+ "type": "openapi",
17
+ "url": "{PLT_CLIENT_URL}"
18
+ }],
19
+ "metrics": false,
20
+ "watch": false
21
+ }
@@ -0,0 +1,8 @@
1
+ 'use default'
2
+
3
+ /** @type {import('fastify').FastifyPluginAsync<{ optionA: boolean, optionB: string }>} */
4
+ module.exports = async function (app) {
5
+ app.get('/', async () => {
6
+ return app.hello.get()
7
+ })
8
+ }
package/help/compile.txt CHANGED
@@ -1,9 +1,10 @@
1
1
  Compile typescript plugins.
2
+
2
3
  ``` bash
3
4
  $ platformatic service compile
4
5
  ```
5
6
 
6
- As a result of executing this command, the Platformatic DB will compile typescript
7
+ As a result of executing this command, Platformatic Service will compile typescript
7
8
  plugins in the `outDir` directory.
8
9
 
9
10
  If not specified, the configuration specified will be loaded from
package/index.js CHANGED
@@ -46,7 +46,15 @@ async function platformaticService (app, opts, toLoad = []) {
46
46
  }
47
47
 
48
48
  if (config.plugins) {
49
- if (config.plugins.typescript) {
49
+ let registerTsCompiler = false
50
+ const typescript = config.plugins.typescript
51
+ if (typescript === true) {
52
+ registerTsCompiler = true
53
+ } else if (typeof typescript === 'object') {
54
+ registerTsCompiler = typescript.enabled === true || typescript.enabled === undefined
55
+ }
56
+
57
+ if (registerTsCompiler) {
50
58
  await app.register(setupTsCompiler)
51
59
  }
52
60
  await app.register(loadPlugins)
package/lib/compile.js CHANGED
@@ -48,29 +48,30 @@ async function setup (cwd, config, logger) {
48
48
  /* c8 ignore next 4 */
49
49
  if (tscExecutablePath === undefined) {
50
50
  const msg = 'The tsc executable was not found.'
51
- logger.error(msg)
51
+ logger.warn(msg)
52
52
  }
53
53
 
54
- const tsconfigPath = resolve(cwd, 'tsconfig.json')
55
- const tsconfigExists = await isFileAccessible(tsconfigPath)
54
+ const tsConfigPath = config?.plugins?.typescript?.tsConfig || resolve(cwd, 'tsconfig.json')
55
+ const tsConfigExists = await isFileAccessible(tsConfigPath)
56
56
 
57
- if (!tsconfigExists) {
58
- const msg = 'The tsconfig.json file was not found.'
59
- logger.error(msg)
57
+ if (!tsConfigExists) {
58
+ const msg = 'No typescript configuration file was found.'
59
+ logger.warn(msg)
60
60
  }
61
61
 
62
- return { execa, logger, tscExecutablePath }
62
+ return { execa, logger, tscExecutablePath, tsConfigPath, tsConfigExists }
63
63
  }
64
64
 
65
65
  async function compile (cwd, config, originalLogger) {
66
- const { execa, logger, tscExecutablePath } = await setup(cwd, config, originalLogger)
66
+ const { execa, logger, tscExecutablePath, tsConfigPath, tsConfigExists } = await setup(cwd, config, originalLogger)
67
67
  /* c8 ignore next 3 */
68
- if (!tscExecutablePath) {
68
+ if (!tscExecutablePath || !tsConfigExists) {
69
69
  return false
70
70
  }
71
71
 
72
72
  try {
73
- await execa(tscExecutablePath, ['--project', 'tsconfig.json', '--rootDir', '.'], { cwd })
73
+ const tsFlags = config?.plugins?.typescript?.flags || ['--project', tsConfigPath, '--rootDir', '.']
74
+ await execa(tscExecutablePath, tsFlags, { cwd })
74
75
  logger.info('Typescript compilation completed successfully.')
75
76
  return true
76
77
  } catch (error) {
@@ -82,11 +83,13 @@ async function compile (cwd, config, originalLogger) {
82
83
  function buildCompileCmd (app) {
83
84
  return async function compileCmd (_args) {
84
85
  let fullPath = null
86
+ let config = null
85
87
  try {
86
88
  const { configManager } = await loadConfig({}, _args, app, {
87
89
  watch: false
88
90
  })
89
91
  await configManager.parseAndValidate()
92
+ config = configManager.current
90
93
  fullPath = dirname(configManager.fullPath)
91
94
  /* c8 ignore next 4 */
92
95
  } catch (err) {
@@ -94,7 +97,7 @@ function buildCompileCmd (app) {
94
97
  process.exit(1)
95
98
  }
96
99
 
97
- if (!await compile(fullPath)) {
100
+ if (!await compile(fullPath, config)) {
98
101
  process.exit(1)
99
102
  }
100
103
  }
@@ -1,11 +1,15 @@
1
1
  'use strict'
2
2
 
3
3
  const fp = require('fastify-plugin')
4
+ const client = require('@platformatic/client')
4
5
 
5
6
  async function setupClients (app, opts) {
6
- const clientsConfig = opts
7
- for (const { path, url } of clientsConfig) {
8
- app.register(require(path), { url })
7
+ for (const { path, url, serviceId, name, schema, type } of opts) {
8
+ if (path) {
9
+ app.register(require(path), { url, serviceId })
10
+ } else {
11
+ app.register(client, { url, serviceId, name, path: schema, type })
12
+ }
9
13
  }
10
14
  }
11
15
 
@@ -12,18 +12,30 @@ async function loadPlugins (app) {
12
12
  const configManager = app.platformatic.configManager
13
13
  const config = configManager.current
14
14
 
15
- if (config.plugins.typescript) {
16
- const workingDir = configManager.dirname
17
- const tsConfigPath = join(workingDir, 'tsconfig.json')
15
+ let isOutDirAccessible = false
16
+ let outDir = null
18
17
 
19
- const isTsConfigAccessible = await isFileAccessible(tsConfigPath)
20
- if (!isTsConfigAccessible) {
21
- throw new Error('Cannot load typescript plugin, tsconfig.json not found')
22
- }
18
+ const workingDir = configManager.dirname
19
+ const tsConfigPath = configManager.current.plugins.typescript?.tsConfig || join(workingDir, 'tsconfig.json')
23
20
 
21
+ // If the tsconfig.json file exists, then we need to adjust the plugin paths
22
+ // to point to the compiled JS files.
23
+ const isTsConfigAccessible = await isFileAccessible(tsConfigPath)
24
+ if (isTsConfigAccessible) {
24
25
  const tsConfig = JSON.parse(await readFile(tsConfigPath, 'utf8'))
25
- const outDir = resolve(workingDir, tsConfig.compilerOptions.outDir)
26
+ outDir = resolve(workingDir, tsConfig.compilerOptions.outDir)
27
+ }
28
+
29
+ /* c8 ignore next 3 */
30
+ if (configManager.current.plugins.typescript?.outDir) {
31
+ outDir = configManager.current.plugins.typescript.outDir
32
+ }
33
+
34
+ if (outDir) {
35
+ isOutDirAccessible = await isFileAccessible(outDir)
36
+ }
26
37
 
38
+ if (isOutDirAccessible) {
27
39
  config.plugins.paths = config.plugins.paths.map((plugin) => {
28
40
  /* c8 ignore next 3 */
29
41
  return typeof plugin === 'string'
package/lib/schema.js CHANGED
@@ -390,7 +390,36 @@ const plugins = {
390
390
  type: 'integer'
391
391
  },
392
392
  typescript: {
393
- type: 'boolean'
393
+ anyOf: [{
394
+ type: 'object',
395
+ properties: {
396
+ enabled: {
397
+ anyOf: [{
398
+ type: 'boolean'
399
+ }, {
400
+ type: 'string'
401
+ }]
402
+ },
403
+ tsConfig: {
404
+ type: 'string',
405
+ resolvePath: true
406
+ },
407
+ outDir: {
408
+ type: 'string',
409
+ resolvePath: true
410
+ },
411
+ flags: {
412
+ type: 'array',
413
+ items: {
414
+ type: 'string'
415
+ }
416
+ }
417
+ }
418
+ }, {
419
+ type: 'boolean'
420
+ }, {
421
+ type: 'string'
422
+ }]
394
423
  }
395
424
  },
396
425
  additionalProperties: false,
@@ -403,7 +432,12 @@ const metrics = {
403
432
  {
404
433
  type: 'object',
405
434
  properties: {
406
- port: { type: 'integer' },
435
+ port: {
436
+ anyOf: [
437
+ { type: 'integer' },
438
+ { type: 'string' }
439
+ ]
440
+ },
407
441
  hostname: { type: 'string' },
408
442
  auth: {
409
443
  type: 'object',
@@ -515,16 +549,26 @@ const clients = {
515
549
  serviceId: {
516
550
  type: 'string'
517
551
  },
552
+ name: {
553
+ type: 'string'
554
+ },
555
+ type: {
556
+ type: 'string',
557
+ enum: ['openapi', 'graphql']
558
+ },
518
559
  path: {
519
560
  type: 'string',
520
561
  resolvePath: true
521
562
  },
563
+ schema: {
564
+ type: 'string',
565
+ resolvePath: true
566
+ },
522
567
  url: {
523
568
  type: 'string'
524
569
  }
525
570
  },
526
- additionalProperties: false,
527
- required: ['path', 'url']
571
+ additionalProperties: false
528
572
  }
529
573
  }
530
574
 
@@ -538,6 +582,8 @@ const platformaticServiceSchema = {
538
582
  watch: {
539
583
  anyOf: [watch, {
540
584
  type: 'boolean'
585
+ }, {
586
+ type: 'string'
541
587
  }]
542
588
  },
543
589
  $schema: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/service",
3
- "version": "0.28.1",
3
+ "version": "0.30.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -64,11 +64,11 @@
64
64
  "pino-pretty": "^10.0.0",
65
65
  "rfdc": "^1.3.0",
66
66
  "ua-parser-js": "^1.0.35",
67
- "@platformatic/client": "0.28.1",
68
- "@platformatic/config": "0.28.1",
69
- "@platformatic/swagger-ui-theme": "0.28.1",
70
- "@platformatic/types": "0.28.1",
71
- "@platformatic/utils": "0.28.1"
67
+ "@platformatic/client": "0.30.0",
68
+ "@platformatic/config": "0.30.0",
69
+ "@platformatic/swagger-ui-theme": "0.30.0",
70
+ "@platformatic/types": "0.30.0",
71
+ "@platformatic/utils": "0.30.0"
72
72
  },
73
73
  "standard": {
74
74
  "ignore": [