@platformatic/composer 2.74.3 → 3.0.0-alpha.2

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 (58) hide show
  1. package/config.d.ts +2 -30
  2. package/eslint.config.js +11 -2
  3. package/index.d.ts +58 -17
  4. package/index.js +29 -212
  5. package/lib/application.js +186 -0
  6. package/lib/commands/index.js +15 -0
  7. package/lib/commands/openapi-fetch-schemas.js +47 -0
  8. package/lib/composer-hook.js +9 -9
  9. package/lib/errors.js +15 -10
  10. package/lib/generator.js +127 -0
  11. package/lib/graphql-fetch.js +44 -46
  12. package/lib/graphql-generator.js +12 -10
  13. package/lib/graphql.js +13 -9
  14. package/lib/{proxy/not-host-constraints.js → not-host-constraints.js} +3 -5
  15. package/lib/openapi-composer.js +39 -41
  16. package/lib/openapi-config-schema.js +26 -30
  17. package/lib/openapi-generator.js +115 -112
  18. package/lib/openapi-load-config.js +14 -14
  19. package/lib/openapi-modifier.js +12 -21
  20. package/lib/openapi-scalar.js +3 -5
  21. package/lib/proxy.js +13 -12
  22. package/lib/{root-endpoint/index.js → root.js} +12 -12
  23. package/lib/schema.js +41 -25
  24. package/lib/stackable.js +29 -39
  25. package/lib/upgrade.js +6 -8
  26. package/lib/utils.js +5 -16
  27. package/lib/versions/2.0.0.js +4 -6
  28. package/lib/versions/3.0.0.js +14 -0
  29. package/package.json +15 -18
  30. package/schema.json +8 -153
  31. package/.c8rc +0 -6
  32. package/composer.mjs +0 -54
  33. package/help/create.txt +0 -11
  34. package/help/help.txt +0 -7
  35. package/help/openapi schemas fetch.txt +0 -9
  36. package/help/start.txt +0 -54
  37. package/index.test-d.ts +0 -23
  38. package/lib/create.mjs +0 -84
  39. package/lib/generator/README.md +0 -30
  40. package/lib/generator/composer-generator.d.ts +0 -11
  41. package/lib/generator/composer-generator.js +0 -128
  42. package/lib/openapi-fetch-schemas.mjs +0 -61
  43. /package/{lib/root-endpoint/public → public}/images/dark_mode.svg +0 -0
  44. /package/{lib/root-endpoint/public → public}/images/ellipse.svg +0 -0
  45. /package/{lib/root-endpoint/public → public}/images/external-link.svg +0 -0
  46. /package/{lib/root-endpoint/public → public}/images/favicon.ico +0 -0
  47. /package/{lib/root-endpoint/public → public}/images/graphiql.svg +0 -0
  48. /package/{lib/root-endpoint/public → public}/images/graphql.svg +0 -0
  49. /package/{lib/root-endpoint/public → public}/images/light_mode.svg +0 -0
  50. /package/{lib/root-endpoint/public → public}/images/openapi.svg +0 -0
  51. /package/{lib/root-endpoint/public → public}/images/platformatic-logo-dark.svg +0 -0
  52. /package/{lib/root-endpoint/public → public}/images/platformatic-logo-light.svg +0 -0
  53. /package/{lib/root-endpoint/public → public}/images/reverse-proxy.svg +0 -0
  54. /package/{lib/root-endpoint/public → public}/images/triangle_dark.svg +0 -0
  55. /package/{lib/root-endpoint/public → public}/images/triangle_light.svg +0 -0
  56. /package/{lib/root-endpoint/public → public}/index.html +0 -0
  57. /package/{lib/root-endpoint/public → public}/index.njk +0 -0
  58. /package/{lib/root-endpoint/public → public}/main.css +0 -0
@@ -1,16 +1,14 @@
1
- 'use strict'
2
-
3
- const { readFile } = require('node:fs/promises')
4
- const { request, getGlobalDispatcher } = require('undici')
5
- const fp = require('fastify-plugin')
6
- const fastifySwagger = require('@fastify/swagger')
7
-
8
- const errors = require('./errors')
9
- const { modifyOpenApiSchema, originPathSymbol } = require('./openapi-modifier')
10
- const composeOpenApi = require('./openapi-composer')
11
- const loadOpenApiConfig = require('./openapi-load-config.js')
12
- const { prefixWithSlash } = require('./utils.js')
13
- const openApiScalar = require('./openapi-scalar')
1
+ import fastifyReplyFrom from '@fastify/reply-from'
2
+ import fastifySwagger from '@fastify/swagger'
3
+ import fp from 'fastify-plugin'
4
+ import { readFile } from 'node:fs/promises'
5
+ import { getGlobalDispatcher, request } from 'undici'
6
+ import { CouldNotReadOpenAPIConfigError } from './errors.js'
7
+ import { composeOpenApi } from './openapi-composer.js'
8
+ import { loadOpenApiConfig } from './openapi-load-config.js'
9
+ import { modifyOpenApiSchema, originPathSymbol } from './openapi-modifier.js'
10
+ import { openApiScalar } from './openapi-scalar.js'
11
+ import { prefixWithSlash } from './utils.js'
14
12
 
15
13
  async function fetchOpenApiSchema (openApiUrl) {
16
14
  const { body } = await request(openApiUrl)
@@ -31,95 +29,35 @@ async function getOpenApiSchema (origin, openapi) {
31
29
  return readOpenApiSchema(openapi.file)
32
30
  }
33
31
 
34
- async function generateComposedOpenApi (app, opts) {
35
- if (!opts.services.some(s => s.openapi)) { return }
36
-
37
- const { services } = opts
38
-
39
- const openApiSchemas = []
40
- const apiByApiRoutes = {}
41
-
42
- for (const { id, origin, openapi } of services) {
43
- if (!openapi) continue
44
-
45
- let openapiConfig = null
46
- if (openapi.config) {
47
- try {
48
- openapiConfig = await loadOpenApiConfig(openapi.config)
49
- } catch (error) {
50
- app.log.error(error)
51
- throw new errors.CouldNotReadOpenAPIConfigError(id)
52
- }
53
- }
54
-
55
- let originSchema = null
56
- try {
57
- originSchema = await getOpenApiSchema(origin, openapi)
58
- } catch (error) {
59
- app.log.error(error, `failed to fetch schema for "${id} service"`)
60
- continue
61
- }
62
-
63
- const schema = modifyOpenApiSchema(app, originSchema, openapiConfig)
64
-
65
- const prefix = openapi.prefix ? prefixWithSlash(openapi.prefix) : ''
66
- for (const path in schema.paths) {
67
- apiByApiRoutes[prefix + path] = {
68
- origin,
69
- prefix,
70
- schema: schema.paths[path],
71
- }
72
- }
73
-
74
- openApiSchemas.push({ id, prefix, schema, originSchema, config: openapiConfig })
32
+ function createPathMapper (originOpenApiPath, renamedOpenApiPath, prefix) {
33
+ if (prefix + originOpenApiPath === renamedOpenApiPath) {
34
+ return path => path.slice(prefix.length)
75
35
  }
76
36
 
77
- const composedOpenApiSchema = composeOpenApi(openApiSchemas, opts.openapi)
78
-
79
- app.decorate('openApiSchemas', openApiSchemas)
80
- app.decorate('composedOpenApiSchema', composedOpenApiSchema)
81
-
82
- await app.register(fastifySwagger, {
83
- exposeRoute: true,
84
- openapi: {
85
- info: {
86
- title: opts.openapi?.title || 'Platformatic Composer',
87
- version: opts.openapi?.version || '1.0.0'
88
- },
89
- servers: [{ url: globalThis.platformatic?.runtimeBasePath ?? '/' }],
90
- components: app.composedOpenApiSchema.components
91
- },
92
- transform ({ schema, url }) {
93
- for (const service of opts.services) {
94
- if (!service.proxy) continue
95
-
96
- const prefix = service.proxy.prefix ?? ''
97
- const proxyPrefix = prefix.at(-1) === '/' ? prefix.slice(0, -1) : prefix
98
-
99
- const proxyUrls = [proxyPrefix + '/', proxyPrefix + '/*']
100
- if (proxyUrls.includes(url)) {
101
- schema = schema ?? {}
102
- schema.hide = true
103
- break
104
- }
105
- }
106
- return { schema, url }
107
- }
108
- })
37
+ const extractParamsRegexp = generateRouteRegex(renamedOpenApiPath)
38
+ return path => {
39
+ const routeParams = path.match(extractParamsRegexp).slice(1)
40
+ return generateRenamedPath(originOpenApiPath, routeParams)
41
+ }
42
+ }
109
43
 
110
- await app.register(openApiScalar, opts)
44
+ function generateRouteRegex (route) {
45
+ const regex = route.replace(/{(.*?)}/g, '(.*)')
46
+ return new RegExp(regex)
47
+ }
111
48
 
112
- return { apiByApiRoutes }
49
+ function generateRenamedPath (renamedOpenApiPath, routeParams) {
50
+ return renamedOpenApiPath.replace(/{(.*?)}/g, () => routeParams.shift())
113
51
  }
114
52
 
115
- async function openApiComposer (app, { opts, generated }) {
53
+ async function openApiComposerPlugin (app, { opts, generated }) {
116
54
  const { apiByApiRoutes } = generated
117
55
 
118
56
  const dispatcher = getGlobalDispatcher()
119
57
 
120
- await app.register(require('@fastify/reply-from'), {
58
+ await app.register(fastifyReplyFrom, {
121
59
  undici: dispatcher,
122
- destroyAgent: false,
60
+ destroyAgent: false
123
61
  })
124
62
 
125
63
  await app.register(await import('@platformatic/fastify-openapi-glue'), {
@@ -152,7 +90,11 @@ async function openApiComposer (app, { opts, generated }) {
152
90
  const rewriteRequestHeaders = (request, headers) => {
153
91
  const targetUrl = `${origin}${request.url}`
154
92
  const context = request.span?.context
155
- const { span, telemetryHeaders } = app.openTelemetry?.startHTTPSpanClient(targetUrl, request.method, context) || { span: null, telemetryHeaders: {} }
93
+ const { span, telemetryHeaders } = app.openTelemetry?.startHTTPSpanClient(
94
+ targetUrl,
95
+ request.method,
96
+ context
97
+ ) || { span: null, telemetryHeaders: {} }
156
98
  // We need to store the span in a different object
157
99
  // to correctly close it in the onResponse hook
158
100
  // Note that we have 2 spans:
@@ -164,7 +106,7 @@ async function openApiComposer (app, { opts, generated }) {
164
106
  ...headers,
165
107
  ...telemetryHeaders,
166
108
  'x-forwarded-for': request.ip,
167
- 'x-forwarded-host': request.host,
109
+ 'x-forwarded-host': request.host
168
110
  }
169
111
 
170
112
  return headers
@@ -173,38 +115,99 @@ async function openApiComposer (app, { opts, generated }) {
173
115
  replyOptions.rewriteRequestHeaders = rewriteRequestHeaders
174
116
 
175
117
  reply.from(origin + newRoutePath, replyOptions)
176
- },
118
+ }
177
119
  }
178
- },
120
+ }
179
121
  })
180
122
 
181
- app.addHook('preValidation', async (req) => {
123
+ app.addHook('preValidation', async req => {
182
124
  if (typeof req.query.fields === 'string') {
183
125
  req.query.fields = req.query.fields.split(',')
184
126
  }
185
127
  })
186
128
  }
187
129
 
188
- function createPathMapper (originOpenApiPath, renamedOpenApiPath, prefix) {
189
- if (prefix + originOpenApiPath === renamedOpenApiPath) {
190
- return (path) => path.slice(prefix.length)
130
+ export async function openApiGenerator (app, opts) {
131
+ if (!opts.services.some(s => s.openapi)) {
132
+ return
191
133
  }
192
134
 
193
- const extractParamsRegexp = generateRouteRegex(renamedOpenApiPath)
194
- return (path) => {
195
- const routeParams = path.match(extractParamsRegexp).slice(1)
196
- return generateRenamedPath(originOpenApiPath, routeParams)
135
+ const { services } = opts
136
+
137
+ const openApiSchemas = []
138
+ const apiByApiRoutes = {}
139
+
140
+ for (const { id, origin, openapi } of services) {
141
+ if (!openapi) continue
142
+
143
+ let openapiConfig = null
144
+ if (openapi.config) {
145
+ try {
146
+ openapiConfig = await loadOpenApiConfig(openapi.config)
147
+ } catch (error) {
148
+ app.log.error(error)
149
+ throw new CouldNotReadOpenAPIConfigError(id)
150
+ }
151
+ }
152
+
153
+ let originSchema = null
154
+ try {
155
+ originSchema = await getOpenApiSchema(origin, openapi)
156
+ } catch (error) {
157
+ app.log.error(error, `failed to fetch schema for "${id} service"`)
158
+ continue
159
+ }
160
+
161
+ const schema = modifyOpenApiSchema(app, originSchema, openapiConfig)
162
+
163
+ const prefix = openapi.prefix ? prefixWithSlash(openapi.prefix) : ''
164
+ for (const path in schema.paths) {
165
+ apiByApiRoutes[prefix + path] = {
166
+ origin,
167
+ prefix,
168
+ schema: schema.paths[path]
169
+ }
170
+ }
171
+
172
+ openApiSchemas.push({ id, prefix, schema, originSchema, config: openapiConfig })
197
173
  }
198
- }
199
174
 
200
- function generateRouteRegex (route) {
201
- const regex = route.replace(/{(.*?)}/g, '(.*)')
202
- return new RegExp(regex)
203
- }
175
+ const composedOpenApiSchema = composeOpenApi(openApiSchemas, opts.openapi)
204
176
 
205
- function generateRenamedPath (renamedOpenApiPath, routeParams) {
206
- return renamedOpenApiPath.replace(/{(.*?)}/g, () => routeParams.shift())
177
+ app.decorate('openApiSchemas', openApiSchemas)
178
+ app.decorate('composedOpenApiSchema', composedOpenApiSchema)
179
+
180
+ await app.register(fastifySwagger, {
181
+ exposeRoute: true,
182
+ openapi: {
183
+ info: {
184
+ title: opts.openapi?.title || 'Platformatic Composer',
185
+ version: opts.openapi?.version || '1.0.0'
186
+ },
187
+ servers: [{ url: globalThis.platformatic?.runtimeBasePath ?? '/' }],
188
+ components: app.composedOpenApiSchema.components
189
+ },
190
+ transform ({ schema, url }) {
191
+ for (const service of opts.services) {
192
+ if (!service.proxy) continue
193
+
194
+ const prefix = service.proxy.prefix ?? ''
195
+ const proxyPrefix = prefix.at(-1) === '/' ? prefix.slice(0, -1) : prefix
196
+
197
+ const proxyUrls = [proxyPrefix + '/', proxyPrefix + '/*']
198
+ if (proxyUrls.includes(url)) {
199
+ schema = schema ?? {}
200
+ schema.hide = true
201
+ break
202
+ }
203
+ }
204
+ return { schema, url }
205
+ }
206
+ })
207
+
208
+ await app.register(openApiScalar, opts)
209
+
210
+ return { apiByApiRoutes }
207
211
  }
208
212
 
209
- module.exports.openApiGenerator = generateComposedOpenApi
210
- module.exports.openApiComposer = fp(openApiComposer)
213
+ export const openApiComposer = fp(openApiComposerPlugin)
@@ -1,31 +1,31 @@
1
- 'use strict'
2
-
3
- const { readFile } = require('node:fs/promises')
4
- const Ajv = require('ajv')
5
- const openApiConfigSchema = require('./openapi-config-schema')
6
- const errors = require('./errors')
1
+ import Ajv from 'ajv'
2
+ import { readFile } from 'node:fs/promises'
3
+ import { ValidationErrors } from './errors.js'
4
+ import { openApiConfigSchema } from './openapi-config-schema.js'
7
5
 
8
6
  const ajv = new Ajv()
9
7
  const ajvValidate = ajv.compile(openApiConfigSchema)
10
8
 
11
- async function loadOpenApiConfig (pathToConfig) {
9
+ export async function loadOpenApiConfig (pathToConfig) {
12
10
  const openApiConfigFile = await readFile(pathToConfig, 'utf-8')
13
11
  const openApiConfig = JSON.parse(openApiConfigFile)
14
12
 
15
13
  if (!ajvValidate(openApiConfig)) {
16
- const validationErrors = ajvValidate.errors.map((err) => {
14
+ const validationErrors = ajvValidate.errors.map(err => {
17
15
  return {
18
16
  /* c8 ignore next 1 */
19
17
  path: err.instancePath === '' ? '/' : err.instancePath,
20
- message: err.message + ' ' + JSON.stringify(err.params),
18
+ message: err.message + ' ' + JSON.stringify(err.params)
21
19
  }
22
20
  })
23
- throw new errors.ValidationErrors(validationErrors.map((err) => {
24
- return err.message
25
- }).join('\n'))
21
+ throw new ValidationErrors(
22
+ validationErrors
23
+ .map(err => {
24
+ return err.message
25
+ })
26
+ .join('\n')
27
+ )
26
28
  }
27
29
 
28
30
  return openApiConfig
29
31
  }
30
-
31
- module.exports = loadOpenApiConfig
@@ -1,11 +1,12 @@
1
- 'use strict'
1
+ import traverse from 'json-schema-traverse'
2
+ import rfdc from 'rfdc'
2
3
 
3
- const traverse = require('json-schema-traverse')
4
- const clone = require('rfdc')()
4
+ const clone = rfdc()
5
5
 
6
- const originPathSymbol = Symbol('originPath')
7
6
  const MODIFICATION_KEYWORDS = ['rename']
8
7
 
8
+ export const originPathSymbol = Symbol('originPath')
9
+
9
10
  function findDataBySchemaPointer (schemaPointer, schema, data, parentData, callback) {
10
11
  const schemaPointerParts = schemaPointer.split('/').slice(1)
11
12
 
@@ -34,9 +35,7 @@ function getModificationRules (modificationSchema) {
34
35
 
35
36
  function getModificationRules (schema, jsonPointer) {
36
37
  const schemaKeys = Object.keys(schema)
37
- const modificationKeys = schemaKeys.filter(
38
- key => MODIFICATION_KEYWORDS.includes(key)
39
- )
38
+ const modificationKeys = schemaKeys.filter(key => MODIFICATION_KEYWORDS.includes(key))
40
39
 
41
40
  if (modificationKeys.length === 0) return
42
41
  modificationRules[jsonPointer] = schema
@@ -70,22 +69,16 @@ function modifyPayload (payload, originSchema, modificationRules) {
70
69
  for (const schemaJsonPointer in modificationRules) {
71
70
  const rule = modificationRules[schemaJsonPointer]
72
71
 
73
- findDataBySchemaPointer(
74
- schemaJsonPointer,
75
- originSchema,
76
- payload,
77
- null,
78
- (data, parentData) => {
79
- if (rule.rename) {
80
- parentData[rule.rename] = data
81
- delete parentData[schemaJsonPointer.split('/').pop()]
82
- }
72
+ findDataBySchemaPointer(schemaJsonPointer, originSchema, payload, null, (data, parentData) => {
73
+ if (rule.rename) {
74
+ parentData[rule.rename] = data
75
+ delete parentData[schemaJsonPointer.split('/').pop()]
83
76
  }
84
- )
77
+ })
85
78
  }
86
79
  }
87
80
 
88
- function modifyOpenApiSchema (app, schema, config) {
81
+ export function modifyOpenApiSchema (app, schema, config) {
89
82
  const newSchemaPaths = {}
90
83
  const { paths } = clone(schema)
91
84
 
@@ -133,5 +126,3 @@ function modifyOpenApiSchema (app, schema, config) {
133
126
 
134
127
  return { ...schema, paths: newSchemaPaths }
135
128
  }
136
-
137
- module.exports = { modifyOpenApiSchema, originPathSymbol }
@@ -1,8 +1,6 @@
1
- 'use strict'
1
+ import fp from 'fastify-plugin'
2
2
 
3
- const fp = require('fastify-plugin')
4
-
5
- async function openApiScalar (app, opts) {
3
+ async function openApiScalarPlugin (app, opts) {
6
4
  const { default: scalarTheme } = await import('@platformatic/scalar-theme')
7
5
  const { default: scalarApiReference } = await import('@scalar/fastify-api-reference')
8
6
 
@@ -21,4 +19,4 @@ async function openApiScalar (app, opts) {
21
19
  })
22
20
  }
23
21
 
24
- module.exports = fp(openApiScalar)
22
+ export const openApiScalar = fp(openApiScalarPlugin)
package/lib/proxy.js CHANGED
@@ -1,11 +1,10 @@
1
- 'use strict'
2
-
3
- const httpProxy = require('@fastify/http-proxy')
4
- const { ensureLoggableError } = require('@platformatic/utils')
5
- const fp = require('fastify-plugin')
6
- const { workerData } = require('node:worker_threads')
7
- const { getGlobalDispatcher } = require('undici')
8
- const { initMetrics } = require('./metrics')
1
+ import httpProxy from '@fastify/http-proxy'
2
+ import { ensureLoggableError, loadModule } from '@platformatic/foundation'
3
+ import fp from 'fastify-plugin'
4
+ import { createRequire } from 'node:module'
5
+ import { workerData } from 'node:worker_threads'
6
+ import { getGlobalDispatcher } from 'undici'
7
+ import { initMetrics } from './metrics.js'
9
8
 
10
9
  const kITC = Symbol.for('plt.runtime.itc')
11
10
  const kProxyRoute = Symbol('plt.composer.proxy.route')
@@ -36,7 +35,7 @@ async function resolveServiceProxyParameters (service) {
36
35
  }
37
36
 
38
37
  if (service.proxy?.ws?.hooks) {
39
- const hooks = require(service.proxy.ws.hooks.path)
38
+ const hooks = await loadModule(createRequire(import.meta.filename), service.proxy.ws.hooks.path)
40
39
  service.proxy.ws.hooks = hooks
41
40
  }
42
41
 
@@ -55,7 +54,7 @@ async function resolveServiceProxyParameters (service) {
55
54
 
56
55
  let metrics
57
56
 
58
- module.exports = fp(async function (app, opts) {
57
+ async function proxyPlugin (app, opts) {
59
58
  const meta = { proxies: {} }
60
59
  const hostnameLessProxies = []
61
60
 
@@ -260,5 +259,7 @@ module.exports = fp(async function (app, opts) {
260
259
  await app.register(httpProxy, options)
261
260
  }
262
261
 
263
- opts.context?.stackable?.registerMeta(meta)
264
- })
262
+ opts.stackable?.registerMeta(meta)
263
+ }
264
+
265
+ export const proxy = fp(proxyPlugin)
@@ -1,18 +1,18 @@
1
- 'use strict'
1
+ import fastifyStatic from '@fastify/static'
2
+ import fastifyView from '@fastify/view'
3
+ import userAgentParser from 'my-ua-parser'
4
+ import { join } from 'node:path'
5
+ import nunjucks from 'nunjucks'
2
6
 
3
- const { join } = require('node:path')
4
- const fastifyStatic = require('@fastify/static')
5
- const userAgentParser = require('my-ua-parser')
6
-
7
- module.exports = async (app, opts) => {
7
+ export default function root (app) {
8
8
  app.register(fastifyStatic, {
9
- root: join(__dirname, 'public'),
9
+ root: join(import.meta.dirname, '../public')
10
10
  })
11
- app.register(require('@fastify/view'), {
11
+ app.register(fastifyView, {
12
12
  engine: {
13
- nunjucks: require('nunjucks')
13
+ nunjucks
14
14
  },
15
- root: join(__dirname, 'public')
15
+ root: join(import.meta.dirname, '../public')
16
16
  })
17
17
  // root endpoint
18
18
  app.route({
@@ -44,7 +44,7 @@ module.exports = async (app, opts) => {
44
44
  }
45
45
  }
46
46
 
47
- app.platformatic.config.composer.services.forEach((s) => {
47
+ app.platformatic.config.composer.services.forEach(s => {
48
48
  if (s.openapi) {
49
49
  hasOpenAPIServices = true
50
50
  serviceTypes.openapi.services.push(s)
@@ -70,6 +70,6 @@ module.exports = async (app, opts) => {
70
70
  }
71
71
  // Load services
72
72
  return { message: 'Welcome to Platformatic! Please visit https://docs.platformatic.dev' }
73
- },
73
+ }
74
74
  })
75
75
  }
package/lib/schema.js CHANGED
@@ -1,13 +1,22 @@
1
1
  #! /usr/bin/env node
2
- 'use strict'
3
2
 
4
- const { metrics, server, plugins, watch, clients, openApiBase, openApiDefs, graphqlBase } =
5
- require('@platformatic/service').schemas
6
- const { schemaComponents } = require('@platformatic/utils')
7
- const telemetry = require('@platformatic/telemetry').schema
8
- const pkg = require('../package.json')
3
+ import { schemaComponents as basicSchemaComponents } from '@platformatic/basic'
4
+ import {
5
+ fastifyServer as server,
6
+ schemaComponents as utilsSchemaComponents,
7
+ watch,
8
+ wrappedRuntime
9
+ } from '@platformatic/foundation'
10
+ import { schemaComponents as serviceSchemaComponents } from '@platformatic/service'
11
+ import { readFileSync } from 'node:fs'
12
+ import { resolve } from 'node:path'
9
13
 
10
- const openApiService = {
14
+ const { $defs, graphqlBase, openApiBase, plugins } = serviceSchemaComponents
15
+
16
+ export const packageJson = JSON.parse(readFileSync(resolve(import.meta.dirname, '../package.json'), 'utf8'))
17
+ export const version = packageJson.version
18
+
19
+ export const openApiService = {
11
20
  type: 'object',
12
21
  properties: {
13
22
  url: { type: 'string' },
@@ -19,7 +28,7 @@ const openApiService = {
19
28
  additionalProperties: false
20
29
  }
21
30
 
22
- const entityResolver = {
31
+ export const entityResolver = {
23
32
  type: 'object',
24
33
  properties: {
25
34
  name: { type: 'string' },
@@ -34,7 +43,7 @@ const entityResolver = {
34
43
  additionalProperties: false
35
44
  }
36
45
 
37
- const entities = {
46
+ export const entities = {
38
47
  type: 'object',
39
48
  patternProperties: {
40
49
  '^.*$': {
@@ -77,7 +86,7 @@ const entities = {
77
86
  }
78
87
  }
79
88
 
80
- const graphqlService = {
89
+ export const graphqlService = {
81
90
  anyOf: [
82
91
  { type: 'boolean' },
83
92
  {
@@ -94,7 +103,7 @@ const graphqlService = {
94
103
  ]
95
104
  }
96
105
 
97
- const graphqlComposerOptions = {
106
+ export const graphqlComposerOptions = {
98
107
  type: 'object',
99
108
  properties: {
100
109
  ...graphqlBase.properties,
@@ -109,7 +118,7 @@ const graphqlComposerOptions = {
109
118
  additionalProperties: false
110
119
  }
111
120
 
112
- const composer = {
121
+ export const composer = {
113
122
  type: 'object',
114
123
  properties: {
115
124
  services: {
@@ -179,7 +188,7 @@ const composer = {
179
188
  additionalProperties: false
180
189
  }
181
190
 
182
- const types = {
191
+ export const types = {
183
192
  type: 'object',
184
193
  properties: {
185
194
  autogenerate: {
@@ -195,10 +204,20 @@ const types = {
195
204
  additionalProperties: false
196
205
  }
197
206
 
198
- const platformaticComposerSchema = {
199
- $id: `https://schemas.platformatic.dev/@platformatic/composer/${pkg.version}.json`,
207
+ export const schemaComponents = {
208
+ openApiService,
209
+ entityResolver,
210
+ entities,
211
+ graphqlService,
212
+ graphqlComposerOptions,
213
+ composer,
214
+ types
215
+ }
216
+
217
+ export const schema = {
218
+ $id: `https://schemas.platformatic.dev/@platformatic/composer/${packageJson.version}.json`,
200
219
  $schema: 'http://json-schema.org/draft-07/schema#',
201
- title: 'Platformatic Composer',
220
+ title: 'Platformatic Composer Config',
202
221
  type: 'object',
203
222
  properties: {
204
223
  basePath: {
@@ -206,12 +225,11 @@ const platformaticComposerSchema = {
206
225
  },
207
226
  server,
208
227
  composer,
209
- metrics,
210
228
  types,
211
229
  plugins,
212
- clients,
213
- runtime: schemaComponents.wrappedRuntime,
214
- telemetry,
230
+ application: basicSchemaComponents.application,
231
+ runtime: wrappedRuntime,
232
+ telemetry: utilsSchemaComponents.telemetry,
215
233
  watch: {
216
234
  anyOf: [
217
235
  watch,
@@ -231,12 +249,10 @@ const platformaticComposerSchema = {
231
249
  }
232
250
  },
233
251
  additionalProperties: false,
234
- $defs: openApiDefs
252
+ $defs
235
253
  }
236
254
 
237
- module.exports.schema = platformaticComposerSchema
238
-
239
255
  /* c8 ignore next 3 */
240
- if (require.main === module) {
241
- console.log(JSON.stringify(platformaticComposerSchema, null, 2))
256
+ if (process.argv[1] === import.meta.filename) {
257
+ console.log(JSON.stringify(schema, null, 2))
242
258
  }