@platformatic/composer 3.4.1 → 3.5.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.
- package/LICENSE +1 -1
- package/config.d.ts +482 -131
- package/eslint.config.js +4 -2
- package/index.d.ts +1 -17
- package/index.js +9 -210
- package/package.json +18 -59
- package/schema.json +2121 -843
- package/scripts/schema.js +12 -0
- package/.c8rc +0 -6
- package/composer.mjs +0 -54
- package/help/create.txt +0 -11
- package/help/help.txt +0 -7
- package/help/openapi schemas fetch.txt +0 -9
- package/help/start.txt +0 -54
- package/index.test-d.ts +0 -23
- package/lib/composer-hook.js +0 -60
- package/lib/create.mjs +0 -84
- package/lib/errors.js +0 -13
- package/lib/generator/README.md +0 -30
- package/lib/generator/composer-generator.d.ts +0 -11
- package/lib/generator/composer-generator.js +0 -128
- package/lib/graphql-fetch.js +0 -85
- package/lib/graphql-generator.js +0 -31
- package/lib/graphql.js +0 -20
- package/lib/openapi-composer.js +0 -81
- package/lib/openapi-config-schema.js +0 -93
- package/lib/openapi-fetch-schemas.mjs +0 -61
- package/lib/openapi-generator.js +0 -167
- package/lib/openapi-load-config.js +0 -31
- package/lib/openapi-modifier.js +0 -137
- package/lib/openapi.js +0 -49
- package/lib/proxy.js +0 -161
- package/lib/root-endpoint/index.js +0 -28
- package/lib/root-endpoint/public/images/dark_mode.svg +0 -3
- package/lib/root-endpoint/public/images/favicon.ico +0 -0
- package/lib/root-endpoint/public/images/light_mode.svg +0 -11
- package/lib/root-endpoint/public/images/platformatic-logo-dark.svg +0 -30
- package/lib/root-endpoint/public/images/platformatic-logo-light.svg +0 -30
- package/lib/root-endpoint/public/images/triangle_dark.svg +0 -3
- package/lib/root-endpoint/public/images/triangle_light.svg +0 -3
- package/lib/root-endpoint/public/index.html +0 -237
- package/lib/schema.js +0 -210
- package/lib/stackable.js +0 -59
- package/lib/upgrade.js +0 -22
- package/lib/utils.js +0 -27
- package/lib/versions/2.0.0.js +0 -11
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFile, writeFile } from 'node:fs/promises'
|
|
4
|
+
import { resolve } from 'node:path'
|
|
5
|
+
|
|
6
|
+
const gatewaySchema = JSON.parse(await readFile(resolve(import.meta.dirname, '../../gateway/schema.json'), 'utf8'))
|
|
7
|
+
gatewaySchema.$id = gatewaySchema.$id.replace('@platformatic/gateway', '@platformatic/composer')
|
|
8
|
+
gatewaySchema.title = gatewaySchema.title.replace('Platformatic Gateway', 'Platformatic Composer')
|
|
9
|
+
gatewaySchema.properties.composer = gatewaySchema.properties.gateway
|
|
10
|
+
delete gatewaySchema.properties.gateway
|
|
11
|
+
|
|
12
|
+
await writeFile(resolve(import.meta.dirname, '../schema.json'), JSON.stringify(gatewaySchema, null, 2), 'utf8')
|
package/.c8rc
DELETED
package/composer.mjs
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
#! /usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { readFile } from 'fs/promises'
|
|
4
|
-
|
|
5
|
-
import commist from 'commist'
|
|
6
|
-
import parseArgs from 'minimist'
|
|
7
|
-
import isMain from 'es-main'
|
|
8
|
-
import helpMe from 'help-me'
|
|
9
|
-
import { join } from 'desm'
|
|
10
|
-
import { start } from '@platformatic/service'
|
|
11
|
-
import { printAndExitLoadConfigError } from '@platformatic/config'
|
|
12
|
-
|
|
13
|
-
import { fetchOpenApiSchemas } from './lib/openapi-fetch-schemas.mjs'
|
|
14
|
-
import { platformaticComposer } from './index.js'
|
|
15
|
-
import { createComposer } from './lib/create.mjs'
|
|
16
|
-
const help = helpMe({
|
|
17
|
-
dir: join(import.meta.url, 'help'),
|
|
18
|
-
// the default
|
|
19
|
-
ext: '.txt',
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const program = commist({ maxDistance: 2 })
|
|
23
|
-
|
|
24
|
-
program.register('start', (argv) => {
|
|
25
|
-
start(platformaticComposer, argv).catch(printAndExitLoadConfigError)
|
|
26
|
-
})
|
|
27
|
-
program.register('openapi schemas fetch', (argv) => {
|
|
28
|
-
return fetchOpenApiSchemas(argv).catch(printAndExitLoadConfigError)
|
|
29
|
-
})
|
|
30
|
-
program.register('create', createComposer)
|
|
31
|
-
|
|
32
|
-
export async function runComposer (argv) {
|
|
33
|
-
const args = parseArgs(argv, {
|
|
34
|
-
alias: {
|
|
35
|
-
v: 'version',
|
|
36
|
-
},
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
if (args.version) {
|
|
40
|
-
console.log('v' + JSON.parse(await readFile(join(import.meta.url, 'package.json'), 'utf-8')).version)
|
|
41
|
-
process.exit(0)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const output = await program.parseAsync(argv)
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
output,
|
|
48
|
-
help,
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if (isMain(import.meta)) {
|
|
53
|
-
await runComposer(process.argv.splice(2))
|
|
54
|
-
}
|
package/help/create.txt
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
Creates a new Platformatic Composer application.
|
|
2
|
-
|
|
3
|
-
Options are
|
|
4
|
-
|
|
5
|
-
* `dir <string>` - the directory where to create the project (Default: `process.cwd() + 'platformatic-composer'`)
|
|
6
|
-
* `port <string>` - the port where the application will listen (Default: `3042`)
|
|
7
|
-
* `hostname <string>` - the hostname where the application will listen (Default: `0.0.0.0`)
|
|
8
|
-
* `git <boolean>` - Init the git repository (Default: `true`)
|
|
9
|
-
* `typescript <boolean>` - Use Typescript (Default: `false`)
|
|
10
|
-
* `install <boolean>` - Run or not `npm install` after creating the files (Default: `true`)
|
|
11
|
-
* `plugin <boolean>` - Creates a sample plugin and tests (Default: `true`)
|
package/help/help.txt
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
Available commands:
|
|
2
|
-
|
|
3
|
-
* `create` - creates a new Platformatic Composer application.
|
|
4
|
-
* `help` - show this help message.
|
|
5
|
-
* `help <command>` - shows more information about a command.
|
|
6
|
-
* `start` - start the server.
|
|
7
|
-
* `openapi schemas fetch` - fetch OpenAPI schemas from services.
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
Fetch OpenAPI schemas from remote services to use in your Platformatic project.
|
|
2
|
-
|
|
3
|
-
``` bash
|
|
4
|
-
$ platformatic composer openapi schemas fetch
|
|
5
|
-
```
|
|
6
|
-
|
|
7
|
-
It will fetch all the schemas from the remote services and store them by path
|
|
8
|
-
set in the `platformatic.json` file. If the path is not set, it will
|
|
9
|
-
skip fetching the schema.
|
package/help/start.txt
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
Start the Platformatic Composer server with the following command:
|
|
2
|
-
|
|
3
|
-
``` bash
|
|
4
|
-
$ platformatic composer start
|
|
5
|
-
```
|
|
6
|
-
|
|
7
|
-
You will need a configuration file. Here is an example to get you started,
|
|
8
|
-
save the following as `platformatic.json`:
|
|
9
|
-
|
|
10
|
-
``` json
|
|
11
|
-
{
|
|
12
|
-
"server": {
|
|
13
|
-
"hostname": "127.0.0.1",
|
|
14
|
-
"port": 0,
|
|
15
|
-
"logger": {
|
|
16
|
-
"level": "info"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"composer": {
|
|
20
|
-
"services": [
|
|
21
|
-
{
|
|
22
|
-
"id": "service1",
|
|
23
|
-
"origin": "http://127.0.0.1:3051",
|
|
24
|
-
"openapi": {
|
|
25
|
-
"url": "/documentation/json"
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"id": "service2",
|
|
30
|
-
"origin": "http://127.0.0.1:3052",
|
|
31
|
-
"openapi": {
|
|
32
|
-
"file": "./schemas/service2.openapi.json"
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
],
|
|
36
|
-
"refreshTimeout": 1000
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
By sending the SIGUSR2 signal, the server can be reloaded.
|
|
42
|
-
|
|
43
|
-
Options:
|
|
44
|
-
|
|
45
|
-
* `-c, --config FILE` - Specify a configuration file to use.
|
|
46
|
-
|
|
47
|
-
If not specified, the configuration will be loaded from any of the following, in the current directory.
|
|
48
|
-
|
|
49
|
-
* `platformatic.json`, or
|
|
50
|
-
* `platformatic.yml`, or
|
|
51
|
-
* `platformatic.tml`
|
|
52
|
-
|
|
53
|
-
You can find more details about the configuration format here:
|
|
54
|
-
* [Platformatic Composer Configuration](https://docs.platformatic.dev/docs/composer/configuration)
|
package/index.test-d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { buildServer, PlatformaticApp, PlatformaticComposerConfig } from '.'
|
|
2
|
-
import ConfigManager from '@platformatic/config'
|
|
3
|
-
import { expectType } from 'tsd'
|
|
4
|
-
|
|
5
|
-
declare module 'fastify' {
|
|
6
|
-
interface FastifyInstance {
|
|
7
|
-
platformatic: PlatformaticApp<PlatformaticComposerConfig>
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async function main (): Promise<void> {
|
|
12
|
-
// TODO this configuration is incomplete, type it fully
|
|
13
|
-
const server = await buildServer({
|
|
14
|
-
server: {
|
|
15
|
-
port: 3042,
|
|
16
|
-
host: '127.0.0.1'
|
|
17
|
-
}
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
expectType<ConfigManager<PlatformaticComposerConfig>>(server.platformatic.configManager)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
main().catch(console.error)
|
package/lib/composer-hook.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const deepClone = require('rfdc')()
|
|
4
|
-
const fp = require('fastify-plugin')
|
|
5
|
-
const errors = require('./errors')
|
|
6
|
-
|
|
7
|
-
async function composeOpenAPI (app) {
|
|
8
|
-
const onRoutesHooks = {}
|
|
9
|
-
|
|
10
|
-
app.addHook('onRoute', (routeOptions) => {
|
|
11
|
-
if (routeOptions.schema) {
|
|
12
|
-
routeOptions.schema = deepClone(routeOptions.schema)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const method = routeOptions.method
|
|
16
|
-
const openApiPath = routeOptions.config?.openApiPath
|
|
17
|
-
|
|
18
|
-
const onRouteHooks = onRoutesHooks[openApiPath]?.[method]
|
|
19
|
-
if (Array.isArray(onRouteHooks)) {
|
|
20
|
-
for (const onRouteHook of onRouteHooks) {
|
|
21
|
-
onRouteHook(routeOptions)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
let isApplicationReady = false
|
|
27
|
-
app.addHook('onReady', () => {
|
|
28
|
-
isApplicationReady = true
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
function addComposerOnRouteHook (openApiPath, methods, hook) {
|
|
32
|
-
/* c8 ignore next 5 */
|
|
33
|
-
if (isApplicationReady) {
|
|
34
|
-
throw new errors.FastifyInstanceIsAlreadyListeningError()
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (onRoutesHooks[openApiPath] === undefined) {
|
|
38
|
-
onRoutesHooks[openApiPath] = {}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const routeHooks = onRoutesHooks[openApiPath]
|
|
42
|
-
|
|
43
|
-
for (let method of methods) {
|
|
44
|
-
method = method.toUpperCase()
|
|
45
|
-
|
|
46
|
-
if (routeHooks[method] === undefined) {
|
|
47
|
-
routeHooks[method] = []
|
|
48
|
-
}
|
|
49
|
-
routeHooks[method].push(hook)
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
Object.defineProperty(app.platformatic, 'addComposerOnRouteHook', {
|
|
54
|
-
value: addComposerOnRouteHook,
|
|
55
|
-
writable: false,
|
|
56
|
-
configurable: false,
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
module.exports = fp(composeOpenAPI)
|
package/lib/create.mjs
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
import minimist from 'minimist'
|
|
3
|
-
import { Generator } from './generator/composer-generator.js'
|
|
4
|
-
import { join } from 'node:path'
|
|
5
|
-
import { getPkgManager } from '@platformatic/utils'
|
|
6
|
-
import { execa } from 'execa'
|
|
7
|
-
import ora from 'ora'
|
|
8
|
-
import { Table } from 'console-table-printer'
|
|
9
|
-
import pino from 'pino'
|
|
10
|
-
import pinoPretty from 'pino-pretty'
|
|
11
|
-
|
|
12
|
-
function printAppSummary (args, logger) {
|
|
13
|
-
logger.info('Creating a Platformatic Composer app with this config: ')
|
|
14
|
-
const table = [
|
|
15
|
-
{ config: 'Directory', value: args.dir },
|
|
16
|
-
{ config: 'Language', value: args.typescript ? 'Typescript' : 'Javascript' },
|
|
17
|
-
{ config: 'Init Git Repository', value: args.git },
|
|
18
|
-
{ config: 'Install Dependencies', value: args.install },
|
|
19
|
-
]
|
|
20
|
-
|
|
21
|
-
const p = new Table({
|
|
22
|
-
columns: [
|
|
23
|
-
{ name: 'config', alignment: 'right' },
|
|
24
|
-
{ name: 'value', alignment: 'left' },
|
|
25
|
-
],
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
p.addRows(table)
|
|
29
|
-
p.printTable()
|
|
30
|
-
}
|
|
31
|
-
async function createComposer (_args) {
|
|
32
|
-
const stream = pinoPretty({
|
|
33
|
-
translateTime: 'SYS:HH:MM:ss',
|
|
34
|
-
ignore: 'hostname,pid',
|
|
35
|
-
minimumLevel: 'debug',
|
|
36
|
-
sync: true,
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
const logger = pino(stream)
|
|
40
|
-
|
|
41
|
-
const args = minimist(process.argv.slice(2), {
|
|
42
|
-
string: ['dir', 'port', 'hostname', 'git'],
|
|
43
|
-
boolean: ['typescript', 'install'],
|
|
44
|
-
default: {
|
|
45
|
-
dir: join(process.cwd(), 'platformatic-composer'),
|
|
46
|
-
port: 3042,
|
|
47
|
-
hostname: '0.0.0.0',
|
|
48
|
-
plugin: true,
|
|
49
|
-
typescript: false,
|
|
50
|
-
git: false,
|
|
51
|
-
install: true,
|
|
52
|
-
},
|
|
53
|
-
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
printAppSummary(args, logger)
|
|
57
|
-
|
|
58
|
-
const gen = new Generator({})
|
|
59
|
-
gen.setConfig({
|
|
60
|
-
port: args.port,
|
|
61
|
-
hostname: args.hostname,
|
|
62
|
-
plugin: args.plugin,
|
|
63
|
-
tests: args.plugin,
|
|
64
|
-
typescript: args.typescript,
|
|
65
|
-
initGitRepository: args.git,
|
|
66
|
-
targetDirectory: args.dir,
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
try {
|
|
70
|
-
await gen.run()
|
|
71
|
-
if (args.install) {
|
|
72
|
-
const pkgManager = getPkgManager()
|
|
73
|
-
const spinner = ora('Installing dependencies...').start()
|
|
74
|
-
await execa(pkgManager, ['install'], { cwd: args.dir })
|
|
75
|
-
spinner.succeed()
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
logger.info('Done! 🎉')
|
|
79
|
-
} catch (err) {
|
|
80
|
-
logger.error(err.message)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export { createComposer }
|
package/lib/errors.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const createError = require('@fastify/error')
|
|
4
|
-
|
|
5
|
-
const ERROR_PREFIX = 'PLT_COMPOSER'
|
|
6
|
-
|
|
7
|
-
module.exports = {
|
|
8
|
-
FastifyInstanceIsAlreadyListeningError: createError(`${ERROR_PREFIX}_FASTIFY_INSTANCE_IS_ALREADY_LISTENING`, 'Fastify instance is already listening. Cannot call "addComposerOnRouteHook"!'),
|
|
9
|
-
FailedToFetchOpenAPISchemaError: createError(`${ERROR_PREFIX}_FAILED_TO_FETCH_OPENAPI_SCHEMA`, 'Failed to fetch OpenAPI schema from %s'),
|
|
10
|
-
ValidationErrors: createError(`${ERROR_PREFIX}_VALIDATION_ERRORS`, 'Validation errors: %s'),
|
|
11
|
-
PathAlreadyExistsError: createError(`${ERROR_PREFIX}_PATH_ALREADY_EXISTS`, 'Path "%s" already exists'),
|
|
12
|
-
CouldNotReadOpenAPIConfigError: createError(`${ERROR_PREFIX}_COULD_NOT_READ_OPENAPI_CONFIG`, 'Could not read openapi config for "%s" service'),
|
|
13
|
-
}
|
package/lib/generator/README.md
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# Platformatic Composer API
|
|
2
|
-
|
|
3
|
-
This is a generated [Platformatic Composer](https://docs.platformatic.dev/docs/composer/overview) application.
|
|
4
|
-
|
|
5
|
-
## Requirements
|
|
6
|
-
|
|
7
|
-
Platformatic supports macOS, Linux and Windows ([WSL](https://docs.microsoft.com/windows/wsl/) recommended).
|
|
8
|
-
You'll need to have [Node.js](https://nodejs.org/) >= v18.8.0 or >= v20.6.0
|
|
9
|
-
|
|
10
|
-
## Setup
|
|
11
|
-
|
|
12
|
-
1. Install dependencies:
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
npm install
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Usage
|
|
19
|
-
|
|
20
|
-
Run the API with:
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npm start
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
### Explore
|
|
27
|
-
- ⚡ The Platformatic Composer server is running at http://localhost:3042/
|
|
28
|
-
- 📔 View the REST API's Swagger documentation at http://localhost:3042/documentation/
|
|
29
|
-
|
|
30
|
-
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { BaseGenerator } from "@platformatic/generators";
|
|
2
|
-
import RuntimeGenerator from "../../../runtime/lib/generator/runtime-generator";
|
|
3
|
-
|
|
4
|
-
export namespace ComposerGenerator {
|
|
5
|
-
export class ComposerGenerator extends BaseGenerator {
|
|
6
|
-
runtime: RuntimeGenerator
|
|
7
|
-
|
|
8
|
-
setRuntime(runtime: RuntimeGenerator): void
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { BaseGenerator } = require('@platformatic/generators')
|
|
4
|
-
const { join } = require('node:path')
|
|
5
|
-
const { readFile } = require('node:fs/promises')
|
|
6
|
-
|
|
7
|
-
class ComposerGenerator extends BaseGenerator {
|
|
8
|
-
constructor (opts) {
|
|
9
|
-
super({
|
|
10
|
-
...opts,
|
|
11
|
-
module: '@platformatic/composer',
|
|
12
|
-
})
|
|
13
|
-
this.runtime = null
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
getDefaultConfig () {
|
|
17
|
-
const defaultBaseConfig = super.getDefaultConfig()
|
|
18
|
-
return {
|
|
19
|
-
...defaultBaseConfig,
|
|
20
|
-
plugin: false,
|
|
21
|
-
routes: false,
|
|
22
|
-
tests: false,
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async _getConfigFileContents () {
|
|
27
|
-
const template = {
|
|
28
|
-
$schema: `https://schemas.platformatic.dev/@platformatic/composer/${this.platformaticVersion}.json`,
|
|
29
|
-
composer: {
|
|
30
|
-
services: [
|
|
31
|
-
{
|
|
32
|
-
id: 'example',
|
|
33
|
-
origin: `{${this.getEnvVarName('PLT_EXAMPLE_ORIGIN')}}`,
|
|
34
|
-
openapi: {
|
|
35
|
-
url: '/documentation/json',
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
refreshTimeout: 1000,
|
|
40
|
-
},
|
|
41
|
-
watch: true,
|
|
42
|
-
}
|
|
43
|
-
if (this.runtime !== null) {
|
|
44
|
-
template.composer.services = this.runtime.services
|
|
45
|
-
.filter(serviceMeta => serviceMeta.service.module !== '@platformatic/composer')
|
|
46
|
-
.map((serviceMeta) => {
|
|
47
|
-
return {
|
|
48
|
-
id: serviceMeta.name,
|
|
49
|
-
openapi: {
|
|
50
|
-
url: '/documentation/json',
|
|
51
|
-
prefix: `/${serviceMeta.name}`,
|
|
52
|
-
},
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (this.config.plugin) {
|
|
58
|
-
template.plugins = {
|
|
59
|
-
paths: [
|
|
60
|
-
{
|
|
61
|
-
path: './plugins',
|
|
62
|
-
encapsulate: false,
|
|
63
|
-
},
|
|
64
|
-
'./routes',
|
|
65
|
-
],
|
|
66
|
-
typescript: `{${this.getEnvVarName('PLT_TYPESCRIPT')}}`,
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (!this.config.isRuntimeContext) {
|
|
71
|
-
template.server = {
|
|
72
|
-
hostname: '{PLT_SERVER_HOSTNAME}',
|
|
73
|
-
port: '{PORT}',
|
|
74
|
-
logger: {
|
|
75
|
-
level: '{PLT_SERVER_LOGGER_LEVEL}',
|
|
76
|
-
},
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return template
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async _beforePrepare () {
|
|
84
|
-
if (!this.config.isUpdating) {
|
|
85
|
-
if (!this.config.isRuntimeContext) {
|
|
86
|
-
this.addEnvVars({
|
|
87
|
-
PLT_SERVER_HOSTNAME: this.config.hostname,
|
|
88
|
-
PLT_SERVER_LOGGER_LEVEL: 'info',
|
|
89
|
-
PORT: 3042,
|
|
90
|
-
}, { overwrite: false, default: true })
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
this.addEnvVars({
|
|
94
|
-
PLT_TYPESCRIPT: this.config.typescript,
|
|
95
|
-
PLT_EXAMPLE_ORIGIN: 'http://127.0.0.1:3043',
|
|
96
|
-
}, { overwrite: false, default: true })
|
|
97
|
-
|
|
98
|
-
this.config.dependencies = {
|
|
99
|
-
'@platformatic/composer': `^${this.platformaticVersion}`,
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
async _afterPrepare () {
|
|
105
|
-
if (!this.config.isUpdating) {
|
|
106
|
-
const GLOBAL_TYPES_TEMPLATE = `
|
|
107
|
-
import { FastifyInstance } from 'fastify'
|
|
108
|
-
import { PlatformaticApp, PlatformaticComposerConfig } from '@platformatic/composer'
|
|
109
|
-
|
|
110
|
-
declare module 'fastify' {
|
|
111
|
-
interface FastifyInstance {
|
|
112
|
-
platformatic: PlatformaticApp<PlatformaticComposerConfig>
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
`
|
|
116
|
-
this.addFile({ path: '', file: 'global.d.ts', contents: GLOBAL_TYPES_TEMPLATE })
|
|
117
|
-
this.addFile({ path: '', file: 'README.md', contents: await readFile(join(__dirname, 'README.md'), 'utf-8') })
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
setRuntime (runtime) {
|
|
122
|
-
this.runtime = runtime
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
module.exports = ComposerGenerator
|
|
127
|
-
module.exports.ComposerGenerator = ComposerGenerator
|
|
128
|
-
module.exports.Generator = ComposerGenerator
|
package/lib/graphql-fetch.js
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { compose } = require('@platformatic/graphql-composer')
|
|
4
|
-
|
|
5
|
-
const placeholderSdl = 'Query { _info: String }'
|
|
6
|
-
const placeholderResolvers = { Query: { _info: 'platformatic composer' } }
|
|
7
|
-
|
|
8
|
-
function createSupergraph ({ sdl = null, resolvers = {} } = {}) {
|
|
9
|
-
// in case of temporary failures of subgraphs on watching, the service can restart if no subgraphs are (tempoary) available
|
|
10
|
-
if (!sdl) {
|
|
11
|
-
return {
|
|
12
|
-
sdl: placeholderSdl,
|
|
13
|
-
resolvers: placeholderResolvers,
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
return { sdl, resolvers }
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function isSameGraphqlSchema (a, b) {
|
|
20
|
-
// TODO review
|
|
21
|
-
return a?.sdl === b?.sdl
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function serviceToSubgraphConfig (service) {
|
|
25
|
-
if (!service.graphql) { return }
|
|
26
|
-
return {
|
|
27
|
-
name: service.graphql.name || service.id || service.origin,
|
|
28
|
-
entities: service.graphql.entities,
|
|
29
|
-
server: {
|
|
30
|
-
host: service.graphql.host || service.origin,
|
|
31
|
-
composeEndpoint: service.graphql.composeEndpoint,
|
|
32
|
-
graphqlEndpoint: service.graphql.graphqlEndpoint,
|
|
33
|
-
},
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async function fetchGraphqlSubgraphs (services, options, app) {
|
|
38
|
-
const subgraphs = services.map(serviceToSubgraphConfig).filter(s => !!s)
|
|
39
|
-
const composer = await compose({ ...toComposerOptions(options, app), subgraphs })
|
|
40
|
-
|
|
41
|
-
return createSupergraph({
|
|
42
|
-
logger: app.log,
|
|
43
|
-
sdl: composer.toSdl(),
|
|
44
|
-
resolvers: composer.resolvers,
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// TODO support subscriptions
|
|
49
|
-
// const defaultSubscriptionsOptions = {
|
|
50
|
-
// onError: function onComposerSubscriptionsError (ctx, topic, err) {
|
|
51
|
-
// // TODO log.error({err})
|
|
52
|
-
// throw err
|
|
53
|
-
// },
|
|
54
|
-
// publish (ctx, topic, payload) {
|
|
55
|
-
// ctx.pubsub.publish({ topic, payload })
|
|
56
|
-
// },
|
|
57
|
-
// subscribe (ctx, topic) {
|
|
58
|
-
// return ctx.pubsub.subscribe(topic)
|
|
59
|
-
// },
|
|
60
|
-
// unsubscribe (ctx, topic) {
|
|
61
|
-
// ctx.pubsub.close()
|
|
62
|
-
// }
|
|
63
|
-
// }
|
|
64
|
-
|
|
65
|
-
function toComposerOptions (options, app) {
|
|
66
|
-
return {
|
|
67
|
-
logger: app.log,
|
|
68
|
-
defaultArgsAdapter: options?.defaultArgsAdapter,
|
|
69
|
-
addEntitiesResolvers: options?.addEntitiesResolvers,
|
|
70
|
-
entities: options?.entities,
|
|
71
|
-
onSubgraphError: (err, subgraphName) => {
|
|
72
|
-
app.log.error({ err }, 'graphql composer error on subgraph ' + subgraphName)
|
|
73
|
-
|
|
74
|
-
if (options?.onSubgraphError) {
|
|
75
|
-
try {
|
|
76
|
-
options.onSubgraphError(err, subgraphName)
|
|
77
|
-
} catch (err) {
|
|
78
|
-
app.log.error({ err }, 'running onSubgraphError')
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
module.exports = { fetchGraphqlSubgraphs, createSupergraph, isSameGraphqlSchema, serviceToSubgraphConfig }
|
package/lib/graphql-generator.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const fp = require('fastify-plugin')
|
|
4
|
-
const mercurius = require('mercurius')
|
|
5
|
-
const { fetchGraphqlSubgraphs } = require('./graphql-fetch')
|
|
6
|
-
|
|
7
|
-
async function composeGraphql (app, opts) {
|
|
8
|
-
if (!opts.services.some(s => s.graphql)) { return }
|
|
9
|
-
|
|
10
|
-
const services = []
|
|
11
|
-
|
|
12
|
-
for (const service of opts.services) {
|
|
13
|
-
if (!service.graphql) { continue }
|
|
14
|
-
services.push(service)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const graphqlConfig = {
|
|
18
|
-
graphiql: opts.graphql?.graphiql,
|
|
19
|
-
}
|
|
20
|
-
if (services.length > 0) {
|
|
21
|
-
const graphqlSupergraph = await fetchGraphqlSubgraphs(services, opts.graphql, app)
|
|
22
|
-
graphqlConfig.schema = graphqlSupergraph.sdl
|
|
23
|
-
graphqlConfig.resolvers = graphqlSupergraph.resolvers
|
|
24
|
-
graphqlConfig.subscription = false // TODO support subscriptions, will be !!opts.graphql.subscriptions
|
|
25
|
-
app.graphqlSupergraph = graphqlSupergraph
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
await app.register(mercurius, graphqlConfig)
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
module.exports = fp(composeGraphql)
|
package/lib/graphql.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const fp = require('fastify-plugin')
|
|
4
|
-
const { createSupergraph } = require('./graphql-fetch')
|
|
5
|
-
|
|
6
|
-
const graphqlSupergraphSymbol = Symbol('graphqlSupergraph')
|
|
7
|
-
|
|
8
|
-
async function composeGraphql (app, opts) {
|
|
9
|
-
app.decorate('graphqlSupergraph', {
|
|
10
|
-
getter () { return this[graphqlSupergraphSymbol] },
|
|
11
|
-
setter (v) { this[graphqlSupergraphSymbol] = v },
|
|
12
|
-
})
|
|
13
|
-
app.decorate('graphqlComposerOptions', {
|
|
14
|
-
getter () { return opts },
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
app.graphqlSupergraph = createSupergraph()
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
module.exports = fp(composeGraphql)
|