@platformatic/basic 2.6.1 → 2.7.1-alpha.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/lib/base.js +42 -22
- package/lib/worker/child-process.js +57 -0
- package/package.json +6 -6
- package/schema.json +1 -1
package/lib/base.js
CHANGED
|
@@ -3,6 +3,7 @@ import { collectMetrics } from '@platformatic/metrics'
|
|
|
3
3
|
import { parseCommandString } from 'execa'
|
|
4
4
|
import { spawn } from 'node:child_process'
|
|
5
5
|
import { once } from 'node:events'
|
|
6
|
+
import { workerData } from 'node:worker_threads'
|
|
6
7
|
import { existsSync } from 'node:fs'
|
|
7
8
|
import { platform } from 'node:os'
|
|
8
9
|
import { pathToFileURL } from 'node:url'
|
|
@@ -12,6 +13,8 @@ import { NonZeroExitCode } from './errors.js'
|
|
|
12
13
|
import { cleanBasePath } from './utils.js'
|
|
13
14
|
import { ChildManager } from './worker/child-manager.js'
|
|
14
15
|
|
|
16
|
+
const kITC = Symbol.for('plt.runtime.itc')
|
|
17
|
+
|
|
15
18
|
export class BaseStackable {
|
|
16
19
|
childManager
|
|
17
20
|
#subprocess
|
|
@@ -34,6 +37,7 @@ export class BaseStackable {
|
|
|
34
37
|
this.startHttpTimer = null
|
|
35
38
|
this.endHttpTimer = null
|
|
36
39
|
this.clientWs = null
|
|
40
|
+
this.runtimeConfig = workerData?.config ?? null
|
|
37
41
|
|
|
38
42
|
// Setup the logger
|
|
39
43
|
const pinoOptions = {
|
|
@@ -49,7 +53,8 @@ export class BaseStackable {
|
|
|
49
53
|
this.registerGlobals({
|
|
50
54
|
setOpenapiSchema: this.setOpenapiSchema.bind(this),
|
|
51
55
|
setGraphqlSchema: this.setGraphqlSchema.bind(this),
|
|
52
|
-
setBasePath: this.setBasePath.bind(this)
|
|
56
|
+
setBasePath: this.setBasePath.bind(this),
|
|
57
|
+
invalidateHttpCache: this.#invalidateHttpCache.bind(this)
|
|
53
58
|
})
|
|
54
59
|
}
|
|
55
60
|
|
|
@@ -134,20 +139,12 @@ export class BaseStackable {
|
|
|
134
139
|
|
|
135
140
|
this.logger.debug(`Executing "${command}" ...`)
|
|
136
141
|
|
|
142
|
+
const context = await this.#getChildManagerContext(basePath)
|
|
137
143
|
this.childManager = new ChildManager({
|
|
138
144
|
logger: this.logger,
|
|
139
145
|
loader,
|
|
140
146
|
scripts,
|
|
141
|
-
context
|
|
142
|
-
id: this.id,
|
|
143
|
-
// Always use URL to avoid serialization problem in Windows
|
|
144
|
-
root: pathToFileURL(this.root).toString(),
|
|
145
|
-
basePath,
|
|
146
|
-
logLevel: this.logger.level,
|
|
147
|
-
/* c8 ignore next 2 */
|
|
148
|
-
port: (this.isEntrypoint ? this.serverConfig?.port || 0 : undefined) ?? true,
|
|
149
|
-
host: (this.isEntrypoint ? this.serverConfig?.hostname : undefined) ?? true
|
|
150
|
-
}
|
|
147
|
+
context
|
|
151
148
|
})
|
|
152
149
|
|
|
153
150
|
try {
|
|
@@ -188,20 +185,12 @@ export class BaseStackable {
|
|
|
188
185
|
async startWithCommand (command, loader) {
|
|
189
186
|
const config = this.configManager.current
|
|
190
187
|
const basePath = config.application?.basePath ? cleanBasePath(config.application?.basePath) : ''
|
|
188
|
+
|
|
189
|
+
const context = await this.#getChildManagerContext(basePath)
|
|
191
190
|
this.childManager = new ChildManager({
|
|
192
191
|
logger: this.logger,
|
|
193
192
|
loader,
|
|
194
|
-
context
|
|
195
|
-
id: this.id,
|
|
196
|
-
// Always use URL to avoid serialization problem in Windows
|
|
197
|
-
root: pathToFileURL(this.root).toString(),
|
|
198
|
-
basePath,
|
|
199
|
-
logLevel: this.logger.level,
|
|
200
|
-
/* c8 ignore next 2 */
|
|
201
|
-
port: (this.isEntrypoint ? this.serverConfig?.port || 0 : undefined) ?? true,
|
|
202
|
-
host: (this.isEntrypoint ? this.serverConfig?.hostname : undefined) ?? true,
|
|
203
|
-
telemetry: this.telemetryConfig
|
|
204
|
-
}
|
|
193
|
+
context
|
|
205
194
|
})
|
|
206
195
|
|
|
207
196
|
this.childManager.on('config', config => {
|
|
@@ -312,4 +301,35 @@ export class BaseStackable {
|
|
|
312
301
|
? await this.metricsRegistry.getMetricsAsJSON()
|
|
313
302
|
: await this.metricsRegistry.metrics()
|
|
314
303
|
}
|
|
304
|
+
|
|
305
|
+
async #invalidateHttpCache (opts = {}) {
|
|
306
|
+
await globalThis[kITC].send('invalidateHttpCache', opts)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
getMeta () {
|
|
310
|
+
return {
|
|
311
|
+
composer: {
|
|
312
|
+
wantsAbsoluteUrls: false
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async #getChildManagerContext (basePath) {
|
|
318
|
+
const meta = await this.getMeta()
|
|
319
|
+
|
|
320
|
+
return {
|
|
321
|
+
id: this.id,
|
|
322
|
+
// Always use URL to avoid serialization problem in Windows
|
|
323
|
+
root: pathToFileURL(this.root).toString(),
|
|
324
|
+
basePath,
|
|
325
|
+
logLevel: this.logger.level,
|
|
326
|
+
isEntrypoint: this.isEntrypoint,
|
|
327
|
+
runtimeBasePath: this.runtimeConfig?.basePath ?? null,
|
|
328
|
+
wantsAbsoluteUrls: meta.composer?.wantsAbsoluteUrls ?? false,
|
|
329
|
+
/* c8 ignore next 2 */
|
|
330
|
+
port: (this.isEntrypoint ? this.serverConfig?.port || 0 : undefined) ?? true,
|
|
331
|
+
host: (this.isEntrypoint ? this.serverConfig?.hostname : undefined) ?? true,
|
|
332
|
+
telemetry: this.telemetryConfig
|
|
333
|
+
}
|
|
334
|
+
}
|
|
315
335
|
}
|
|
@@ -16,6 +16,8 @@ import { WebSocket } from 'ws'
|
|
|
16
16
|
import { exitCodes } from '../errors.js'
|
|
17
17
|
import { importFile } from '../utils.js'
|
|
18
18
|
import { getSocketPath, isWindows } from './child-manager.js'
|
|
19
|
+
import diagnosticChannel from 'node:diagnostics_channel'
|
|
20
|
+
import { ServerResponse } from 'node:http'
|
|
19
21
|
|
|
20
22
|
function createInterceptor (itc) {
|
|
21
23
|
return function (dispatch) {
|
|
@@ -248,6 +250,11 @@ export class ChildProcess extends ITC {
|
|
|
248
250
|
}
|
|
249
251
|
|
|
250
252
|
tracingChannel('net.server.listen').subscribe(subscribers)
|
|
253
|
+
|
|
254
|
+
const { isEntrypoint, runtimeBasePath, wantsAbsoluteUrls } = globalThis.platformatic
|
|
255
|
+
if (isEntrypoint && runtimeBasePath && !wantsAbsoluteUrls) {
|
|
256
|
+
stripBasePath(runtimeBasePath)
|
|
257
|
+
}
|
|
251
258
|
}
|
|
252
259
|
|
|
253
260
|
#setupInterceptors () {
|
|
@@ -270,6 +277,56 @@ export class ChildProcess extends ITC {
|
|
|
270
277
|
}
|
|
271
278
|
}
|
|
272
279
|
|
|
280
|
+
function stripBasePath (basePath) {
|
|
281
|
+
const kBasePath = Symbol('kBasePath')
|
|
282
|
+
|
|
283
|
+
diagnosticChannel.subscribe('http.server.request.start', ({ request, response }) => {
|
|
284
|
+
if (request.url.startsWith(basePath)) {
|
|
285
|
+
request.url = request.url.slice(basePath.length)
|
|
286
|
+
|
|
287
|
+
if (request.url.charAt(0) !== '/') {
|
|
288
|
+
request.url = '/' + request.url
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
response[kBasePath] = basePath
|
|
292
|
+
}
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
const originWriteHead = ServerResponse.prototype.writeHead
|
|
296
|
+
const originSetHeader = ServerResponse.prototype.setHeader
|
|
297
|
+
|
|
298
|
+
ServerResponse.prototype.writeHead = function (statusCode, statusMessage, headers) {
|
|
299
|
+
if (this[kBasePath] !== undefined) {
|
|
300
|
+
if (headers === undefined && typeof statusMessage === 'object') {
|
|
301
|
+
headers = statusMessage
|
|
302
|
+
statusMessage = undefined
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (headers) {
|
|
306
|
+
for (const key in headers) {
|
|
307
|
+
if (
|
|
308
|
+
key.toLowerCase() === 'location' &&
|
|
309
|
+
!headers[key].startsWith(basePath)
|
|
310
|
+
) {
|
|
311
|
+
headers[key] = basePath + headers[key]
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return originWriteHead.call(this, statusCode, statusMessage, headers)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
ServerResponse.prototype.setHeader = function (name, value) {
|
|
321
|
+
if (this[kBasePath]) {
|
|
322
|
+
if (name.toLowerCase() === 'location' && !value.startsWith(basePath)) {
|
|
323
|
+
value = basePath + value
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
originSetHeader.call(this, name, value)
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
273
330
|
async function main () {
|
|
274
331
|
const dataPath = resolve(tmpdir(), 'platformatic', 'runtimes', `${process.env.PLT_MANAGER_ID}.json`)
|
|
275
332
|
const { data, loader, scripts } = JSON.parse(await readFile(dataPath))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/basic",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.1-alpha.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"split2": "^4.2.0",
|
|
24
24
|
"undici": "^6.19.5",
|
|
25
25
|
"ws": "^8.18.0",
|
|
26
|
-
"@platformatic/config": "2.
|
|
27
|
-
"@platformatic/itc": "2.
|
|
28
|
-
"@platformatic/telemetry": "2.
|
|
29
|
-
"@platformatic/
|
|
30
|
-
"@platformatic/
|
|
26
|
+
"@platformatic/config": "2.7.1-alpha.1",
|
|
27
|
+
"@platformatic/itc": "2.7.1-alpha.1",
|
|
28
|
+
"@platformatic/telemetry": "2.7.1-alpha.1",
|
|
29
|
+
"@platformatic/utils": "2.7.1-alpha.1",
|
|
30
|
+
"@platformatic/metrics": "2.7.1-alpha.1"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"borp": "^0.18.0",
|
package/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/@platformatic/basic/2.
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/basic/2.7.1-alpha.1.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"title": "Platformatic Stackable",
|
|
5
5
|
"type": "object",
|