@platformatic/service 0.43.1 → 0.45.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.
package/config.d.ts CHANGED
@@ -108,7 +108,6 @@ export interface PlatformaticService {
108
108
  strictPreflight?: boolean;
109
109
  hideOptionsRoute?: boolean;
110
110
  };
111
- [k: string]: unknown;
112
111
  };
113
112
  plugins?: Plugins;
114
113
  metrics?:
@@ -121,8 +120,10 @@ export interface PlatformaticService {
121
120
  password: string;
122
121
  };
123
122
  };
123
+ telemetry?: OpenTelemetry;
124
124
  watch?:
125
125
  | {
126
+ enabled?: boolean | string;
126
127
  /**
127
128
  * @minItems 1
128
129
  */
@@ -175,6 +176,17 @@ export interface Plugins {
175
176
  path?: string;
176
177
  encapsulate?: boolean;
177
178
  maxDepth?: number;
179
+ autoHooks?: boolean;
180
+ autoHooksPattern?: string;
181
+ cascadeHooks?: boolean;
182
+ overwriteHooks?: boolean;
183
+ routeParams?: boolean;
184
+ forceESM?: boolean;
185
+ ignoreFilter?: string;
186
+ matchFilter?: string;
187
+ ignorePattern?: string;
188
+ scriptPattern?: string;
189
+ indexPattern?: string;
178
190
  options?: {
179
191
  [k: string]: unknown;
180
192
  };
@@ -193,6 +205,73 @@ export interface Plugins {
193
205
  | boolean
194
206
  | string;
195
207
  }
208
+ export interface OpenTelemetry {
209
+ /**
210
+ * The name of the service. Defaults to the folder name if not specified.
211
+ */
212
+ serviceName: string;
213
+ /**
214
+ * The version of the service (optional)
215
+ */
216
+ version?: string;
217
+ /**
218
+ * An array of paths to skip when creating spans. Useful for health checks and other endpoints that do not need to be traced.
219
+ */
220
+ skip?: {
221
+ /**
222
+ * The path to skip. Can be a string or a regex.
223
+ */
224
+ path?: string;
225
+ /**
226
+ * HTTP method to skip
227
+ */
228
+ method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS";
229
+ [k: string]: unknown;
230
+ }[];
231
+ exporter?:
232
+ | {
233
+ type?: "console" | "otlp" | "zipkin" | "memory";
234
+ /**
235
+ * Options for the exporter. These are passed directly to the exporter.
236
+ */
237
+ options?: {
238
+ /**
239
+ * The URL to send the traces to. Not used for console or memory exporters.
240
+ */
241
+ url?: string;
242
+ /**
243
+ * Headers to send to the exporter. Not used for console or memory exporters.
244
+ */
245
+ headers?: {
246
+ [k: string]: unknown;
247
+ };
248
+ [k: string]: unknown;
249
+ };
250
+ additionalProperties?: never;
251
+ [k: string]: unknown;
252
+ }[]
253
+ | {
254
+ type?: "console" | "otlp" | "zipkin" | "memory";
255
+ /**
256
+ * Options for the exporter. These are passed directly to the exporter.
257
+ */
258
+ options?: {
259
+ /**
260
+ * The URL to send the traces to. Not used for console or memory exporters.
261
+ */
262
+ url?: string;
263
+ /**
264
+ * Headers to send to the exporter. Not used for console or memory exporters.
265
+ */
266
+ headers?: {
267
+ [k: string]: unknown;
268
+ };
269
+ [k: string]: unknown;
270
+ };
271
+ additionalProperties?: never;
272
+ [k: string]: unknown;
273
+ };
274
+ }
196
275
  export interface Info {
197
276
  title: string;
198
277
  summary?: string;
@@ -293,7 +372,6 @@ export interface Operation {
293
372
  callbacks?: {
294
373
  [k: string]: CallbacksOrReference;
295
374
  };
296
- deprecated?: boolean;
297
375
  security?: SecurityRequirement[];
298
376
  servers?: Server[];
299
377
  /**
package/index.d.ts CHANGED
@@ -1,18 +1,17 @@
1
1
  /* eslint-disable @typescript-eslint/triple-slash-reference */
2
- /// <reference types="@platformatic/types" />
3
2
  /// <reference types="mercurius" />
4
3
  /// <reference types="@fastify/swagger" />
5
4
  import { FastifyInstance } from 'fastify'
6
5
  import ConfigManager from '@platformatic/config'
7
6
  import { PlatformaticService } from './config'
8
7
 
9
- declare module '@platformatic/types' {
10
- interface PlatformaticApp {
11
- configManager: ConfigManager<PlatformaticService>
12
- config: PlatformaticService
13
- }
8
+ export interface PlatformaticApp<T> {
9
+ configManager: ConfigManager<T>
10
+ config: T
14
11
  }
15
12
 
13
+ export type PlatformaticServiceConfig = PlatformaticService
14
+
16
15
  export function buildServer (opts: object, app?: object, ConfigManagerContructor?: object): Promise<FastifyInstance>
17
16
 
18
17
  declare module 'fastify' {
package/index.test-d.ts CHANGED
@@ -1,11 +1,17 @@
1
1
  import { expectType } from 'tsd'
2
2
  import { FastifyInstance } from 'fastify'
3
- import { buildServer } from '.'
3
+ import { buildServer, PlatformaticApp } from '.'
4
4
  import ConfigManager from '@platformatic/config'
5
5
  import { OpenAPI } from 'openapi-types'
6
6
  import type { MercuriusPlugin } from 'mercurius'
7
7
  import { PlatformaticService } from './config'
8
8
 
9
+ declare module 'fastify' {
10
+ interface FastifyInstance {
11
+ platformatic: PlatformaticApp<PlatformaticService>
12
+ }
13
+ }
14
+
9
15
  const server = await buildServer({
10
16
  })
11
17
 
@@ -0,0 +1,40 @@
1
+ import { join, dirname } from 'path'
2
+ import { createRequire } from 'module'
3
+ import { writeFile } from 'fs/promises'
4
+ import pino from 'pino'
5
+ import pretty from 'pino-pretty'
6
+ import { loadConfig } from '@platformatic/config'
7
+ import { platformaticService } from '../index.js'
8
+ import { checkForDependencies } from '@platformatic/utils'
9
+
10
+ const GLOBAL_TYPES_TEMPLATE = `
11
+ import { FastifyInstance } from 'fastify'
12
+ import { PlatformaticApp, PlatformaticServiceConfig } from '@platformatic/service'
13
+
14
+ declare module 'fastify' {
15
+ interface FastifyInstance {
16
+ platformatic: PlatformaticApp<PlatformaticServiceConfig>
17
+ }
18
+ }
19
+ `
20
+ async function execute ({ logger, configManager }) {
21
+ const fileNameOrThen = join(dirname(configManager.fullPath), 'global.d.ts')
22
+ await writeFile(fileNameOrThen, GLOBAL_TYPES_TEMPLATE)
23
+ }
24
+
25
+ async function generateTypes (_args) {
26
+ const logger = pino(pretty({
27
+ translateTime: 'SYS:HH:MM:ss',
28
+ ignore: 'hostname,pid'
29
+ }))
30
+
31
+ const { configManager, args } = await loadConfig({}, _args, platformaticService)
32
+
33
+ await configManager.parseAndValidate()
34
+ const config = configManager.current
35
+
36
+ await execute({ logger, configManager })
37
+ await checkForDependencies(logger, args, createRequire(import.meta.url), config, ['@platformatic/service'])
38
+ }
39
+
40
+ export { execute, generateTypes }
@@ -290,10 +290,6 @@ const $defs = {
290
290
  $ref: '#/$defs/callbacks-or-reference'
291
291
  }
292
292
  },
293
- deprecated: {
294
- default: false,
295
- type: 'boolean'
296
- },
297
293
  security: {
298
294
  type: 'array',
299
295
  items: {
@@ -347,10 +343,6 @@ const $defs = {
347
343
  default: false,
348
344
  type: 'boolean'
349
345
  },
350
- deprecated: {
351
- default: false,
352
- type: 'boolean'
353
- },
354
346
  content: {
355
347
  type: 'object',
356
348
  $ref: '#/$defs/content',
@@ -712,10 +704,6 @@ const $defs = {
712
704
  default: false,
713
705
  type: 'boolean'
714
706
  },
715
- deprecated: {
716
- default: false,
717
- type: 'boolean'
718
- },
719
707
  content: {
720
708
  type: 'object',
721
709
  $ref: '#/$defs/content',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/service",
3
- "version": "0.43.1",
3
+ "version": "0.45.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -65,12 +65,11 @@
65
65
  "pino-pretty": "^10.0.0",
66
66
  "rfdc": "^1.3.0",
67
67
  "ua-parser-js": "^1.0.35",
68
- "@platformatic/client": "0.43.1",
69
- "@platformatic/config": "0.43.1",
70
- "@platformatic/swagger-ui-theme": "0.43.1",
71
- "@platformatic/types": "0.43.1",
72
- "@platformatic/utils": "0.43.1",
73
- "@platformatic/telemetry": "0.43.1"
68
+ "@platformatic/client": "0.45.0",
69
+ "@platformatic/config": "0.45.0",
70
+ "@platformatic/swagger-ui-theme": "0.45.0",
71
+ "@platformatic/utils": "0.45.0",
72
+ "@platformatic/telemetry": "0.45.0"
74
73
  },
75
74
  "standard": {
76
75
  "ignore": [
package/service.mjs CHANGED
@@ -6,7 +6,9 @@ import isMain from 'es-main'
6
6
  import helpMe from 'help-me'
7
7
  import { readFile } from 'fs/promises'
8
8
  import { join } from 'desm'
9
+ import { printAndExitLoadConfigError } from '@platformatic/config'
9
10
  import { generateJsonSchemaConfig } from './lib/gen-schema.js'
11
+ import { generateTypes } from './lib/gen-types.mjs'
10
12
 
11
13
  import { buildCompileCmd } from './lib/compile.js'
12
14
 
@@ -18,20 +20,30 @@ const help = helpMe({
18
20
  ext: '.txt'
19
21
  })
20
22
 
23
+ function wrapCommand (fn) {
24
+ return async function (...args) {
25
+ try {
26
+ return await fn(...args)
27
+ /* c8 ignore next 3 */
28
+ } catch (err) {
29
+ printAndExitLoadConfigError(err)
30
+ }
31
+ }
32
+ }
33
+
21
34
  const program = commist({ maxDistance: 2 })
22
35
 
23
36
  program.register('help', help.toStdout)
24
37
  program.register('help start', help.toStdout.bind(null, ['start']))
25
38
 
26
39
  program.register('start', (argv) => {
27
- start(platformaticService, argv).catch((err) => {
28
- /* c8 ignore next 2 */
29
- console.error(err)
30
- process.exit(1)
31
- })
40
+ /* c8 ignore next 1 */
41
+ start(platformaticService, argv).catch(printAndExitLoadConfigError)
32
42
  })
43
+
33
44
  program.register('compile', buildCompileCmd(platformaticService))
34
- program.register('schema config', generateJsonSchemaConfig)
45
+ program.register('types', wrapCommand(generateTypes))
46
+ program.register('schema config', wrapCommand(generateJsonSchemaConfig))
35
47
  program.register('schema', help.toStdout.bind(null, ['schema']))
36
48
 
37
49
  export async function runService (argv) {
@@ -9,8 +9,9 @@ import { cliPath, safeKill } from './helper.mjs'
9
9
  import { fileURLToPath } from 'url'
10
10
 
11
11
  let count = 0
12
+ const isWin = os.platform() === 'win32'
12
13
 
13
- if (os.platform() !== 'win32') {
14
+ if (!isWin) {
14
15
  t.jobs = 5
15
16
  }
16
17
  t.setTimeout(360000)
@@ -266,7 +267,7 @@ t.test('should compile typescript plugin with start command with different cwd',
266
267
  t.fail('should compile typescript plugin with start command')
267
268
  })
268
269
 
269
- t.test('valid tsconfig file inside an inner folder', async (t) => {
270
+ t.test('valid tsconfig file inside an inner folder', { skip: isWin }, async (t) => {
270
271
  const testDir = path.join(urlDirname(import.meta.url), '..', 'fixtures', 'typescript-plugin')
271
272
  const cwd = await getCWD(t)
272
273
 
@@ -498,3 +499,34 @@ t.test('should not compile typescript plugin with start without tsconfig', async
498
499
  t.equal(err.stdout.includes('No typescript configuration file was found, skipping compilation.'), true)
499
500
  }
500
501
  })
502
+
503
+ t.test('should compile ts app with config', async (t) => {
504
+ const testDir = path.join(urlDirname(import.meta.url), '..', 'fixtures', 'hello-ts-with-config')
505
+ const cwd = await getCWD(t)
506
+
507
+ await cp(testDir, cwd, { recursive: true })
508
+
509
+ const child = execa('node', [cliPath, 'compile'], { cwd })
510
+
511
+ t.teardown(exitOnTeardown(child))
512
+
513
+ const splitter = split()
514
+ child.stdout.pipe(splitter)
515
+
516
+ for await (const data of splitter) {
517
+ const sanitized = stripAnsi(data)
518
+ if (sanitized.includes('Typescript compilation completed successfully.')) {
519
+ const jsPluginPath = path.join(cwd, 'dist', 'plugin.js')
520
+ try {
521
+ await access(jsPluginPath)
522
+ } catch (err) {
523
+ t.fail(err)
524
+ }
525
+
526
+ t.pass()
527
+ return
528
+ }
529
+ }
530
+
531
+ t.fail('should compile typescript plugin with a compile command')
532
+ })
@@ -0,0 +1,30 @@
1
+ import { cliPath } from './helper.mjs'
2
+ import { test } from 'tap'
3
+ import { join } from 'desm'
4
+ import { execa } from 'execa'
5
+ import { readFile, unlink } from 'fs/promises'
6
+
7
+ const GLOBAL_TYPES_TEMPLATE = `
8
+ import { FastifyInstance } from 'fastify'
9
+ import { PlatformaticApp, PlatformaticServiceConfig } from '@platformatic/service'
10
+
11
+ declare module 'fastify' {
12
+ interface FastifyInstance {
13
+ platformatic: PlatformaticApp<PlatformaticServiceConfig>
14
+ }
15
+ }
16
+ `
17
+
18
+ test('generate global.d.ts', async ({ equal }) => {
19
+ const fileNameOrThen = join(import.meta.url, '..', '..', 'fixtures', 'hello', 'global.d.ts')
20
+ try {
21
+ await unlink(fileNameOrThen)
22
+ } catch {}
23
+
24
+ await execa('node', [cliPath, 'types', '-c', join(import.meta.url, '..', '..', 'fixtures', 'hello', 'platformatic.service.json')])
25
+
26
+ const data = await readFile(fileNameOrThen, 'utf-8')
27
+ await unlink(fileNameOrThen)
28
+
29
+ equal(data, GLOBAL_TYPES_TEMPLATE)
30
+ })
@@ -3,6 +3,7 @@ import { test } from 'tap'
3
3
  import { join } from 'desm'
4
4
  import { readFile } from 'fs/promises'
5
5
  import { execa } from 'execa'
6
+ import stripAnsi from 'strip-ansi'
6
7
 
7
8
  const version = JSON.parse(await readFile(join(import.meta.url, '..', '..', 'package.json'))).version
8
9
 
@@ -21,7 +22,7 @@ test('print validation errors', async ({ equal, plan }) => {
21
22
  await execa('node', [cliPath, 'start', '--config', join(import.meta.url, '..', 'fixtures', 'missing-property.config.json')])
22
23
  } catch (err) {
23
24
  equal(err.exitCode, 1)
24
- equal(err.stdout, `
25
+ equal(stripAnsi(err.stdout), `
25
26
  ┌─────────┬──────┬─────────────────────────────────────────────────────────────────────┐
26
27
  │ (index) │ path │ message │
27
28
  ├─────────┼──────┼─────────────────────────────────────────────────────────────────────┤
@@ -0,0 +1,8 @@
1
+ import { FastifyInstance } from 'fastify'
2
+ import { PlatformaticApp, PlatformaticServiceConfig } from '../../../index'
3
+
4
+ declare module 'fastify' {
5
+ interface FastifyInstance {
6
+ platformatic: PlatformaticApp<PlatformaticServiceConfig>
7
+ }
8
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "server": {
3
+ "hostname": "127.0.0.1",
4
+ "port": 0,
5
+ "logger": {
6
+ "level": "info"
7
+ },
8
+ "pluginTimeout": 30000
9
+ },
10
+ "plugins": {
11
+ "paths": ["./plugin.ts"],
12
+ "typescript": true
13
+ },
14
+ "metrics": false,
15
+ "watch": false
16
+ }
@@ -0,0 +1,8 @@
1
+ /// <reference path="./global.d.ts" />
2
+ import { FastifyInstance } from 'fastify'
3
+
4
+ export default async function (app: FastifyInstance) {
5
+ app.get('/', async () => {
6
+ return app.platformatic.config
7
+ })
8
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "commonjs",
4
+ "esModuleInterop": true,
5
+ "target": "es2020",
6
+ "moduleResolution": "node",
7
+ "sourceMap": false,
8
+ "incremental": true,
9
+ "pretty": true,
10
+ "noEmitOnError": true,
11
+ "outDir": "dist"
12
+ },
13
+ "watchOptions": {
14
+ "watchFile": "fixedPollingInterval",
15
+ "watchDirectory": "fixedPollingInterval",
16
+ "fallbackPolling": "dynamicPriority",
17
+ "synchronousWatchDirectory": true,
18
+ "excludeDirectories": [
19
+ "**/node_modules",
20
+ "dist"
21
+ ]
22
+ }
23
+ }