@platformatic/runtime 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/config.d.ts +13 -1
- package/lib/management-api.js +9 -0
- package/lib/runtime.js +38 -1
- package/lib/schema.js +29 -0
- package/lib/shared-http-cache.js +45 -0
- package/lib/worker/http-cache.js +83 -0
- package/lib/worker/main.js +99 -5
- package/package.json +16 -14
- package/schema.json +33 -1
package/config.d.ts
CHANGED
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
* and run json-schema-to-typescript to regenerate this file.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
export type
|
|
8
|
+
export type HttpsSchemasPlatformaticDevPlatformaticRuntime271Alpha1Json = {
|
|
9
9
|
[k: string]: unknown;
|
|
10
10
|
} & {
|
|
11
11
|
$schema?: string;
|
|
12
12
|
preload?: string;
|
|
13
13
|
entrypoint?: string;
|
|
14
|
+
basePath?: string;
|
|
14
15
|
autoload?: {
|
|
15
16
|
path: string;
|
|
16
17
|
exclude?: string[];
|
|
@@ -109,6 +110,17 @@ export type HttpsSchemasPlatformaticDevPlatformaticRuntime261Json = {
|
|
|
109
110
|
};
|
|
110
111
|
[k: string]: unknown;
|
|
111
112
|
};
|
|
113
|
+
httpCache?:
|
|
114
|
+
| boolean
|
|
115
|
+
| {
|
|
116
|
+
store?: string;
|
|
117
|
+
/**
|
|
118
|
+
* @minItems 1
|
|
119
|
+
*/
|
|
120
|
+
methods?: [string, ...string[]];
|
|
121
|
+
cacheTagsHeader?: string;
|
|
122
|
+
[k: string]: unknown;
|
|
123
|
+
};
|
|
112
124
|
watch?: boolean | string;
|
|
113
125
|
managementApi?:
|
|
114
126
|
| boolean
|
package/lib/management-api.js
CHANGED
|
@@ -193,6 +193,15 @@ async function managementApiPlugin (app, opts) {
|
|
|
193
193
|
const logFileStream = await runtime.getLogFileStream(logId, runtimePID)
|
|
194
194
|
return logFileStream
|
|
195
195
|
})
|
|
196
|
+
|
|
197
|
+
app.get('/http-cache/requests', async () => {
|
|
198
|
+
return runtime.getCachedHttpRequests()
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
app.post('/http-cache/invalidate', async (req) => {
|
|
202
|
+
const { origin, routes, tags } = req.body
|
|
203
|
+
await runtime.invalidateHttpCache({ origin, routes, tags })
|
|
204
|
+
})
|
|
196
205
|
}
|
|
197
206
|
|
|
198
207
|
async function startManagementApi (runtime, configManager) {
|
package/lib/runtime.js
CHANGED
|
@@ -16,6 +16,7 @@ const errors = require('./errors')
|
|
|
16
16
|
const { createLogger } = require('./logger')
|
|
17
17
|
const { startManagementApi } = require('./management-api')
|
|
18
18
|
const { startPrometheusServer } = require('./prom-server')
|
|
19
|
+
const { createSharedStore } = require('./shared-http-cache')
|
|
19
20
|
const { getRuntimeTmpDir } = require('./utils')
|
|
20
21
|
const { sendViaITC, waitEventFromITC } = require('./worker/itc')
|
|
21
22
|
const { kId, kITC, kConfig } = require('./worker/symbols')
|
|
@@ -53,6 +54,7 @@ class Runtime extends EventEmitter {
|
|
|
53
54
|
#bootstrapAttempts
|
|
54
55
|
#inspectors
|
|
55
56
|
#inspectorServer
|
|
57
|
+
#sharedHttpCache
|
|
56
58
|
|
|
57
59
|
constructor (configManager, runtimeLogsDir, env) {
|
|
58
60
|
super()
|
|
@@ -72,6 +74,7 @@ class Runtime extends EventEmitter {
|
|
|
72
74
|
this.#restartPromises = new Map()
|
|
73
75
|
this.#bootstrapAttempts = new Map()
|
|
74
76
|
this.#inspectors = []
|
|
77
|
+
this.#sharedHttpCache = null
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
async init () {
|
|
@@ -116,6 +119,11 @@ class Runtime extends EventEmitter {
|
|
|
116
119
|
throw e
|
|
117
120
|
}
|
|
118
121
|
|
|
122
|
+
this.#sharedHttpCache = createSharedStore(
|
|
123
|
+
this.#configManager.dirname,
|
|
124
|
+
config.httpCache
|
|
125
|
+
)
|
|
126
|
+
|
|
119
127
|
this.#updateStatus('init')
|
|
120
128
|
}
|
|
121
129
|
|
|
@@ -755,6 +763,24 @@ class Runtime extends EventEmitter {
|
|
|
755
763
|
return createReadStream(filePath)
|
|
756
764
|
}
|
|
757
765
|
|
|
766
|
+
async getCachedHttpRequests () {
|
|
767
|
+
return this.#sharedHttpCache.getRoutes()
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
async invalidateHttpCache (options = {}) {
|
|
771
|
+
const { origin, routes, tags } = options
|
|
772
|
+
|
|
773
|
+
if (!this.#sharedHttpCache) return
|
|
774
|
+
|
|
775
|
+
if (routes && routes.length > 0) {
|
|
776
|
+
await this.#sharedHttpCache.deleteRoutes(routes)
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
if (tags && tags.length > 0) {
|
|
780
|
+
await this.#sharedHttpCache.deleteByCacheTags(origin, tags)
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
|
|
758
784
|
#updateStatus (status) {
|
|
759
785
|
this.#status = status
|
|
760
786
|
this.emit(status)
|
|
@@ -865,7 +891,18 @@ class Runtime extends EventEmitter {
|
|
|
865
891
|
port: service,
|
|
866
892
|
handlers: {
|
|
867
893
|
getServiceMeta: this.getServiceMeta.bind(this),
|
|
868
|
-
getServices: this.getServices.bind(this)
|
|
894
|
+
getServices: this.getServices.bind(this),
|
|
895
|
+
isHttpCacheFull: () => this.#sharedHttpCache.isFull(),
|
|
896
|
+
getHttpCacheValue: opts => this.#sharedHttpCache.getValue(opts.request),
|
|
897
|
+
setHttpCacheValue: opts => this.#sharedHttpCache.setValue(
|
|
898
|
+
opts.request,
|
|
899
|
+
opts.response,
|
|
900
|
+
opts.payload
|
|
901
|
+
),
|
|
902
|
+
deleteHttpCacheValue: opts => this.#sharedHttpCache.deleteByOrigin(
|
|
903
|
+
opts.origin
|
|
904
|
+
),
|
|
905
|
+
invalidateHttpCache: opts => this.invalidateHttpCache(opts),
|
|
869
906
|
}
|
|
870
907
|
})
|
|
871
908
|
service[kITC].listen()
|
package/lib/schema.js
CHANGED
|
@@ -49,6 +49,9 @@ const platformaticRuntimeSchema = {
|
|
|
49
49
|
entrypoint: {
|
|
50
50
|
type: 'string'
|
|
51
51
|
},
|
|
52
|
+
basePath: {
|
|
53
|
+
type: 'string'
|
|
54
|
+
},
|
|
52
55
|
autoload: {
|
|
53
56
|
type: 'object',
|
|
54
57
|
additionalProperties: false,
|
|
@@ -142,6 +145,32 @@ const platformaticRuntimeSchema = {
|
|
|
142
145
|
}
|
|
143
146
|
}
|
|
144
147
|
},
|
|
148
|
+
httpCache: {
|
|
149
|
+
oneOf: [
|
|
150
|
+
{
|
|
151
|
+
type: 'boolean'
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: 'object',
|
|
155
|
+
properties: {
|
|
156
|
+
store: {
|
|
157
|
+
type: 'string'
|
|
158
|
+
},
|
|
159
|
+
methods: {
|
|
160
|
+
type: 'array',
|
|
161
|
+
items: {
|
|
162
|
+
type: 'string'
|
|
163
|
+
},
|
|
164
|
+
default: ['GET', 'HEAD'],
|
|
165
|
+
minItems: 1
|
|
166
|
+
},
|
|
167
|
+
cacheTagsHeader: {
|
|
168
|
+
type: 'string'
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
},
|
|
145
174
|
watch: {
|
|
146
175
|
anyOf: [
|
|
147
176
|
{
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { join } = require('node:path')
|
|
4
|
+
const { createRequire } = require('node:module')
|
|
5
|
+
const MemoryCacheStore = require('@platformatic/undici-cache-memory')
|
|
6
|
+
|
|
7
|
+
function createSharedStore (projectDir, httpCacheConfig = {}) {
|
|
8
|
+
const runtimeRequire = createRequire(join(projectDir, 'file'))
|
|
9
|
+
|
|
10
|
+
const { store, ...storeConfig } = httpCacheConfig
|
|
11
|
+
const CacheStore = store ? runtimeRequire(store) : MemoryCacheStore
|
|
12
|
+
|
|
13
|
+
class SharedCacheStore extends CacheStore {
|
|
14
|
+
async getValue (req) {
|
|
15
|
+
const readStream = await this.createReadStream(req)
|
|
16
|
+
if (!readStream) return null
|
|
17
|
+
|
|
18
|
+
let payload = ''
|
|
19
|
+
for await (const chunk of readStream) {
|
|
20
|
+
payload += chunk
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const response = this.#sanitizeResponse(readStream.value)
|
|
24
|
+
return { response, payload }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setValue (req, opts, data) {
|
|
28
|
+
const writeStream = this.createWriteStream(req, opts)
|
|
29
|
+
writeStream.write(data)
|
|
30
|
+
writeStream.end()
|
|
31
|
+
return null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#sanitizeResponse (response) {
|
|
35
|
+
return {
|
|
36
|
+
...response,
|
|
37
|
+
rawHeaders: response.rawHeaders.map(header => header.toString())
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return new SharedCacheStore(storeConfig)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = { createSharedStore }
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { Readable, Writable } = require('node:stream')
|
|
4
|
+
const { kITC } = require('./symbols')
|
|
5
|
+
|
|
6
|
+
class RemoteCacheStore {
|
|
7
|
+
get isFull () {
|
|
8
|
+
// TODO: make an itc call to the shared cache when interceptor supports
|
|
9
|
+
// an async isFull method
|
|
10
|
+
return false
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async createReadStream (request) {
|
|
14
|
+
const itc = globalThis[kITC]
|
|
15
|
+
if (!itc) return
|
|
16
|
+
|
|
17
|
+
const cachedValue = await itc.send('getHttpCacheValue', {
|
|
18
|
+
request: this.#sanitizeRequest(request)
|
|
19
|
+
})
|
|
20
|
+
if (!cachedValue) return
|
|
21
|
+
|
|
22
|
+
const readable = new Readable({
|
|
23
|
+
read () {}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
Object.defineProperty(readable, 'value', {
|
|
27
|
+
get () { return cachedValue.response }
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
readable.push(cachedValue.payload)
|
|
31
|
+
readable.push(null)
|
|
32
|
+
|
|
33
|
+
return readable
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
createWriteStream (request, response) {
|
|
37
|
+
const itc = globalThis[kITC]
|
|
38
|
+
if (!itc) throw new Error('Cannot write to cache without an ITC instance')
|
|
39
|
+
|
|
40
|
+
let payload = ''
|
|
41
|
+
|
|
42
|
+
request = this.#sanitizeRequest(request)
|
|
43
|
+
response = this.#sanitizeResponse(response)
|
|
44
|
+
|
|
45
|
+
return new Writable({
|
|
46
|
+
write (chunk, encoding, callback) {
|
|
47
|
+
payload += chunk
|
|
48
|
+
callback()
|
|
49
|
+
},
|
|
50
|
+
final (callback) {
|
|
51
|
+
itc.send('setHttpCacheValue', { request, response, payload })
|
|
52
|
+
.then(() => callback())
|
|
53
|
+
.catch((err) => callback(err))
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
deleteByOrigin (origin) {
|
|
59
|
+
const itc = globalThis[kITC]
|
|
60
|
+
if (!itc) throw new Error('Cannot delete from cache without an ITC instance')
|
|
61
|
+
|
|
62
|
+
itc.send('deleteHttpCacheValue', { origin })
|
|
63
|
+
// TODO: return a Promise
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
#sanitizeRequest (request) {
|
|
67
|
+
return {
|
|
68
|
+
origin: request.origin,
|
|
69
|
+
method: request.method,
|
|
70
|
+
path: request.path,
|
|
71
|
+
headers: request.headers
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
#sanitizeResponse (response) {
|
|
76
|
+
return {
|
|
77
|
+
...response,
|
|
78
|
+
rawHeaders: response.rawHeaders.map(header => header.toString())
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = RemoteCacheStore
|
package/lib/worker/main.js
CHANGED
|
@@ -5,11 +5,15 @@ const { join } = require('node:path')
|
|
|
5
5
|
const { parentPort, workerData, threadId } = require('node:worker_threads')
|
|
6
6
|
const { pathToFileURL } = require('node:url')
|
|
7
7
|
const inspector = require('node:inspector')
|
|
8
|
+
const diagnosticChannel = require('node:diagnostics_channel')
|
|
9
|
+
const { ServerResponse } = require('node:http')
|
|
8
10
|
|
|
9
11
|
const pino = require('pino')
|
|
10
|
-
const { fetch, setGlobalDispatcher, Agent } = require('undici')
|
|
12
|
+
const { fetch, setGlobalDispatcher, getGlobalDispatcher, Agent } = require('undici')
|
|
11
13
|
const { wire } = require('undici-thread-interceptor')
|
|
14
|
+
const undici = require('undici')
|
|
12
15
|
|
|
16
|
+
const RemoteCacheStore = require('./http-cache')
|
|
13
17
|
const { PlatformaticApp } = require('./app')
|
|
14
18
|
const { setupITC } = require('./itc')
|
|
15
19
|
const loadInterceptors = require('./interceptors')
|
|
@@ -78,10 +82,34 @@ async function main () {
|
|
|
78
82
|
}
|
|
79
83
|
}
|
|
80
84
|
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
const dispatcherOpts = { ...config.undici }
|
|
86
|
+
|
|
87
|
+
if (Object.keys(interceptors).length > 0) {
|
|
88
|
+
const clientInterceptors = []
|
|
89
|
+
const poolInterceptors = []
|
|
90
|
+
|
|
91
|
+
if (interceptors.Agent) {
|
|
92
|
+
clientInterceptors.push(...interceptors.Agent)
|
|
93
|
+
poolInterceptors.push(...interceptors.Agent)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (interceptors.Pool) {
|
|
97
|
+
poolInterceptors.push(...interceptors.Pool)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (interceptors.Client) {
|
|
101
|
+
clientInterceptors.push(...interceptors.Client)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
dispatcherOpts.factory = (origin, opts) => {
|
|
105
|
+
return opts && opts.connections === 1
|
|
106
|
+
? new undici.Client(origin, opts).compose(clientInterceptors)
|
|
107
|
+
: new undici.Pool(origin, opts).compose(poolInterceptors)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const globalDispatcher = new Agent(dispatcherOpts)
|
|
112
|
+
.compose(composedInterceptors)
|
|
85
113
|
|
|
86
114
|
setGlobalDispatcher(globalDispatcher)
|
|
87
115
|
|
|
@@ -90,6 +118,15 @@ async function main () {
|
|
|
90
118
|
// TODO: make this configurable
|
|
91
119
|
const threadDispatcher = wire({ port: parentPort, useNetwork: service.useHttp, timeout: 5 * 60 * 1000 })
|
|
92
120
|
|
|
121
|
+
if (config.httpCache) {
|
|
122
|
+
setGlobalDispatcher(
|
|
123
|
+
getGlobalDispatcher().compose(undici.interceptors.cache({
|
|
124
|
+
store: new RemoteCacheStore(),
|
|
125
|
+
methods: config.httpCache.methods ?? ['GET', 'HEAD']
|
|
126
|
+
}))
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
93
130
|
// If the service is an entrypoint and runtime server config is defined, use it.
|
|
94
131
|
let serverConfig = null
|
|
95
132
|
if (config.server && service.entrypoint) {
|
|
@@ -141,6 +178,13 @@ async function main () {
|
|
|
141
178
|
|
|
142
179
|
await app.init()
|
|
143
180
|
|
|
181
|
+
if (service.entrypoint && config.basePath) {
|
|
182
|
+
const meta = await app.stackable.getMeta()
|
|
183
|
+
if (!meta.wantsAbsoluteUrls) {
|
|
184
|
+
stripBasePath(config.basePath)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
144
188
|
// Setup interaction with parent port
|
|
145
189
|
const itc = setupITC(app, service, threadDispatcher)
|
|
146
190
|
|
|
@@ -152,5 +196,55 @@ async function main () {
|
|
|
152
196
|
globalThis[kITC] = itc
|
|
153
197
|
}
|
|
154
198
|
|
|
199
|
+
function stripBasePath (basePath) {
|
|
200
|
+
const kBasePath = Symbol('kBasePath')
|
|
201
|
+
|
|
202
|
+
diagnosticChannel.subscribe('http.server.request.start', ({ request, response }) => {
|
|
203
|
+
if (request.url.startsWith(basePath)) {
|
|
204
|
+
request.url = request.url.slice(basePath.length)
|
|
205
|
+
|
|
206
|
+
if (request.url.charAt(0) !== '/') {
|
|
207
|
+
request.url = '/' + request.url
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
response[kBasePath] = basePath
|
|
211
|
+
}
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
const originWriteHead = ServerResponse.prototype.writeHead
|
|
215
|
+
const originSetHeader = ServerResponse.prototype.setHeader
|
|
216
|
+
|
|
217
|
+
ServerResponse.prototype.writeHead = function (statusCode, statusMessage, headers) {
|
|
218
|
+
if (this[kBasePath] !== undefined) {
|
|
219
|
+
if (headers === undefined && typeof statusMessage === 'object') {
|
|
220
|
+
headers = statusMessage
|
|
221
|
+
statusMessage = undefined
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (headers) {
|
|
225
|
+
for (const key in headers) {
|
|
226
|
+
if (
|
|
227
|
+
key.toLowerCase() === 'location' &&
|
|
228
|
+
!headers[key].startsWith(basePath)
|
|
229
|
+
) {
|
|
230
|
+
headers[key] = basePath + headers[key]
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return originWriteHead.call(this, statusCode, statusMessage, headers)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
ServerResponse.prototype.setHeader = function (name, value) {
|
|
240
|
+
if (this[kBasePath]) {
|
|
241
|
+
if (name.toLowerCase() === 'location' && !value.startsWith(basePath)) {
|
|
242
|
+
value = basePath + value
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
originSetHeader.call(this, name, value)
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
155
249
|
// No need to catch this because there is the unhadledRejection handler on top.
|
|
156
250
|
main()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platformatic/runtime",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.1-alpha.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -35,17 +35,19 @@
|
|
|
35
35
|
"typescript": "^5.5.4",
|
|
36
36
|
"undici-oidc-interceptor": "^0.5.0",
|
|
37
37
|
"why-is-node-running": "^2.2.2",
|
|
38
|
-
"@platformatic/composer": "2.
|
|
39
|
-
"@platformatic/
|
|
40
|
-
"@platformatic/
|
|
41
|
-
"@platformatic/
|
|
42
|
-
"@platformatic/sql-graphql": "2.
|
|
38
|
+
"@platformatic/composer": "2.7.1-alpha.1",
|
|
39
|
+
"@platformatic/service": "2.7.1-alpha.1",
|
|
40
|
+
"@platformatic/db": "2.7.1-alpha.1",
|
|
41
|
+
"@platformatic/node": "2.7.1-alpha.1",
|
|
42
|
+
"@platformatic/sql-graphql": "2.7.1-alpha.1",
|
|
43
|
+
"@platformatic/sql-mapper": "2.7.1-alpha.1"
|
|
43
44
|
},
|
|
44
45
|
"dependencies": {
|
|
45
46
|
"@fastify/error": "^4.0.0",
|
|
46
47
|
"@fastify/websocket": "^11.0.0",
|
|
47
48
|
"@hapi/topo": "^6.0.2",
|
|
48
49
|
"@platformatic/http-metrics": "^0.2.1",
|
|
50
|
+
"@platformatic/undici-cache-memory": "^0.3.0",
|
|
49
51
|
"@watchable/unpromise": "^1.0.2",
|
|
50
52
|
"boring-name-generator": "^1.0.3",
|
|
51
53
|
"change-case-all": "^2.1.0",
|
|
@@ -67,16 +69,16 @@
|
|
|
67
69
|
"semgrator": "^0.3.0",
|
|
68
70
|
"tail-file-stream": "^0.2.0",
|
|
69
71
|
"thread-cpu-usage": "^0.2.0",
|
|
70
|
-
"undici": "
|
|
72
|
+
"undici": "7.0.0-alpha.3",
|
|
71
73
|
"undici-thread-interceptor": "^0.7.0",
|
|
72
74
|
"ws": "^8.16.0",
|
|
73
|
-
"@platformatic/
|
|
74
|
-
"@platformatic/
|
|
75
|
-
"@platformatic/generators": "2.
|
|
76
|
-
"@platformatic/
|
|
77
|
-
"@platformatic/ts-compiler": "2.
|
|
78
|
-
"@platformatic/
|
|
79
|
-
"@platformatic/utils": "2.
|
|
75
|
+
"@platformatic/config": "2.7.1-alpha.1",
|
|
76
|
+
"@platformatic/basic": "2.7.1-alpha.1",
|
|
77
|
+
"@platformatic/generators": "2.7.1-alpha.1",
|
|
78
|
+
"@platformatic/telemetry": "2.7.1-alpha.1",
|
|
79
|
+
"@platformatic/ts-compiler": "2.7.1-alpha.1",
|
|
80
|
+
"@platformatic/itc": "2.7.1-alpha.1",
|
|
81
|
+
"@platformatic/utils": "2.7.1-alpha.1"
|
|
80
82
|
},
|
|
81
83
|
"scripts": {
|
|
82
84
|
"test": "npm run lint && borp --concurrency=1 --timeout=180000 && tsd",
|
package/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.
|
|
2
|
+
"$id": "https://schemas.platformatic.dev/@platformatic/runtime/2.7.1-alpha.1.json",
|
|
3
3
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
4
4
|
"type": "object",
|
|
5
5
|
"properties": {
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
"entrypoint": {
|
|
14
14
|
"type": "string"
|
|
15
15
|
},
|
|
16
|
+
"basePath": {
|
|
17
|
+
"type": "string"
|
|
18
|
+
},
|
|
16
19
|
"autoload": {
|
|
17
20
|
"type": "object",
|
|
18
21
|
"additionalProperties": false,
|
|
@@ -379,6 +382,35 @@
|
|
|
379
382
|
}
|
|
380
383
|
}
|
|
381
384
|
},
|
|
385
|
+
"httpCache": {
|
|
386
|
+
"oneOf": [
|
|
387
|
+
{
|
|
388
|
+
"type": "boolean"
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
"type": "object",
|
|
392
|
+
"properties": {
|
|
393
|
+
"store": {
|
|
394
|
+
"type": "string"
|
|
395
|
+
},
|
|
396
|
+
"methods": {
|
|
397
|
+
"type": "array",
|
|
398
|
+
"items": {
|
|
399
|
+
"type": "string"
|
|
400
|
+
},
|
|
401
|
+
"default": [
|
|
402
|
+
"GET",
|
|
403
|
+
"HEAD"
|
|
404
|
+
],
|
|
405
|
+
"minItems": 1
|
|
406
|
+
},
|
|
407
|
+
"cacheTagsHeader": {
|
|
408
|
+
"type": "string"
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
]
|
|
413
|
+
},
|
|
382
414
|
"watch": {
|
|
383
415
|
"anyOf": [
|
|
384
416
|
{
|