@platformatic/runtime 1.43.0 → 1.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/fixtures/configs/monorepo-with-dependencies.json +8 -0
- package/fixtures/management-api/services/service-1/platformatic.json +3 -1
- package/fixtures/management-api/services/service-db/migrations/001.do.sql +4 -0
- package/fixtures/management-api/services/service-db/migrations/001.undo.sql +1 -0
- package/fixtures/management-api/services/service-db/package.json +5 -0
- package/fixtures/management-api/services/service-db/platformatic.db.json +29 -0
- package/fixtures/management-api/services/service-db/plugin.js +12 -0
- package/fixtures/monorepo-with-dependencies/main/clients/service-1/package.json +3 -0
- package/fixtures/monorepo-with-dependencies/main/clients/service-1/schema.json +204 -0
- package/fixtures/monorepo-with-dependencies/main/clients/service-2/package.json +3 -0
- package/fixtures/monorepo-with-dependencies/main/clients/service-2/schema.json +204 -0
- package/fixtures/monorepo-with-dependencies/main/external-service.schema.json +204 -0
- package/fixtures/monorepo-with-dependencies/main/platformatic.json +46 -0
- package/fixtures/monorepo-with-dependencies/service-1/clients/service-2/package.json +3 -0
- package/fixtures/monorepo-with-dependencies/service-1/clients/service-2/schema.json +204 -0
- package/fixtures/monorepo-with-dependencies/service-1/external-service.schema.json +204 -0
- package/fixtures/monorepo-with-dependencies/service-1/platformatic.json +29 -0
- package/fixtures/monorepo-with-dependencies/service-2/platformatic.json +15 -0
- package/lib/api.js +11 -1
- package/lib/config.js +73 -116
- package/lib/management-api.js +12 -0
- package/package.json +10 -10
package/lib/config.js
CHANGED
|
@@ -103,135 +103,87 @@ function missingDependencyErrorMessage (clientName, service, configManager) {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
async function parseClientsAndComposer (configManager) {
|
|
106
|
-
for (
|
|
107
|
-
const service = configManager.current.services[i]
|
|
106
|
+
for (const service of configManager.current.services) {
|
|
108
107
|
const cm = new ConfigManager({ source: service.config })
|
|
109
108
|
const configString = await cm.load()
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
if (Array.isArray(parsed.composer?.services)) {
|
|
113
|
-
for (let i = 0; i < parsed.composer.services.length; ++i) {
|
|
114
|
-
const dep = parsed.composer.services[i]
|
|
115
|
-
/* c8 ignore next 4 - why c8? */
|
|
116
|
-
const clientName = dep.id ?? ''
|
|
117
|
-
const dependency = configManager.current.serviceMap.get(clientName)
|
|
118
|
-
|
|
119
|
-
let isLocal = true
|
|
120
|
-
let clientUrl = null
|
|
121
|
-
|
|
122
|
-
if (dep.origin !== undefined) {
|
|
123
|
-
try {
|
|
124
|
-
clientUrl = await cm.replaceEnv(dep.origin)
|
|
125
|
-
isLocal = false
|
|
126
|
-
/* c8 ignore next 4 */
|
|
127
|
-
} catch (err) {
|
|
128
|
-
// The MissingValueError is an error coming from pupa: https://github.com/sindresorhus/pupa#missingvalueerror
|
|
129
|
-
// All other errors are simply rethrown.
|
|
130
|
-
if (err.name !== 'MissingValueError') {
|
|
131
|
-
throw err
|
|
132
|
-
}
|
|
109
|
+
const serviceConfig = cm._parser(configString)
|
|
133
110
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
}
|
|
111
|
+
async function parseConfigUrl (urlString) {
|
|
112
|
+
if (!urlString) {
|
|
113
|
+
return { url: null, envVar: null }
|
|
114
|
+
}
|
|
140
115
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
116
|
+
try {
|
|
117
|
+
const url = await cm.replaceEnv(urlString)
|
|
118
|
+
return { url, envVar: null }
|
|
119
|
+
} catch (err) {
|
|
120
|
+
// The MissingValueError is an error coming from pupa
|
|
121
|
+
// https://github.com/sindresorhus/pupa#missingvalueerror
|
|
122
|
+
// All other errors are simply re-thrown.
|
|
123
|
+
if (err.name !== 'MissingValueError' || urlString !== `{${err.key}}`) {
|
|
124
|
+
throw err
|
|
147
125
|
}
|
|
148
|
-
|
|
149
|
-
service.dependencies.push({
|
|
150
|
-
id: clientName,
|
|
151
|
-
url: clientUrl,
|
|
152
|
-
local: isLocal
|
|
153
|
-
})
|
|
126
|
+
return { url: null, envVar: err.key }
|
|
154
127
|
}
|
|
155
128
|
}
|
|
156
129
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
let missingKey
|
|
164
|
-
let isLocal = false
|
|
130
|
+
async function addServiceDependency (service, dependencyId, urlString) {
|
|
131
|
+
let { url, envVar } = await parseConfigUrl(urlString)
|
|
132
|
+
if (url !== null) {
|
|
133
|
+
service.dependencies.push({ id: dependencyId, url, local: false })
|
|
134
|
+
return
|
|
135
|
+
}
|
|
165
136
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
/* c8 ignore next 3 */
|
|
173
|
-
reject(err)
|
|
174
|
-
return
|
|
175
|
-
}
|
|
137
|
+
const depService = configManager.current.serviceMap.get(dependencyId)
|
|
138
|
+
if (depService === undefined) {
|
|
139
|
+
throw new errors.MissingDependencyError(
|
|
140
|
+
missingDependencyErrorMessage(dependencyId, service, configManager)
|
|
141
|
+
)
|
|
142
|
+
}
|
|
176
143
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
/* c8 ignore next 2 */
|
|
183
|
-
isLocal = true
|
|
184
|
-
}
|
|
144
|
+
url = `http://${dependencyId}.plt.local`
|
|
145
|
+
|
|
146
|
+
if (envVar !== null) {
|
|
147
|
+
service.localServiceEnvVars.set(envVar, url)
|
|
148
|
+
}
|
|
185
149
|
|
|
186
|
-
|
|
187
|
-
|
|
150
|
+
depService.dependents.push(service.id)
|
|
151
|
+
service.dependencies.push({ id: dependencyId, url, local: true })
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const composedServices = serviceConfig.composer?.services
|
|
155
|
+
if (Array.isArray(composedServices)) {
|
|
156
|
+
await Promise.all(
|
|
157
|
+
composedServices.map(async (composedService) =>
|
|
158
|
+
addServiceDependency(
|
|
159
|
+
service,
|
|
160
|
+
composedService.id,
|
|
161
|
+
composedService.origin
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (Array.isArray(serviceConfig.clients)) {
|
|
168
|
+
await Promise.all(
|
|
169
|
+
serviceConfig.clients.map(async (client) => {
|
|
170
|
+
let clientServiceId = client.serviceId
|
|
171
|
+
if (!clientServiceId) {
|
|
188
172
|
try {
|
|
189
|
-
const
|
|
190
|
-
const
|
|
191
|
-
const
|
|
192
|
-
|
|
173
|
+
const clientPath = pathResolve(service.path, client.path)
|
|
174
|
+
const clientPackageJsonPath = join(clientPath, 'package.json')
|
|
175
|
+
const clientPackageJSONFile = await readFile(clientPackageJsonPath, 'utf8')
|
|
176
|
+
const clientPackageJSON = JSON.parse(clientPackageJSONFile)
|
|
177
|
+
clientServiceId = clientPackageJSON.name ?? ''
|
|
193
178
|
} catch (err) {
|
|
194
|
-
if (client.url
|
|
195
|
-
|
|
196
|
-
resolve()
|
|
197
|
-
} else {
|
|
198
|
-
reject(err)
|
|
179
|
+
if (client.url === undefined || client.name === undefined) {
|
|
180
|
+
throw err
|
|
199
181
|
}
|
|
200
|
-
return
|
|
201
182
|
}
|
|
202
183
|
}
|
|
203
|
-
|
|
204
|
-
if (clientUrl === undefined) {
|
|
205
|
-
// Combine the service name with the client name to avoid collisions
|
|
206
|
-
// if two or more services have a client with the same name pointing
|
|
207
|
-
// to different services.
|
|
208
|
-
clientUrl = isLocal ? `http://${clientName}.plt.local` : client.url
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
service.dependencies.push({
|
|
212
|
-
id: clientName,
|
|
213
|
-
url: clientUrl,
|
|
214
|
-
local: isLocal
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
const dependency = configManager.current.serviceMap.get(clientName)
|
|
218
|
-
|
|
219
|
-
/* c8 ignore next 4 */
|
|
220
|
-
if (dependency === undefined) {
|
|
221
|
-
throw new errors.MissingDependencyError(missingDependencyErrorMessage(clientName, service, configManager))
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
dependency.dependents.push(service.id)
|
|
225
|
-
|
|
226
|
-
if (isLocal) {
|
|
227
|
-
service.localServiceEnvVars.set(missingKey, clientUrl)
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
resolve()
|
|
184
|
+
await addServiceDependency(service, clientServiceId, client.url)
|
|
231
185
|
})
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
await Promise.all(promises)
|
|
186
|
+
)
|
|
235
187
|
}
|
|
236
188
|
}
|
|
237
189
|
}
|
|
@@ -240,11 +192,16 @@ function topologicalSort (configManager) {
|
|
|
240
192
|
const { services } = configManager.current
|
|
241
193
|
const topo = new Topo.Sorter()
|
|
242
194
|
|
|
243
|
-
for (
|
|
244
|
-
const
|
|
245
|
-
|
|
195
|
+
for (const service of services) {
|
|
196
|
+
const localDependencyIds = service.dependencies
|
|
197
|
+
.filter(dep => dep.local)
|
|
198
|
+
.map(dep => dep.id)
|
|
246
199
|
|
|
247
|
-
topo.add(service, {
|
|
200
|
+
topo.add(service, {
|
|
201
|
+
group: service.id,
|
|
202
|
+
after: localDependencyIds,
|
|
203
|
+
manual: true
|
|
204
|
+
})
|
|
248
205
|
}
|
|
249
206
|
|
|
250
207
|
configManager.current.services = topo.sort()
|
package/lib/management-api.js
CHANGED
|
@@ -59,6 +59,18 @@ async function managementApiPlugin (app, opts) {
|
|
|
59
59
|
return runtime.getServiceConfig(id)
|
|
60
60
|
})
|
|
61
61
|
|
|
62
|
+
app.get('/services/:id/openapi-schema', async (request) => {
|
|
63
|
+
const { id } = request.params
|
|
64
|
+
app.log.debug('get openapi-schema', { id })
|
|
65
|
+
return runtime.getServiceOpenapiSchema(id)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
app.get('/services/:id/graphql-schema', async (request) => {
|
|
69
|
+
const { id } = request.params
|
|
70
|
+
app.log.debug('get graphql-schema', { id })
|
|
71
|
+
return runtime.getServiceGraphqlSchema(id)
|
|
72
|
+
})
|
|
73
|
+
|
|
62
74
|
app.post('/services/:id/start', async (request) => {
|
|
63
75
|
const { id } = request.params
|
|
64
76
|
app.log.debug('start service', { id })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/runtime",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.45.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"typescript": "^5.4.2",
|
|
35
35
|
"undici-oidc-interceptor": "^0.5.0",
|
|
36
36
|
"why-is-node-running": "^2.2.2",
|
|
37
|
-
"@platformatic/sql-graphql": "1.
|
|
38
|
-
"@platformatic/sql-mapper": "1.
|
|
37
|
+
"@platformatic/sql-graphql": "1.45.0",
|
|
38
|
+
"@platformatic/sql-mapper": "1.45.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@fastify/error": "^3.4.1",
|
|
@@ -63,13 +63,13 @@
|
|
|
63
63
|
"undici": "^6.9.0",
|
|
64
64
|
"why-is-node-running": "^2.2.2",
|
|
65
65
|
"ws": "^8.16.0",
|
|
66
|
-
"@platformatic/composer": "1.
|
|
67
|
-
"@platformatic/
|
|
68
|
-
"@platformatic/
|
|
69
|
-
"@platformatic/generators": "1.
|
|
70
|
-
"@platformatic/
|
|
71
|
-
"@platformatic/
|
|
72
|
-
"@platformatic/
|
|
66
|
+
"@platformatic/composer": "1.45.0",
|
|
67
|
+
"@platformatic/config": "1.45.0",
|
|
68
|
+
"@platformatic/db": "1.45.0",
|
|
69
|
+
"@platformatic/generators": "1.45.0",
|
|
70
|
+
"@platformatic/telemetry": "1.45.0",
|
|
71
|
+
"@platformatic/service": "1.45.0",
|
|
72
|
+
"@platformatic/utils": "1.45.0"
|
|
73
73
|
},
|
|
74
74
|
"standard": {
|
|
75
75
|
"ignore": [
|