@platformatic/service 0.27.0 → 0.29.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 (49) 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/fixtures/hello-client-ts-without-deps/hello.d.ts +34 -0
  6. package/fixtures/hello-client-ts-without-deps/hello.openapi.json +22 -0
  7. package/fixtures/hello-client-ts-without-deps/platformatic.service.json +23 -0
  8. package/fixtures/hello-client-ts-without-deps/plugin.ts +8 -0
  9. package/fixtures/hello-client-ts-without-deps/tsconfig.json +22 -0
  10. package/fixtures/hello-client-without-deps/hello.d.ts +34 -0
  11. package/fixtures/hello-client-without-deps/hello.openapi.json +22 -0
  12. package/fixtures/hello-client-without-deps/platformatic.service.json +21 -0
  13. package/fixtures/hello-client-without-deps/plugin.js +8 -0
  14. package/help/compile.txt +2 -1
  15. package/index.d.ts +17 -11
  16. package/index.js +4 -21
  17. package/index.test-d.ts +14 -22
  18. package/lib/compile.js +0 -26
  19. package/lib/load-config.js +1 -2
  20. package/lib/plugins/clients.js +7 -3
  21. package/lib/plugins/plugins.js +17 -33
  22. package/lib/plugins/typescript.js +1 -31
  23. package/lib/root-endpoint/public/background_frame.svg +614 -0
  24. package/lib/root-endpoint/public/background_polygon_14.svg +3 -0
  25. package/lib/root-endpoint/public/background_polygon_28.svg +3 -0
  26. package/lib/root-endpoint/public/dark_mode.svg +3 -0
  27. package/lib/root-endpoint/public/index.html +164 -35
  28. package/lib/root-endpoint/public/light_mode.svg +11 -0
  29. package/lib/root-endpoint/public/platformatic-logo-dark.svg +8 -0
  30. package/lib/root-endpoint/public/platformatic-logo-light.svg +8 -0
  31. package/lib/schema.js +28 -14
  32. package/lib/start.js +2 -23
  33. package/package.json +17 -9
  34. package/test/autoload.test.js +0 -182
  35. package/test/cli/compile.test.mjs +98 -1
  36. package/test/clients.test.js +53 -0
  37. package/test/fixtures/bad-typescript-plugin/platformatic.service.json +1 -1
  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/load-and-reload-files.test.js +7 -278
  45. package/tsconfig.json +12 -0
  46. package/lib/plugins/file-watcher.js +0 -44
  47. package/lib/root-endpoint/public/logo-512x512.png +0 -0
  48. package/test/cli/watch.test.mjs +0 -289
  49. package/test/watch.test.js +0 -248
@@ -47,99 +47,6 @@ test('autoload & filesystem based routing / watch disabled', async ({ teardown,
47
47
  }
48
48
  })
49
49
 
50
- test('autoload & filesystem based routing / watch enabled', async ({ teardown, equal }) => {
51
- const config = {
52
- server: {
53
- hostname: '127.0.0.1',
54
- port: 0
55
- },
56
- plugins: {
57
- paths: [join(__dirname, 'fixtures', 'directories', 'routes')]
58
- },
59
- watch: true,
60
- metrics: false
61
- }
62
-
63
- const app = await buildServer(config)
64
- teardown(async () => {
65
- await app.close()
66
- })
67
- await app.start()
68
-
69
- {
70
- const res = await request(`${app.url}/`)
71
- equal(res.statusCode, 200, 'status code')
72
- const body = await res.body.json()
73
- equal(body.hello, 'from root', 'body')
74
- }
75
-
76
- {
77
- const res = await request(`${app.url}/foo/bar`)
78
- equal(res.statusCode, 200, 'status code')
79
- const body = await res.body.json()
80
- equal(body.hello, 'from bar', 'body')
81
- }
82
-
83
- {
84
- const res = await request(`${app.url}/foo/baz`)
85
- equal(res.statusCode, 200, 'status code')
86
- const body = await res.body.json()
87
- equal(body.hello, 'from baz', 'body')
88
- }
89
- })
90
-
91
- test('multiple files', async ({ teardown, equal }) => {
92
- const config = {
93
- server: {
94
- hostname: '127.0.0.1',
95
- port: 0
96
- },
97
- plugins: {
98
- paths: [{
99
- path: join(__dirname, 'fixtures', 'directories', 'plugins')
100
- }, {
101
- path: join(__dirname, 'fixtures', 'directories', 'routes')
102
- }]
103
- },
104
- watch: true,
105
- metrics: false
106
- }
107
-
108
- const app = await buildServer(config)
109
- teardown(async () => {
110
- await app.close()
111
- })
112
- await app.start()
113
-
114
- {
115
- const res = await request(`${app.url}/`)
116
- equal(res.statusCode, 200, 'status code')
117
- const body = await res.body.json()
118
- equal(body.hello, 'from root', 'body')
119
- }
120
-
121
- {
122
- const res = await request(`${app.url}/foo/bar`)
123
- equal(res.statusCode, 200, 'status code')
124
- const body = await res.body.json()
125
- equal(body.hello, 'from bar', 'body')
126
- }
127
-
128
- {
129
- const res = await request(`${app.url}/foo/baz`)
130
- equal(res.statusCode, 200, 'status code')
131
- const body = await res.body.json()
132
- equal(body.hello, 'from baz', 'body')
133
- }
134
-
135
- {
136
- const res = await request(`${app.url}/foo/with-decorator`)
137
- equal(res.statusCode, 200, 'status code')
138
- const body = await res.body.json()
139
- equal(body.hello, 'bar', 'body')
140
- }
141
- })
142
-
143
50
  test('multiple files / watch false', async ({ teardown, equal }) => {
144
51
  const config = {
145
52
  server: {
@@ -233,95 +140,6 @@ test('autoload & filesystem based routing / watch disabled / no object', async (
233
140
  }
234
141
  })
235
142
 
236
- test('autoload & filesystem based routing / watch enabled / no object', async ({ teardown, equal }) => {
237
- const config = {
238
- server: {
239
- hostname: '127.0.0.1',
240
- port: 0
241
- },
242
- plugins: {
243
- paths: [join(__dirname, 'fixtures', 'directories', 'routes')]
244
- },
245
- watch: true,
246
- metrics: false
247
- }
248
-
249
- const app = await buildServer(config)
250
- teardown(async () => {
251
- await app.close()
252
- })
253
- await app.start()
254
-
255
- {
256
- const res = await request(`${app.url}/`)
257
- equal(res.statusCode, 200, 'status code')
258
- const body = await res.body.json()
259
- equal(body.hello, 'from root', 'body')
260
- }
261
-
262
- {
263
- const res = await request(`${app.url}/foo/bar`)
264
- equal(res.statusCode, 200, 'status code')
265
- const body = await res.body.json()
266
- equal(body.hello, 'from bar', 'body')
267
- }
268
-
269
- {
270
- const res = await request(`${app.url}/foo/baz`)
271
- equal(res.statusCode, 200, 'status code')
272
- const body = await res.body.json()
273
- equal(body.hello, 'from baz', 'body')
274
- }
275
- })
276
-
277
- test('multiple files / no object', async ({ teardown, equal }) => {
278
- const config = {
279
- server: {
280
- hostname: '127.0.0.1',
281
- port: 0
282
- },
283
- plugins: {
284
- paths: [join(__dirname, 'fixtures', 'directories', 'plugins'), join(__dirname, 'fixtures', 'directories', 'routes')]
285
- },
286
- watch: true,
287
- metrics: false
288
- }
289
-
290
- const app = await buildServer(config)
291
- teardown(async () => {
292
- await app.close()
293
- })
294
- await app.start()
295
-
296
- {
297
- const res = await request(`${app.url}/`)
298
- equal(res.statusCode, 200, 'status code')
299
- const body = await res.body.json()
300
- equal(body.hello, 'from root', 'body')
301
- }
302
-
303
- {
304
- const res = await request(`${app.url}/foo/bar`)
305
- equal(res.statusCode, 200, 'status code')
306
- const body = await res.body.json()
307
- equal(body.hello, 'from bar', 'body')
308
- }
309
-
310
- {
311
- const res = await request(`${app.url}/foo/baz`)
312
- equal(res.statusCode, 200, 'status code')
313
- const body = await res.body.json()
314
- equal(body.hello, 'from baz', 'body')
315
- }
316
-
317
- {
318
- const res = await request(`${app.url}/foo/with-decorator`)
319
- equal(res.statusCode, 200, 'status code')
320
- const body = await res.body.json()
321
- equal(body.hello, 'bar', 'body')
322
- }
323
- })
324
-
325
143
  test('multiple files / watch false / no object', async ({ teardown, equal }) => {
326
144
  const config = {
327
145
  server: {
@@ -164,7 +164,7 @@ t.test('start command should not compile typescript plugin with errors', async (
164
164
  await childProcess
165
165
  t.fail('should not compile bad typescript plugin')
166
166
  } catch (err) {
167
- if (!err.stderr.includes('Found 1 error')) {
167
+ if (!err.stdout.includes('Found 1 error')) {
168
168
  t.comment(err.stdout)
169
169
  t.comment(err.stderr)
170
170
  t.fail('should throw one ts error')
@@ -284,3 +284,100 @@ t.test('should compile typescript plugin with start command from a folder', asyn
284
284
  }
285
285
  t.fail('should compile typescript plugin with start command')
286
286
  })
287
+
288
+ t.test('should start the service if it was precompiled and typescript is `false`', async (t) => {
289
+ const testDir = path.join(urlDirname(import.meta.url), '..', 'fixtures', 'typescript-plugin-nocompile')
290
+ const cwd = path.join(urlDirname(import.meta.url), '..', 'tmp', 'typescript-plugin-clone-9')
291
+
292
+ await cp(testDir, cwd, { recursive: true })
293
+
294
+ await execa('node', [cliPath, 'compile'], { cwd })
295
+
296
+ const child = execa('node', [cliPath, 'start'], { cwd })
297
+
298
+ const splitter = split()
299
+ child.stdout.pipe(splitter)
300
+
301
+ for await (const data of splitter) {
302
+ const sanitized = stripAnsi(data)
303
+ if (sanitized.includes('Typescript plugin loaded')) {
304
+ t.pass()
305
+ return
306
+ }
307
+ }
308
+ t.fail('should load the typescript plugin without compiling it')
309
+ })
310
+
311
+ t.test('should not start the service if it was not precompiled and typescript is `false`', async (t) => {
312
+ const testDir = path.join(urlDirname(import.meta.url), '..', 'fixtures', 'typescript-plugin-nocompile')
313
+ const cwd = path.join(urlDirname(import.meta.url), '..', 'tmp', 'typescript-plugin-clone-10')
314
+
315
+ await cp(testDir, cwd, { recursive: true })
316
+
317
+ const child = execa('node', [cliPath, 'start'], { cwd })
318
+
319
+ const splitter = split()
320
+ child.stdout.pipe(splitter)
321
+ child.stderr.pipe(splitter)
322
+
323
+ for await (const data of splitter) {
324
+ const sanitized = stripAnsi(data)
325
+ if (sanitized.includes('Unknown file extension ".ts" for')) {
326
+ t.pass()
327
+ return
328
+ }
329
+ }
330
+ t.fail('should load the typescript plugin without compiling it')
331
+ })
332
+
333
+ t.test('should compile typescript plugin with string config', async (t) => {
334
+ const testDir = path.join(urlDirname(import.meta.url), '..', 'fixtures', 'typescript-plugin-string')
335
+ const cwd = path.join(urlDirname(import.meta.url), '..', 'tmp', 'typescript-plugin-clone-11')
336
+
337
+ await cp(testDir, cwd, { recursive: true })
338
+
339
+ const child = execa('node', [cliPath, 'compile'], { cwd })
340
+
341
+ t.teardown(exitOnTeardown(child))
342
+
343
+ const splitter = split()
344
+ child.stdout.pipe(splitter)
345
+
346
+ for await (const data of splitter) {
347
+ const sanitized = stripAnsi(data)
348
+ if (sanitized.includes('Typescript compilation completed successfully.')) {
349
+ const jsPluginPath = path.join(cwd, 'dist', 'plugin.js')
350
+ try {
351
+ await access(jsPluginPath)
352
+ } catch (err) {
353
+ t.fail(err)
354
+ }
355
+
356
+ t.pass()
357
+ return
358
+ }
359
+ }
360
+ t.fail('should compile typescript plugin with a compile command')
361
+ })
362
+
363
+ t.test('should not start the service if it was not precompiled and typescript is `"false"`', async (t) => {
364
+ const testDir = path.join(urlDirname(import.meta.url), '..', 'fixtures', 'typescript-plugin-nocompile')
365
+ const cwd = path.join(urlDirname(import.meta.url), '..', 'tmp', 'typescript-plugin-clone-12')
366
+
367
+ await cp(testDir, cwd, { recursive: true })
368
+
369
+ const child = execa('node', [cliPath, 'start'], { cwd })
370
+
371
+ const splitter = split()
372
+ child.stdout.pipe(splitter)
373
+ child.stderr.pipe(splitter)
374
+
375
+ for await (const data of splitter) {
376
+ const sanitized = stripAnsi(data)
377
+ if (sanitized.includes('Unknown file extension ".ts" for')) {
378
+ t.pass()
379
+ return
380
+ }
381
+ }
382
+ t.fail('should load the typescript plugin without compiling it')
383
+ })
@@ -60,3 +60,56 @@ test('client is loaded (ts)', async ({ teardown, equal, pass, same }) => {
60
60
  const data = await res.body.json()
61
61
  same(data, { hello: 'world' })
62
62
  })
63
+
64
+ test('client is loaded dependencyless', async ({ teardown, equal, same }) => {
65
+ const app1 = await buildServer(join(__dirname, '..', 'fixtures', 'hello', 'warn-log.service.json'))
66
+
67
+ teardown(async () => {
68
+ await app1.close()
69
+ })
70
+ await app1.start()
71
+
72
+ process.env.PLT_CLIENT_URL = app1.url
73
+
74
+ const app2 = await buildServer(join(__dirname, '..', 'fixtures', 'hello-client-without-deps', 'platformatic.service.json'))
75
+
76
+ teardown(async () => {
77
+ await app2.close()
78
+ })
79
+ await app2.start()
80
+
81
+ const res = await request(`${app2.url}/`)
82
+ equal(res.statusCode, 200, 'status code')
83
+ const data = await res.body.json()
84
+ same(data, { hello: 'world' })
85
+ })
86
+
87
+ test('client is loaded (ts) depencyless', async ({ teardown, equal, pass, same }) => {
88
+ const app1 = await buildServer(join(__dirname, '..', 'fixtures', 'hello', 'warn-log.service.json'))
89
+
90
+ teardown(async () => {
91
+ await app1.close()
92
+ })
93
+ await app1.start()
94
+
95
+ process.env.PLT_CLIENT_URL = app1.url
96
+
97
+ const targetDir = join(__dirname, '..', 'fixtures', 'hello-client-ts-without-deps')
98
+
99
+ try {
100
+ await rmdir(join(targetDir, 'dist'))
101
+ } catch {}
102
+
103
+ await compile(targetDir, { server: { logger: { level: 'warn' } } })
104
+
105
+ const app2 = await buildServer(join(targetDir, 'platformatic.service.json'))
106
+ teardown(async () => {
107
+ await app2.close()
108
+ })
109
+ await app2.start()
110
+
111
+ const res = await request(`${app2.url}/`)
112
+ equal(res.statusCode, 200, 'status code')
113
+ const data = await res.body.json()
114
+ same(data, { hello: 'world' })
115
+ })
@@ -12,5 +12,5 @@
12
12
  "paths": ["plugin.ts"],
13
13
  "typescript": true
14
14
  },
15
- "watch": true
15
+ "watch": false
16
16
  }
@@ -0,0 +1,16 @@
1
+ {
2
+ "server": {
3
+ "logger": {
4
+ "level": "info"
5
+ },
6
+ "hostname": "127.0.0.1",
7
+ "port": "0",
8
+ "pluginTimeout": 60000,
9
+ "keepAliveTimeout": 1
10
+ },
11
+ "plugins": {
12
+ "paths": ["plugin.ts"],
13
+ "typescript": "false"
14
+ },
15
+ "watch": false
16
+ }
@@ -0,0 +1,5 @@
1
+ import { FastifyInstance } from 'fastify'
2
+
3
+ export default async function (app: FastifyInstance) {
4
+ app.log.info('Typescript plugin loaded')
5
+ }
@@ -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,16 @@
1
+ {
2
+ "server": {
3
+ "logger": {
4
+ "level": "info"
5
+ },
6
+ "hostname": "127.0.0.1",
7
+ "port": "0",
8
+ "pluginTimeout": 60000,
9
+ "keepAliveTimeout": 1
10
+ },
11
+ "plugins": {
12
+ "paths": ["plugin.ts"],
13
+ "typescript": "true"
14
+ },
15
+ "watch": false
16
+ }
@@ -0,0 +1,5 @@
1
+ import { FastifyInstance } from 'fastify'
2
+
3
+ export default async function (app: FastifyInstance) {
4
+ app.log.info('Typescript plugin loaded')
5
+ }
@@ -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
+ }