@platformatic/basic 2.67.0-alpha.1 → 2.67.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/index.js +21 -38
- package/lib/base.js +44 -68
- package/lib/worker/child-process.js +32 -55
- package/package.json +6 -7
- package/schema.json +1 -1
package/index.js
CHANGED
|
@@ -28,10 +28,6 @@ export const configCandidates = [
|
|
|
28
28
|
'watt.tml'
|
|
29
29
|
]
|
|
30
30
|
|
|
31
|
-
function hasDependency (packageJson, dependency) {
|
|
32
|
-
return packageJson.dependencies?.[dependency] || packageJson.devDependencies?.[dependency]
|
|
33
|
-
}
|
|
34
|
-
|
|
35
31
|
function isImportFailedError (error, pkg) {
|
|
36
32
|
if (error.code !== 'ERR_MODULE_NOT_FOUND' && error.code !== 'MODULE_NOT_FOUND') {
|
|
37
33
|
return false
|
|
@@ -64,37 +60,15 @@ async function importStackablePackage (directory, pkg) {
|
|
|
64
60
|
|
|
65
61
|
const serviceDirectory = workerData ? relative(workerData.dirname, directory) : directory
|
|
66
62
|
throw new Error(
|
|
67
|
-
`Unable to import package '${pkg}'. Please add it as a dependency
|
|
63
|
+
`Unable to import package '${pkg}'. Please add it as a dependency in the package.json file in the folder ${serviceDirectory}.`
|
|
68
64
|
)
|
|
69
65
|
}
|
|
70
66
|
}
|
|
71
67
|
|
|
72
|
-
export function detectStackable (packageJson) {
|
|
73
|
-
let name = '@platformatic/node'
|
|
74
|
-
let label = 'Node.js'
|
|
75
|
-
|
|
76
|
-
if (hasDependency(packageJson, '@nestjs/core')) {
|
|
77
|
-
name = '@platformatic/nest'
|
|
78
|
-
label = 'NestJS'
|
|
79
|
-
} else if (hasDependency(packageJson, 'next')) {
|
|
80
|
-
name = '@platformatic/next'
|
|
81
|
-
label = 'Next.js'
|
|
82
|
-
} else if (hasDependency(packageJson, '@remix-run/dev')) {
|
|
83
|
-
name = '@platformatic/remix'
|
|
84
|
-
label = 'Remix'
|
|
85
|
-
} else if (hasDependency(packageJson, 'astro')) {
|
|
86
|
-
name = '@platformatic/astro'
|
|
87
|
-
label = 'Astro'
|
|
88
|
-
// Since Vite is often used with other frameworks, we must check for Vite last
|
|
89
|
-
} else if (hasDependency(packageJson, 'vite')) {
|
|
90
|
-
name = '@platformatic/vite'
|
|
91
|
-
label = 'Vite'
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return { name, label }
|
|
95
|
-
}
|
|
96
|
-
|
|
97
68
|
export async function importStackableAndConfig (root, config) {
|
|
69
|
+
let moduleName = '@platformatic/node'
|
|
70
|
+
let autodetectDescription = 'is using a generic Node.js application'
|
|
71
|
+
|
|
98
72
|
let rootPackageJson
|
|
99
73
|
try {
|
|
100
74
|
rootPackageJson = JSON.parse(await readFile(resolve(root, 'package.json'), 'utf-8'))
|
|
@@ -113,16 +87,25 @@ export async function importStackableAndConfig (root, config) {
|
|
|
113
87
|
}
|
|
114
88
|
}
|
|
115
89
|
|
|
116
|
-
const {
|
|
90
|
+
const { dependencies, devDependencies } = rootPackageJson
|
|
91
|
+
|
|
92
|
+
if (dependencies?.next || devDependencies?.next) {
|
|
93
|
+
autodetectDescription = 'is using Next.js'
|
|
94
|
+
moduleName = '@platformatic/next'
|
|
95
|
+
} else if (dependencies?.['@remix-run/dev'] || devDependencies?.['@remix-run/dev']) {
|
|
96
|
+
autodetectDescription = 'is using Remix'
|
|
97
|
+
moduleName = '@platformatic/remix'
|
|
98
|
+
} else if (dependencies?.astro || devDependencies?.astro) {
|
|
99
|
+
autodetectDescription = 'is using Astro'
|
|
100
|
+
moduleName = '@platformatic/astro'
|
|
101
|
+
} else if (dependencies?.vite || devDependencies?.vite) {
|
|
102
|
+
autodetectDescription = 'is using Vite'
|
|
103
|
+
moduleName = '@platformatic/vite'
|
|
104
|
+
}
|
|
105
|
+
|
|
117
106
|
const stackable = await importStackablePackage(root, moduleName)
|
|
118
107
|
|
|
119
|
-
return {
|
|
120
|
-
stackable,
|
|
121
|
-
config,
|
|
122
|
-
autodetectDescription:
|
|
123
|
-
moduleName === '@platformatic/node' ? 'is a generic Node.js application' : `is using ${label}`,
|
|
124
|
-
moduleName
|
|
125
|
-
}
|
|
108
|
+
return { stackable, config, autodetectDescription, moduleName }
|
|
126
109
|
}
|
|
127
110
|
|
|
128
111
|
async function buildStackable (opts) {
|
package/lib/base.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { client, collectMetrics } from '@platformatic/metrics'
|
|
2
|
-
import {
|
|
2
|
+
import { deepmerge, executeWithTimeout, buildPinoOptions } from '@platformatic/utils'
|
|
3
3
|
import { parseCommandString } from 'execa'
|
|
4
4
|
import { spawn } from 'node:child_process'
|
|
5
|
-
import
|
|
5
|
+
import { once } from 'node:events'
|
|
6
6
|
import { existsSync } from 'node:fs'
|
|
7
7
|
import { platform } from 'node:os'
|
|
8
8
|
import { pathToFileURL } from 'node:url'
|
|
@@ -14,17 +14,13 @@ import { ChildManager } from './worker/child-manager.js'
|
|
|
14
14
|
|
|
15
15
|
const kITC = Symbol.for('plt.runtime.itc')
|
|
16
16
|
|
|
17
|
-
export class BaseStackable
|
|
17
|
+
export class BaseStackable {
|
|
18
18
|
childManager
|
|
19
19
|
subprocess
|
|
20
|
-
subprocessForceClose
|
|
21
|
-
subprocessTerminationSignal
|
|
22
20
|
#subprocessStarted
|
|
23
21
|
#metricsCollected
|
|
24
22
|
|
|
25
23
|
constructor (type, version, options, root, configManager, standardStreams = {}) {
|
|
26
|
-
super()
|
|
27
|
-
|
|
28
24
|
options.context.worker ??= { count: 1, index: 0 }
|
|
29
25
|
|
|
30
26
|
this.type = type
|
|
@@ -52,18 +48,9 @@ export class BaseStackable extends EventEmitter {
|
|
|
52
48
|
this.runtimeConfig = deepmerge(options.context?.runtimeConfig ?? {}, workerData?.config ?? {})
|
|
53
49
|
this.stdout = standardStreams?.stdout ?? process.stdout
|
|
54
50
|
this.stderr = standardStreams?.stderr ?? process.stderr
|
|
55
|
-
this.subprocessForceClose = false
|
|
56
|
-
this.subprocessTerminationSignal = 'SIGINT'
|
|
57
51
|
|
|
58
52
|
const loggerOptions = deepmerge(this.runtimeConfig?.logger ?? {}, this.configManager.current?.logger ?? {})
|
|
59
|
-
const pinoOptions = buildPinoOptions(
|
|
60
|
-
loggerOptions,
|
|
61
|
-
this.serverConfig?.logger,
|
|
62
|
-
this.serviceId,
|
|
63
|
-
this.workerId,
|
|
64
|
-
options,
|
|
65
|
-
this.root
|
|
66
|
-
)
|
|
53
|
+
const pinoOptions = buildPinoOptions(loggerOptions, this.serverConfig?.logger, this.serviceId, this.workerId, options, this.root)
|
|
67
54
|
this.logger = pino(pinoOptions, standardStreams?.stdout)
|
|
68
55
|
|
|
69
56
|
// Setup globals
|
|
@@ -82,7 +69,6 @@ export class BaseStackable extends EventEmitter {
|
|
|
82
69
|
prometheus: { client, registry: this.metricsRegistry },
|
|
83
70
|
setCustomHealthCheck: this.setCustomHealthCheck.bind(this),
|
|
84
71
|
setCustomReadinessCheck: this.setCustomReadinessCheck.bind(this),
|
|
85
|
-
notifyConfig: this.notifyConfig.bind(this),
|
|
86
72
|
logger: this.logger
|
|
87
73
|
})
|
|
88
74
|
}
|
|
@@ -128,22 +114,6 @@ export class BaseStackable extends EventEmitter {
|
|
|
128
114
|
return this.getUrl() ?? this.getDispatchFunc()
|
|
129
115
|
}
|
|
130
116
|
|
|
131
|
-
getMeta () {
|
|
132
|
-
return {
|
|
133
|
-
composer: {
|
|
134
|
-
wantsAbsoluteUrls: false
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async getMetrics ({ format } = {}) {
|
|
140
|
-
if (this.childManager && this.clientWs) {
|
|
141
|
-
return this.childManager.send(this.clientWs, 'getMetrics', { format })
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return format === 'json' ? await this.metricsRegistry.getMetricsAsJSON() : await this.metricsRegistry.metrics()
|
|
145
|
-
}
|
|
146
|
-
|
|
147
117
|
async getOpenapiSchema () {
|
|
148
118
|
return this.openapiSchema
|
|
149
119
|
}
|
|
@@ -257,7 +227,6 @@ export class BaseStackable extends EventEmitter {
|
|
|
257
227
|
|
|
258
228
|
this.childManager.on('config', config => {
|
|
259
229
|
this.subprocessConfig = config
|
|
260
|
-
this.notifyConfig(config)
|
|
261
230
|
})
|
|
262
231
|
|
|
263
232
|
this.childManager.on('connectionString', connectionString => {
|
|
@@ -309,18 +278,13 @@ export class BaseStackable extends EventEmitter {
|
|
|
309
278
|
const exitPromise = once(this.subprocess, 'exit')
|
|
310
279
|
|
|
311
280
|
// Attempt graceful close on the process
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if (!handled && this.subprocessForceClose) {
|
|
315
|
-
this.subprocess.kill(this.subprocessTerminationSignal)
|
|
316
|
-
}
|
|
281
|
+
this.childManager.notify(this.clientWs, 'close')
|
|
317
282
|
|
|
318
283
|
// If the process hasn't exited in X seconds, kill it in the polite way
|
|
319
284
|
/* c8 ignore next 10 */
|
|
320
285
|
const res = await executeWithTimeout(exitPromise, exitTimeout)
|
|
321
|
-
|
|
322
286
|
if (res === 'timeout') {
|
|
323
|
-
this.subprocess.kill(this.subprocessTerminationSignal)
|
|
287
|
+
this.subprocess.kill(this.subprocessTerminationSignal ?? 'SIGINT')
|
|
324
288
|
|
|
325
289
|
// If the process hasn't exited in X seconds, kill it the hard way
|
|
326
290
|
const res = await executeWithTimeout(exitPromise, exitTimeout)
|
|
@@ -339,28 +303,6 @@ export class BaseStackable extends EventEmitter {
|
|
|
339
303
|
return this.childManager
|
|
340
304
|
}
|
|
341
305
|
|
|
342
|
-
async getChildManagerContext (basePath) {
|
|
343
|
-
const meta = await this.getMeta()
|
|
344
|
-
|
|
345
|
-
return {
|
|
346
|
-
id: this.id,
|
|
347
|
-
config: this.configManager.current,
|
|
348
|
-
serviceId: this.serviceId,
|
|
349
|
-
workerId: this.workerId,
|
|
350
|
-
// Always use URL to avoid serialization problem in Windows
|
|
351
|
-
root: pathToFileURL(this.root).toString(),
|
|
352
|
-
basePath,
|
|
353
|
-
logLevel: this.logger.level,
|
|
354
|
-
isEntrypoint: this.isEntrypoint,
|
|
355
|
-
runtimeBasePath: this.runtimeConfig?.basePath ?? null,
|
|
356
|
-
wantsAbsoluteUrls: meta.composer?.wantsAbsoluteUrls ?? false,
|
|
357
|
-
/* c8 ignore next 2 - Else branches */
|
|
358
|
-
port: (this.isEntrypoint ? this.serverConfig?.port || 0 : undefined) ?? true,
|
|
359
|
-
host: (this.isEntrypoint ? this.serverConfig?.hostname : undefined) ?? true,
|
|
360
|
-
telemetryConfig: this.telemetryConfig
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
306
|
async spawn (command) {
|
|
365
307
|
const [executable, ...args] = parseCommandString(command)
|
|
366
308
|
const hasChainedCommands = command.includes('&&') || command.includes('||') || command.includes(';')
|
|
@@ -386,10 +328,6 @@ export class BaseStackable extends EventEmitter {
|
|
|
386
328
|
return subprocess
|
|
387
329
|
}
|
|
388
330
|
|
|
389
|
-
notifyConfig (config) {
|
|
390
|
-
this.emit('config', config)
|
|
391
|
-
}
|
|
392
|
-
|
|
393
331
|
async _collectMetrics () {
|
|
394
332
|
if (this.#metricsCollected) {
|
|
395
333
|
return
|
|
@@ -453,7 +391,45 @@ export class BaseStackable extends EventEmitter {
|
|
|
453
391
|
}
|
|
454
392
|
}
|
|
455
393
|
|
|
394
|
+
async getMetrics ({ format } = {}) {
|
|
395
|
+
if (this.childManager && this.clientWs) {
|
|
396
|
+
return this.childManager.send(this.clientWs, 'getMetrics', { format })
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return format === 'json' ? await this.metricsRegistry.getMetricsAsJSON() : await this.metricsRegistry.metrics()
|
|
400
|
+
}
|
|
401
|
+
|
|
456
402
|
async #invalidateHttpCache (opts = {}) {
|
|
457
403
|
await globalThis[kITC].send('invalidateHttpCache', opts)
|
|
458
404
|
}
|
|
405
|
+
|
|
406
|
+
getMeta () {
|
|
407
|
+
return {
|
|
408
|
+
composer: {
|
|
409
|
+
wantsAbsoluteUrls: false
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
async getChildManagerContext (basePath) {
|
|
415
|
+
const meta = await this.getMeta()
|
|
416
|
+
|
|
417
|
+
return {
|
|
418
|
+
id: this.id,
|
|
419
|
+
config: this.configManager.current,
|
|
420
|
+
serviceId: this.serviceId,
|
|
421
|
+
workerId: this.workerId,
|
|
422
|
+
// Always use URL to avoid serialization problem in Windows
|
|
423
|
+
root: pathToFileURL(this.root).toString(),
|
|
424
|
+
basePath,
|
|
425
|
+
logLevel: this.logger.level,
|
|
426
|
+
isEntrypoint: this.isEntrypoint,
|
|
427
|
+
runtimeBasePath: this.runtimeConfig?.basePath ?? null,
|
|
428
|
+
wantsAbsoluteUrls: meta.composer?.wantsAbsoluteUrls ?? false,
|
|
429
|
+
/* c8 ignore next 2 */
|
|
430
|
+
port: (this.isEntrypoint ? this.serverConfig?.port || 0 : undefined) ?? true,
|
|
431
|
+
host: (this.isEntrypoint ? this.serverConfig?.hostname : undefined) ?? true,
|
|
432
|
+
telemetryConfig: this.telemetryConfig
|
|
433
|
+
}
|
|
434
|
+
}
|
|
459
435
|
}
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import { ITC } from '@platformatic/itc'
|
|
2
2
|
import { client, collectMetrics } from '@platformatic/metrics'
|
|
3
|
-
import {
|
|
4
|
-
buildPinoFormatters,
|
|
5
|
-
buildPinoTimestamp,
|
|
6
|
-
disablePinoDirectWrite,
|
|
7
|
-
ensureFlushedWorkerStdio,
|
|
8
|
-
ensureLoggableError,
|
|
9
|
-
features
|
|
10
|
-
} from '@platformatic/utils'
|
|
3
|
+
import { buildPinoFormatters, buildPinoTimestamp, disablePinoDirectWrite, ensureFlushedWorkerStdio, ensureLoggableError, features } from '@platformatic/utils'
|
|
11
4
|
import diagnosticChannel, { tracingChannel } from 'node:diagnostics_channel'
|
|
12
5
|
import { EventEmitter, once } from 'node:events'
|
|
13
6
|
import { readFile } from 'node:fs/promises'
|
|
@@ -68,6 +61,7 @@ function createInterceptor () {
|
|
|
68
61
|
export class ChildProcess extends ITC {
|
|
69
62
|
#listener
|
|
70
63
|
#socket
|
|
64
|
+
#child
|
|
71
65
|
#logger
|
|
72
66
|
#metricsRegistry
|
|
73
67
|
#pendingMessages
|
|
@@ -82,25 +76,6 @@ export class ChildProcess extends ITC {
|
|
|
82
76
|
},
|
|
83
77
|
getMetrics: (...args) => {
|
|
84
78
|
return this.#getMetrics(...args)
|
|
85
|
-
},
|
|
86
|
-
close: (signal) => {
|
|
87
|
-
let handled = false
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
handled = globalThis.platformatic.events.emit('close', signal)
|
|
91
|
-
} catch (error) {
|
|
92
|
-
this.#logger.error({ err: ensureLoggableError(error) }, 'Error while handling close event.')
|
|
93
|
-
process.exitCode = 1
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (!handled) {
|
|
97
|
-
// No user event, just exit without errors
|
|
98
|
-
setImmediate(() => {
|
|
99
|
-
process.exit(process.exitCode ?? 0)
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return handled
|
|
104
79
|
}
|
|
105
80
|
}
|
|
106
81
|
})
|
|
@@ -117,37 +92,23 @@ export class ChildProcess extends ITC {
|
|
|
117
92
|
this.#setupServer()
|
|
118
93
|
this.#setupInterceptors()
|
|
119
94
|
|
|
95
|
+
this.on('close', () => {
|
|
96
|
+
if (!globalThis.platformatic.events.emit('close')) {
|
|
97
|
+
// No user event, just exit without errors
|
|
98
|
+
process.exit(0)
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
|
|
120
102
|
this.registerGlobals({
|
|
121
103
|
logger: this.#logger,
|
|
122
104
|
setOpenapiSchema: this.setOpenapiSchema.bind(this),
|
|
123
105
|
setGraphqlSchema: this.setGraphqlSchema.bind(this),
|
|
124
106
|
setConnectionString: this.setConnectionString.bind(this),
|
|
125
107
|
setBasePath: this.setBasePath.bind(this),
|
|
126
|
-
prometheus: { client, registry: this.#metricsRegistry }
|
|
127
|
-
notifyConfig: this.#notifyConfig.bind(this)
|
|
108
|
+
prometheus: { client, registry: this.#metricsRegistry }
|
|
128
109
|
})
|
|
129
110
|
}
|
|
130
111
|
|
|
131
|
-
registerGlobals (globals) {
|
|
132
|
-
globalThis.platformatic = Object.assign(globalThis.platformatic ?? {}, globals)
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
setOpenapiSchema (schema) {
|
|
136
|
-
this.notify('openapiSchema', schema)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
setGraphqlSchema (schema) {
|
|
140
|
-
this.notify('graphqlSchema', schema)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
setConnectionString (connectionString) {
|
|
144
|
-
this.notify('connectionString', connectionString)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
setBasePath (basePath) {
|
|
148
|
-
this.notify('basePath', basePath)
|
|
149
|
-
}
|
|
150
|
-
|
|
151
112
|
_setupListener (listener) {
|
|
152
113
|
this.#listener = listener
|
|
153
114
|
|
|
@@ -268,7 +229,7 @@ export class ChildProcess extends ITC {
|
|
|
268
229
|
#setupServer () {
|
|
269
230
|
const subscribers = {
|
|
270
231
|
asyncStart ({ options }) {
|
|
271
|
-
|
|
232
|
+
// Unix socket, do nothing
|
|
272
233
|
if (options.path) {
|
|
273
234
|
return
|
|
274
235
|
}
|
|
@@ -326,9 +287,9 @@ export class ChildProcess extends ITC {
|
|
|
326
287
|
|
|
327
288
|
#setupHandlers () {
|
|
328
289
|
const errorLabel =
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
290
|
+
typeof globalThis.platformatic.workerId !== 'undefined'
|
|
291
|
+
? `worker ${globalThis.platformatic.workerId} of the service "${globalThis.platformatic.serviceId}"`
|
|
292
|
+
: `service "${globalThis.platformatic.serviceId}"`
|
|
332
293
|
|
|
333
294
|
function handleUnhandled (type, err) {
|
|
334
295
|
this.#logger.error({ err: ensureLoggableError(err) }, `Child process for the ${errorLabel} threw an ${type}.`)
|
|
@@ -341,8 +302,24 @@ export class ChildProcess extends ITC {
|
|
|
341
302
|
process.on('unhandledRejection', handleUnhandled.bind(this, 'unhandled rejection'))
|
|
342
303
|
}
|
|
343
304
|
|
|
344
|
-
|
|
345
|
-
|
|
305
|
+
registerGlobals (globals) {
|
|
306
|
+
globalThis.platformatic = Object.assign(globalThis.platformatic ?? {}, globals)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
setOpenapiSchema (schema) {
|
|
310
|
+
this.notify('openapiSchema', schema)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
setGraphqlSchema (schema) {
|
|
314
|
+
this.notify('graphqlSchema', schema)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
setConnectionString (connectionString) {
|
|
318
|
+
this.notify('connectionString', connectionString)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
setBasePath (basePath) {
|
|
322
|
+
this.notify('basePath', basePath)
|
|
346
323
|
}
|
|
347
324
|
}
|
|
348
325
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/basic",
|
|
3
|
-
"version": "2.67.0
|
|
3
|
+
"version": "2.67.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -24,11 +24,11 @@
|
|
|
24
24
|
"split2": "^4.2.0",
|
|
25
25
|
"undici": "^7.0.0",
|
|
26
26
|
"ws": "^8.18.0",
|
|
27
|
-
"@platformatic/config": "2.67.0
|
|
28
|
-
"@platformatic/itc": "2.67.0
|
|
29
|
-
"@platformatic/telemetry": "2.67.0
|
|
30
|
-
"@platformatic/metrics": "2.67.0
|
|
31
|
-
"@platformatic/utils": "2.67.0
|
|
27
|
+
"@platformatic/config": "2.67.0",
|
|
28
|
+
"@platformatic/itc": "2.67.0",
|
|
29
|
+
"@platformatic/telemetry": "2.67.0",
|
|
30
|
+
"@platformatic/metrics": "2.67.0",
|
|
31
|
+
"@platformatic/utils": "2.67.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"borp": "^0.20.0",
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
"fastify": "^5.0.0",
|
|
38
38
|
"get-port": "^7.1.0",
|
|
39
39
|
"json-schema-to-typescript": "^15.0.0",
|
|
40
|
-
"minimatch": "^10.0.1",
|
|
41
40
|
"neostandard": "^0.12.0",
|
|
42
41
|
"next": "^15.0.0",
|
|
43
42
|
"react": "^18.3.1",
|
package/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/@platformatic/basic/2.67.0
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/basic/2.67.0.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"title": "Platformatic Stackable",
|
|
5
5
|
"type": "object",
|