@platformatic/runtime 2.0.0-alpha.1 → 2.0.0-alpha.3
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 +285 -0
- package/eslint.config.js +8 -0
- package/fixtures/botched-start/platformatic.runtime.json +1 -1
- package/fixtures/botched-start/services/a/platformatic.service.json +1 -1
- package/fixtures/composerApp/platformatic.composer.json +1 -1
- package/fixtures/configs/invalid-autoload-with-services.json +1 -1
- package/fixtures/configs/invalid-entrypoint.json +1 -1
- package/fixtures/configs/invalid-schema-type.config.json +1 -1
- package/fixtures/configs/missing-property.config.json +1 -1
- package/fixtures/configs/missing-service-config.json +1 -1
- package/fixtures/configs/monorepo-composer-no-autoload.json +2 -2
- package/fixtures/configs/monorepo-composer.json +2 -2
- package/fixtures/configs/monorepo-create-cycle.json +2 -2
- package/fixtures/configs/monorepo-missing-dependencies.json +2 -2
- package/fixtures/configs/monorepo-no-cycles.json +2 -2
- package/fixtures/configs/monorepo-openapi.json +2 -2
- package/fixtures/configs/{monorepo-hotreload-env.json → monorepo-watch-env.json} +2 -2
- package/fixtures/configs/monorepo-watch-single.json +12 -0
- package/fixtures/configs/monorepo-watch.json +26 -9
- package/fixtures/configs/monorepo-with-dependencies.json +2 -2
- package/fixtures/configs/monorepo-with-management-api-without-metrics.json +21 -0
- package/fixtures/configs/monorepo-with-management-api.json +2 -2
- package/fixtures/configs/{monorepo-hotreload.json → monorepo-with-metrics.json} +5 -4
- package/fixtures/configs/monorepo.json +2 -2
- package/fixtures/configs/no-services.config.json +1 -1
- package/fixtures/configs/no-sources.config.json +1 -1
- package/fixtures/configs/service-throws-on-start.json +1 -1
- package/fixtures/configs/service-with-env-port.json +2 -2
- package/fixtures/configs/service-with-stdio.json +12 -0
- package/fixtures/configs/{hotreload.json → watch.json} +2 -2
- package/fixtures/dbApp/platformatic.db.json +1 -1
- package/fixtures/dbAppNoName/platformatic.db.json +1 -1
- package/fixtures/dbAppNoPackageJson/platformatic.db.json +1 -1
- package/fixtures/dbAppWithMigrationError/platformatic.db.json +1 -1
- package/fixtures/do-not-reload-dependencies/platformatic.service.json +1 -1
- package/fixtures/do-not-restart-on-crash/platformatic.runtime.json +3 -2
- package/fixtures/do-not-restart-on-crash/services/a/platformatic.service.json +1 -1
- package/fixtures/express/platformatic.runtime.json +1 -1
- package/fixtures/express/services/a/platformatic.service.json +1 -1
- package/fixtures/express/services/b/platformatic.service.json +1 -1
- package/fixtures/external-client/platformatic.service.json +1 -1
- package/fixtures/interceptors/idp.js +2 -2
- package/fixtures/interceptors/platformatic.runtime.json +1 -1
- package/fixtures/interceptors/services/a/platformatic.service.json +1 -1
- package/fixtures/interceptors-2/platformatic.runtime.json +1 -1
- package/fixtures/interceptors-2/services/a/platformatic.service.json +1 -1
- package/fixtures/leven/platformatic.runtime.json +2 -2
- package/fixtures/leven/services/deeply-spittle/platformatic.service.json +1 -1
- package/fixtures/leven/services/rainy-empire/platformatic.composer.json +1 -1
- package/fixtures/management-api/platformatic.json +3 -3
- package/fixtures/management-api/services/service-1/platformatic.json +1 -1
- package/fixtures/management-api/services/service-1/plugin.js +4 -3
- package/fixtures/management-api/services/service-2/platformatic.json +1 -1
- package/fixtures/management-api/services/service-db/platformatic.db.json +1 -1
- package/fixtures/management-api-custom-labels/platformatic.json +2 -2
- package/fixtures/management-api-custom-labels/services/service-1/platformatic.json +1 -1
- package/fixtures/management-api-custom-labels/services/service-1/plugin.js +4 -3
- package/fixtures/management-api-custom-labels/services/service-2/platformatic.json +1 -1
- package/fixtures/management-api-custom-labels/services/service-db/platformatic.db.json +1 -1
- package/fixtures/management-api-without-metrics/platformatic.json +3 -2
- package/fixtures/management-api-without-metrics/services/service-1/platformatic.json +1 -1
- package/fixtures/monorepo/composerApp/platformatic.composer.json +1 -1
- package/fixtures/monorepo/dbApp/platformatic.db.json +1 -1
- package/fixtures/monorepo/serviceApp/platformatic.service.json +3 -2
- package/fixtures/monorepo/serviceApp/with-logger/with-logger.cjs +2 -2
- package/fixtures/monorepo/serviceApp/with-logger/with-logger.d.ts +7 -7
- package/fixtures/monorepo/serviceAppWithLogger/platformatic.service.json +1 -1
- package/fixtures/monorepo/serviceAppWithLogger/plugin.js +12 -0
- package/fixtures/monorepo/serviceAppWithMultiplePlugins/platformatic.service.json +3 -2
- package/fixtures/monorepo-missing-dependencies/composer/platformatic.json +1 -1
- package/fixtures/monorepo-openapi/serviceAppWithoutOpenapi/platformatic.service.json +1 -1
- package/fixtures/monorepo-watch/service1/platformatic.service.json +1 -1
- package/fixtures/monorepo-with-dependencies/main/platformatic.json +1 -1
- package/fixtures/monorepo-with-dependencies/service-1/platformatic.json +1 -1
- package/fixtures/monorepo-with-dependencies/service-2/platformatic.json +1 -1
- package/fixtures/no-env.service.json +1 -1
- package/fixtures/preload/platformatic.runtime.json +1 -1
- package/fixtures/preload/services/a/platformatic.service.json +1 -1
- package/fixtures/prom-server/platformatic.json +2 -2
- package/fixtures/prom-server/services/service-1/platformatic.json +1 -1
- package/fixtures/prom-server/services/service-2/platformatic.json +1 -1
- package/fixtures/restart-on-crash/platformatic.runtime.json +1 -1
- package/fixtures/restart-on-crash/services/a/platformatic.service.json +1 -1
- package/fixtures/sample-runtime/package.json +1 -1
- package/fixtures/sample-runtime/platformatic.json +2 -2
- package/fixtures/sample-runtime/services/rival/package.json +1 -1
- package/fixtures/sample-runtime/services/rival/platformatic.json +1 -1
- package/fixtures/sample-runtime-with-2-services/package.json +1 -1
- package/fixtures/sample-runtime-with-2-services/platformatic.json +2 -2
- package/fixtures/sample-runtime-with-2-services/services/foobar/package.json +1 -1
- package/fixtures/sample-runtime-with-2-services/services/foobar/platformatic.json +1 -1
- package/fixtures/sample-runtime-with-2-services/services/rival/package.json +1 -1
- package/fixtures/sample-runtime-with-2-services/services/rival/platformatic.json +1 -1
- package/fixtures/server/logger-transport/platformatic.runtime.json +2 -2
- package/fixtures/server/logger-transport/services/echo/platformatic.service.json +1 -1
- package/fixtures/server/overrides-service/platformatic.runtime.json +2 -2
- package/fixtures/server/overrides-service/services/echo/platformatic.service.json +1 -1
- package/fixtures/server/runtime-server/platformatic.runtime.json +2 -2
- package/fixtures/server/runtime-server/services/echo/platformatic.service.json +1 -1
- package/fixtures/serviceAppThrowsOnStart/platformatic.service.json +1 -1
- package/fixtures/stackables/node_modules/foo/foo.js +2 -1
- package/fixtures/start-command-in-runtime.js +1 -1
- package/fixtures/stdio/platformatic.service.json +6 -0
- package/fixtures/stdio/plugin.js +24 -0
- package/fixtures/telemetry/platformatic.runtime.json +2 -2
- package/fixtures/telemetry/services/echo/platformatic.service.json +1 -1
- package/fixtures/typescript/platformatic.runtime.json +2 -2
- package/fixtures/typescript/services/composer/platformatic.composer.json +1 -1
- package/fixtures/typescript/services/movies/global.d.ts +2 -3
- package/fixtures/typescript/services/movies/platformatic.db.json +1 -1
- package/fixtures/typescript/services/movies/types/Movie.d.ts +3 -3
- package/fixtures/typescript/services/movies/types/index.d.ts +6 -6
- package/fixtures/typescript/services/titles/client/client.d.ts +35 -35
- package/fixtures/typescript/services/titles/platformatic.service.json +1 -1
- package/fixtures/typescript-custom-flags/platformatic.runtime.json +2 -2
- package/fixtures/typescript-custom-flags/services/composer/platformatic.composer.json +1 -1
- package/fixtures/typescript-custom-flags/services/movies/global.d.ts +2 -3
- package/fixtures/typescript-custom-flags/services/movies/platformatic.db.json +1 -1
- package/fixtures/typescript-custom-flags/services/movies/types/Movie.d.ts +3 -3
- package/fixtures/typescript-custom-flags/services/movies/types/index.d.ts +6 -6
- package/fixtures/typescript-custom-flags/services/titles/client/client.d.ts +35 -35
- package/fixtures/typescript-custom-flags/services/titles/platformatic.service.json +1 -1
- package/fixtures/typescript-no-env/platformatic.runtime.json +2 -2
- package/fixtures/typescript-no-env/services/composer/platformatic.composer.json +1 -1
- package/fixtures/typescript-no-env/services/movies/global.d.ts +2 -3
- package/fixtures/typescript-no-env/services/movies/platformatic.db.json +1 -1
- package/fixtures/typescript-no-env/services/movies/types/Movie.d.ts +3 -3
- package/fixtures/typescript-no-env/services/movies/types/index.d.ts +6 -6
- package/fixtures/typescript-no-env/services/titles/client/client.d.ts +35 -35
- package/fixtures/typescript-no-env/services/titles/platformatic.service.json +1 -1
- package/index.d.ts +7 -8
- package/index.js +14 -10
- package/index.test-d.ts +10 -12
- package/lib/build-server.js +5 -11
- package/lib/compile.js +11 -10
- package/lib/config.js +21 -14
- package/lib/dependencies.js +2 -1
- package/lib/errors.js +3 -2
- package/lib/generator/errors.js +1 -1
- package/lib/generator/runtime-generator.d.ts +15 -15
- package/lib/generator/runtime-generator.js +92 -63
- package/lib/logger.js +55 -0
- package/lib/management-api.js +29 -44
- package/lib/prom-server.js +5 -9
- package/lib/runtime.js +885 -0
- package/lib/schema.js +79 -76
- package/lib/start.js +35 -113
- package/lib/streams/message-port-writable.js +44 -0
- package/lib/streams/pino-writable.js +30 -0
- package/lib/upgrade.js +4 -3
- package/lib/utils.js +49 -1
- package/lib/versions/v1.36.0.js +1 -1
- package/lib/versions/v1.5.0.js +1 -1
- package/lib/versions/v2.0.0.js +17 -0
- package/lib/worker/app.js +224 -0
- package/lib/worker/default-stackable.js +27 -0
- package/lib/worker/itc.js +128 -0
- package/lib/worker/main.js +120 -0
- package/lib/worker/symbols.js +7 -0
- package/package.json +23 -25
- package/runtime.mjs +4 -4
- package/schema.json +824 -0
- package/lib/api-client.js +0 -500
- package/lib/api.js +0 -420
- package/lib/app.js +0 -397
- package/lib/load-config.js +0 -12
- package/lib/loader.mjs +0 -103
- package/lib/message-port-writable.js +0 -50
- package/lib/worker.js +0 -182
- /package/lib/{interceptors.js → worker/interceptors.js} +0 -0
package/lib/schema.js
CHANGED
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
|
|
4
4
|
const telemetry = require('@platformatic/telemetry').schema
|
|
5
5
|
const { schemas: { server } } = require('@platformatic/utils')
|
|
6
|
+
|
|
6
7
|
const pkg = require('../package.json')
|
|
7
|
-
const version = 'v' + pkg.version
|
|
8
8
|
const platformaticRuntimeSchema = {
|
|
9
|
-
$id: `https://platformatic.dev/
|
|
9
|
+
$id: `https://schemas.platformatic.dev/@platformatic/runtime/${pkg.version}.json`,
|
|
10
10
|
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
11
11
|
type: 'object',
|
|
12
12
|
properties: {
|
|
13
13
|
$schema: {
|
|
14
|
-
type: 'string'
|
|
14
|
+
type: 'string',
|
|
15
15
|
},
|
|
16
16
|
preload: {
|
|
17
17
|
type: 'string',
|
|
18
|
-
resolvePath: true
|
|
18
|
+
resolvePath: true,
|
|
19
19
|
},
|
|
20
20
|
autoload: {
|
|
21
21
|
type: 'object',
|
|
@@ -24,106 +24,106 @@ const platformaticRuntimeSchema = {
|
|
|
24
24
|
properties: {
|
|
25
25
|
path: {
|
|
26
26
|
type: 'string',
|
|
27
|
-
resolvePath: true
|
|
27
|
+
resolvePath: true,
|
|
28
28
|
},
|
|
29
29
|
exclude: {
|
|
30
30
|
type: 'array',
|
|
31
31
|
default: [],
|
|
32
32
|
items: {
|
|
33
|
-
type: 'string'
|
|
34
|
-
}
|
|
33
|
+
type: 'string',
|
|
34
|
+
},
|
|
35
35
|
},
|
|
36
36
|
mappings: {
|
|
37
37
|
type: 'object',
|
|
38
38
|
additionalProperties: {
|
|
39
39
|
type: 'object',
|
|
40
40
|
additionalProperties: false,
|
|
41
|
-
required: ['id'
|
|
41
|
+
required: ['id'],
|
|
42
42
|
properties: {
|
|
43
43
|
id: {
|
|
44
|
-
type: 'string'
|
|
44
|
+
type: 'string',
|
|
45
45
|
},
|
|
46
46
|
config: {
|
|
47
|
-
type: 'string'
|
|
47
|
+
type: 'string',
|
|
48
48
|
},
|
|
49
49
|
useHttp: {
|
|
50
|
-
type: 'boolean'
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
50
|
+
type: 'boolean',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
56
|
},
|
|
57
57
|
telemetry,
|
|
58
58
|
server,
|
|
59
59
|
entrypoint: {
|
|
60
|
-
type: 'string'
|
|
60
|
+
type: 'string',
|
|
61
61
|
},
|
|
62
|
-
|
|
62
|
+
watch: {
|
|
63
63
|
anyOf: [
|
|
64
64
|
{
|
|
65
|
-
type: 'boolean'
|
|
65
|
+
type: 'boolean',
|
|
66
66
|
},
|
|
67
67
|
{
|
|
68
|
-
type: 'string'
|
|
69
|
-
}
|
|
70
|
-
]
|
|
68
|
+
type: 'string',
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
71
|
},
|
|
72
72
|
inspectorOptions: {
|
|
73
73
|
type: 'object',
|
|
74
74
|
properties: {
|
|
75
75
|
host: {
|
|
76
|
-
type: 'string'
|
|
76
|
+
type: 'string',
|
|
77
77
|
},
|
|
78
78
|
port: {
|
|
79
|
-
type: 'number'
|
|
79
|
+
type: 'number',
|
|
80
80
|
},
|
|
81
81
|
breakFirstLine: {
|
|
82
|
-
type: 'boolean'
|
|
82
|
+
type: 'boolean',
|
|
83
83
|
},
|
|
84
|
-
|
|
85
|
-
type: 'boolean'
|
|
86
|
-
}
|
|
87
|
-
}
|
|
84
|
+
watchDisabled: {
|
|
85
|
+
type: 'boolean',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
88
|
},
|
|
89
89
|
undici: {
|
|
90
90
|
type: 'object',
|
|
91
91
|
properties: {
|
|
92
92
|
agentOptions: {
|
|
93
93
|
type: 'object',
|
|
94
|
-
additionalProperties: true
|
|
94
|
+
additionalProperties: true,
|
|
95
95
|
},
|
|
96
96
|
interceptors: {
|
|
97
97
|
anyOf: [{
|
|
98
98
|
type: 'array',
|
|
99
99
|
items: {
|
|
100
|
-
$ref: '#/$defs/undiciInterceptor'
|
|
101
|
-
}
|
|
100
|
+
$ref: '#/$defs/undiciInterceptor',
|
|
101
|
+
},
|
|
102
102
|
}, {
|
|
103
103
|
type: 'object',
|
|
104
104
|
properties: {
|
|
105
105
|
Client: {
|
|
106
106
|
type: 'array',
|
|
107
107
|
items: {
|
|
108
|
-
$ref: '#/$defs/undiciInterceptor'
|
|
109
|
-
}
|
|
108
|
+
$ref: '#/$defs/undiciInterceptor',
|
|
109
|
+
},
|
|
110
110
|
},
|
|
111
111
|
Pool: {
|
|
112
112
|
type: 'array',
|
|
113
113
|
items: {
|
|
114
|
-
$ref: '#/$defs/undiciInterceptor'
|
|
115
|
-
}
|
|
114
|
+
$ref: '#/$defs/undiciInterceptor',
|
|
115
|
+
},
|
|
116
116
|
},
|
|
117
117
|
Agent: {
|
|
118
118
|
type: 'array',
|
|
119
119
|
items: {
|
|
120
|
-
$ref: '#/$defs/undiciInterceptor'
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}]
|
|
125
|
-
}
|
|
126
|
-
}
|
|
120
|
+
$ref: '#/$defs/undiciInterceptor',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
}],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
127
|
},
|
|
128
128
|
managementApi: {
|
|
129
129
|
anyOf: [
|
|
@@ -136,14 +136,14 @@ const platformaticRuntimeSchema = {
|
|
|
136
136
|
maxSize: {
|
|
137
137
|
type: 'number',
|
|
138
138
|
minimum: 5,
|
|
139
|
-
default: 200
|
|
140
|
-
}
|
|
141
|
-
}
|
|
139
|
+
default: 200,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
142
|
},
|
|
143
|
-
additionalProperties: false
|
|
144
|
-
}
|
|
143
|
+
additionalProperties: false,
|
|
144
|
+
},
|
|
145
145
|
],
|
|
146
|
-
default: true
|
|
146
|
+
default: true,
|
|
147
147
|
},
|
|
148
148
|
metrics: {
|
|
149
149
|
anyOf: [
|
|
@@ -154,8 +154,8 @@ const platformaticRuntimeSchema = {
|
|
|
154
154
|
port: {
|
|
155
155
|
anyOf: [
|
|
156
156
|
{ type: 'integer' },
|
|
157
|
-
{ type: 'string' }
|
|
158
|
-
]
|
|
157
|
+
{ type: 'string' },
|
|
158
|
+
],
|
|
159
159
|
},
|
|
160
160
|
hostname: { type: 'string' },
|
|
161
161
|
endpoint: { type: 'string' },
|
|
@@ -163,53 +163,56 @@ const platformaticRuntimeSchema = {
|
|
|
163
163
|
type: 'object',
|
|
164
164
|
properties: {
|
|
165
165
|
username: { type: 'string' },
|
|
166
|
-
password: { type: 'string' }
|
|
166
|
+
password: { type: 'string' },
|
|
167
167
|
},
|
|
168
168
|
additionalProperties: false,
|
|
169
|
-
required: ['username', 'password']
|
|
169
|
+
required: ['username', 'password'],
|
|
170
170
|
},
|
|
171
171
|
labels: {
|
|
172
172
|
type: 'object',
|
|
173
|
-
additionalProperties: { type: 'string' }
|
|
174
|
-
}
|
|
173
|
+
additionalProperties: { type: 'string' },
|
|
174
|
+
},
|
|
175
175
|
},
|
|
176
|
-
additionalProperties: false
|
|
177
|
-
}
|
|
178
|
-
]
|
|
176
|
+
additionalProperties: false,
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
179
|
},
|
|
180
180
|
restartOnError: {
|
|
181
181
|
default: true,
|
|
182
182
|
anyOf: [
|
|
183
183
|
{ type: 'boolean' },
|
|
184
|
-
{
|
|
185
|
-
|
|
184
|
+
{
|
|
185
|
+
type: 'number',
|
|
186
|
+
minimum: 100,
|
|
187
|
+
},
|
|
188
|
+
],
|
|
186
189
|
},
|
|
187
190
|
services: {
|
|
188
191
|
type: 'array',
|
|
189
192
|
items: {
|
|
190
193
|
type: 'object',
|
|
191
|
-
required: ['id', 'path'
|
|
194
|
+
required: ['id', 'path'],
|
|
192
195
|
properties: {
|
|
193
196
|
id: {
|
|
194
|
-
type: 'string'
|
|
197
|
+
type: 'string',
|
|
195
198
|
},
|
|
196
199
|
path: {
|
|
197
200
|
type: 'string',
|
|
198
|
-
resolvePath: true
|
|
201
|
+
resolvePath: true,
|
|
199
202
|
},
|
|
200
203
|
config: {
|
|
201
|
-
type: 'string'
|
|
204
|
+
type: 'string',
|
|
202
205
|
},
|
|
203
206
|
useHttp: {
|
|
204
|
-
type: 'boolean'
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
207
|
+
type: 'boolean',
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
209
212
|
},
|
|
210
213
|
anyOf: [
|
|
211
214
|
{ required: ['autoload', 'entrypoint'] },
|
|
212
|
-
{ required: ['services', 'entrypoint'] }
|
|
215
|
+
{ required: ['services', 'entrypoint'] },
|
|
213
216
|
],
|
|
214
217
|
additionalProperties: false,
|
|
215
218
|
$defs: {
|
|
@@ -217,16 +220,16 @@ const platformaticRuntimeSchema = {
|
|
|
217
220
|
type: 'object',
|
|
218
221
|
properties: {
|
|
219
222
|
module: {
|
|
220
|
-
type: 'string'
|
|
223
|
+
type: 'string',
|
|
221
224
|
},
|
|
222
225
|
options: {
|
|
223
226
|
type: 'object',
|
|
224
|
-
additionalProperties: true
|
|
225
|
-
}
|
|
227
|
+
additionalProperties: true,
|
|
228
|
+
},
|
|
226
229
|
},
|
|
227
|
-
required: ['module', 'options']
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
+
required: ['module', 'options'],
|
|
231
|
+
},
|
|
232
|
+
},
|
|
230
233
|
}
|
|
231
234
|
|
|
232
235
|
module.exports.schema = platformaticRuntimeSchema
|
package/lib/start.js
CHANGED
|
@@ -1,46 +1,22 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { once } = require('node:events')
|
|
4
3
|
const inspector = require('node:inspector')
|
|
5
|
-
const { join, resolve, dirname } = require('node:path')
|
|
6
4
|
const { writeFile } = require('node:fs/promises')
|
|
7
|
-
const {
|
|
8
|
-
|
|
5
|
+
const { join, resolve, dirname } = require('node:path')
|
|
6
|
+
|
|
9
7
|
const { printConfigValidationErrors } = require('@platformatic/config')
|
|
10
8
|
const closeWithGrace = require('close-with-grace')
|
|
11
|
-
const { loadConfig } = require('./load-config')
|
|
12
|
-
const { startManagementApi } = require('./management-api')
|
|
13
|
-
const { startPrometheusServer } = require('./prom-server.js')
|
|
14
|
-
const { parseInspectorOptions, wrapConfigInRuntimeConfig } = require('./config')
|
|
15
|
-
const { RuntimeApiClient, getRuntimeLogsDir } = require('./api-client.js')
|
|
16
|
-
const errors = require('./errors')
|
|
17
|
-
const pkg = require('../package.json')
|
|
18
9
|
const pino = require('pino')
|
|
19
10
|
const pretty = require('pino-pretty')
|
|
20
11
|
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
kLoaderFile
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
function startWorker ({ config, dirname, runtimeLogsDir }, env) {
|
|
30
|
-
const worker = new Worker(kWorkerFile, {
|
|
31
|
-
/* c8 ignore next */
|
|
32
|
-
execArgv: config.hotReload ? kWorkerExecArgv : [],
|
|
33
|
-
transferList: config.loggingPort ? [config.loggingPort] : [],
|
|
34
|
-
workerData: { config, dirname, runtimeLogsDir },
|
|
35
|
-
env
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
return worker
|
|
39
|
-
}
|
|
12
|
+
const pkg = require('../package.json')
|
|
13
|
+
const { parseInspectorOptions, wrapConfigInRuntimeConfig } = require('./config')
|
|
14
|
+
const { Runtime } = require('./runtime')
|
|
15
|
+
const errors = require('./errors')
|
|
16
|
+
const { getRuntimeLogsDir, loadConfig } = require('./utils')
|
|
40
17
|
|
|
41
18
|
async function buildRuntime (configManager, env) {
|
|
42
19
|
env = env || process.env
|
|
43
|
-
const config = configManager.current
|
|
44
20
|
|
|
45
21
|
if (inspector.url()) {
|
|
46
22
|
throw new errors.NodeInspectorFlagsNotSupportedError()
|
|
@@ -50,80 +26,24 @@ async function buildRuntime (configManager, env) {
|
|
|
50
26
|
parseInspectorOptions(configManager)
|
|
51
27
|
}
|
|
52
28
|
|
|
53
|
-
if (config.hotReload) {
|
|
54
|
-
config.loaderFile = kLoaderFile
|
|
55
|
-
}
|
|
56
|
-
|
|
57
29
|
const dirname = configManager.dirname
|
|
58
30
|
const runtimeLogsDir = getRuntimeLogsDir(dirname, process.pid)
|
|
59
31
|
|
|
60
|
-
|
|
61
|
-
delete config.configManager
|
|
62
|
-
|
|
63
|
-
let worker = startWorker({ config, dirname, runtimeLogsDir }, env)
|
|
64
|
-
|
|
65
|
-
let managementApi = null
|
|
66
|
-
|
|
67
|
-
if (config.hotReload) {
|
|
68
|
-
/* c8 ignore next 3 */
|
|
69
|
-
process.on('SIGUSR2', () => {
|
|
70
|
-
worker.postMessage({ signal: 'SIGUSR2' })
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
/* c8 ignore next 3 */
|
|
74
|
-
configManager.on('update', () => {
|
|
75
|
-
// TODO(cjihrig): Need to clean up and restart the worker.
|
|
76
|
-
})
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function setupExit () {
|
|
80
|
-
worker.on('exit', (code) => {
|
|
81
|
-
// runtimeApiClient.started can be false if a stop command was issued
|
|
82
|
-
// via the management API.
|
|
83
|
-
if (config.restartOnError === false || !runtimeApiClient.started) {
|
|
84
|
-
// We must stop those here in case the `closeWithGrace` callback
|
|
85
|
-
// was not called.
|
|
86
|
-
configManager.fileWatcher?.stopWatching()
|
|
87
|
-
managementApi?.close()
|
|
88
|
-
return
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
worker = startWorker({ config, dirname, runtimeLogsDir }, env)
|
|
92
|
-
setupExit()
|
|
93
|
-
|
|
94
|
-
once(worker, 'message').then((msg) => {
|
|
95
|
-
runtimeApiClient.setWorker(worker).catch(() => {
|
|
96
|
-
// TODO: currently we restart if the worker fails to start intermitently
|
|
97
|
-
// should we limit this to a number of retries?
|
|
98
|
-
})
|
|
99
|
-
})
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
setupExit()
|
|
104
|
-
|
|
105
|
-
await once(worker, 'message') // plt:init
|
|
32
|
+
const runtime = new Runtime(configManager, runtimeLogsDir, env)
|
|
106
33
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
runtimeLogsDir
|
|
111
|
-
)
|
|
34
|
+
/* c8 ignore next 3 */
|
|
35
|
+
process.on('SIGUSR2', async () => {
|
|
36
|
+
runtime.logger.info('Received SIGUSR2, restarting all services ...')
|
|
112
37
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
if (config.metrics) {
|
|
121
|
-
runtimeApiClient.on('start', async () => {
|
|
122
|
-
await startPrometheusServer(runtimeApiClient, config.metrics)
|
|
123
|
-
})
|
|
124
|
-
}
|
|
38
|
+
try {
|
|
39
|
+
await runtime.restart()
|
|
40
|
+
} catch (err) {
|
|
41
|
+
runtime.logger.error({ err }, 'Failed to restart services.')
|
|
42
|
+
}
|
|
43
|
+
})
|
|
125
44
|
|
|
126
|
-
|
|
45
|
+
await runtime.init()
|
|
46
|
+
return runtime
|
|
127
47
|
}
|
|
128
48
|
|
|
129
49
|
async function start (args) {
|
|
@@ -155,15 +75,15 @@ async function setupAndStartRuntime (config) {
|
|
|
155
75
|
let runtime = await buildRuntime(runtimeConfig)
|
|
156
76
|
|
|
157
77
|
let address = null
|
|
158
|
-
|
|
78
|
+
const startErr = null
|
|
159
79
|
const originalPort = runtimeConfig.current.server?.port || 0
|
|
160
80
|
while (address === null) {
|
|
161
81
|
try {
|
|
162
82
|
address = await runtime.start()
|
|
163
83
|
} catch (err) {
|
|
164
|
-
startErr = err
|
|
165
84
|
if (err.code === 'EADDRINUSE') {
|
|
166
85
|
await runtime.close()
|
|
86
|
+
|
|
167
87
|
if (runtimeConfig.current?.server?.port > MAX_PORT) throw err
|
|
168
88
|
runtimeConfig.current.server.port++
|
|
169
89
|
runtime = await buildRuntime(runtimeConfig)
|
|
@@ -173,10 +93,12 @@ async function setupAndStartRuntime (config) {
|
|
|
173
93
|
}
|
|
174
94
|
}
|
|
175
95
|
if (startErr?.code === 'PLT_RUNTIME_EADDR_IN_USE') {
|
|
176
|
-
const logger = pino(
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
96
|
+
const logger = pino(
|
|
97
|
+
pretty({
|
|
98
|
+
translateTime: 'SYS:HH:MM:ss',
|
|
99
|
+
ignore: 'hostname,pid',
|
|
100
|
+
})
|
|
101
|
+
)
|
|
180
102
|
logger.warn(`Port: ${originalPort} is already in use!`)
|
|
181
103
|
logger.warn(`Starting service on port: ${runtimeConfig.current.server.port}`)
|
|
182
104
|
}
|
|
@@ -192,7 +114,7 @@ async function startCommand (args) {
|
|
|
192
114
|
const runtime = startResult.runtime
|
|
193
115
|
const res = startResult.address
|
|
194
116
|
|
|
195
|
-
closeWithGrace(async
|
|
117
|
+
closeWithGrace(async event => {
|
|
196
118
|
if (event.err instanceof Error) {
|
|
197
119
|
console.error(event.err)
|
|
198
120
|
}
|
|
@@ -203,21 +125,21 @@ async function startCommand (args) {
|
|
|
203
125
|
} catch (err) {
|
|
204
126
|
if (err.code === 'PLT_CONFIG_NO_CONFIG_FILE_FOUND' && args.length === 1) {
|
|
205
127
|
const config = {
|
|
206
|
-
$schema: `https://platformatic.dev/
|
|
128
|
+
$schema: `https://schemas.platformatic.dev/@platformatic/service/${pkg.version}.json`,
|
|
207
129
|
server: {
|
|
208
130
|
hostname: '127.0.0.1',
|
|
209
131
|
port: 3042,
|
|
210
132
|
logger: {
|
|
211
|
-
level: 'info'
|
|
212
|
-
}
|
|
133
|
+
level: 'info',
|
|
134
|
+
},
|
|
213
135
|
},
|
|
214
136
|
plugins: {
|
|
215
|
-
paths: [args[0]]
|
|
137
|
+
paths: [args[0]],
|
|
216
138
|
},
|
|
217
139
|
service: {
|
|
218
|
-
openapi: true
|
|
140
|
+
openapi: true,
|
|
219
141
|
},
|
|
220
|
-
watch: true
|
|
142
|
+
watch: true,
|
|
221
143
|
}
|
|
222
144
|
const toWrite = join(dirname(resolve(args[0])), 'platformatic.service.json')
|
|
223
145
|
console.log(`No config file found, creating ${join(dirname(args[0]), 'platformatic.service.json')}`)
|
|
@@ -229,7 +151,7 @@ async function startCommand (args) {
|
|
|
229
151
|
console.error(`Missing config file!
|
|
230
152
|
Be sure to have a config file with one of the following names:
|
|
231
153
|
|
|
232
|
-
${err.filenames.map(
|
|
154
|
+
${err.filenames.map(s => ' * ' + s).join('\n')}
|
|
233
155
|
|
|
234
156
|
In alternative run "npm create platformatic@latest" to generate a basic plt service config.`)
|
|
235
157
|
process.exit(1)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { Writable } = require('node:stream')
|
|
4
|
+
|
|
5
|
+
class MessagePortWritable extends Writable {
|
|
6
|
+
#port
|
|
7
|
+
#metadata
|
|
8
|
+
|
|
9
|
+
constructor (options) {
|
|
10
|
+
const { port, metadata, ...opts } = options
|
|
11
|
+
|
|
12
|
+
super({ ...opts, decodeStrings: false })
|
|
13
|
+
this.#port = port
|
|
14
|
+
this.#metadata = metadata
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Since this is only invoked by pino, we only receive strings
|
|
18
|
+
_write (chunk, encoding, callback) {
|
|
19
|
+
this.#port.postMessage({ metadata: this.#metadata, logs: [chunk.toString(encoding ?? 'utf-8')] })
|
|
20
|
+
|
|
21
|
+
// Important: do not remove nextTick otherwise _writev will never be used
|
|
22
|
+
process.nextTick(callback)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Since this is only invoked by pino, we only receive strings
|
|
26
|
+
_writev (chunks, callback) {
|
|
27
|
+
this.#port.postMessage({ metadata: this.#metadata, logs: chunks.map(c => c.chunk.toString(c.encoding ?? 'utf-8')) })
|
|
28
|
+
|
|
29
|
+
// Important: do not remove nextTick otherwise _writev will never be used
|
|
30
|
+
process.nextTick(callback)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
_final (callback) {
|
|
34
|
+
this.#port.close()
|
|
35
|
+
callback()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
_destroy (err, callback) {
|
|
39
|
+
this.#port.close()
|
|
40
|
+
callback(err)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = { MessagePortWritable }
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { Writable } = require('node:stream')
|
|
4
|
+
const inspect = require('node:util')
|
|
5
|
+
|
|
6
|
+
class PinoWritable extends Writable {
|
|
7
|
+
#write
|
|
8
|
+
|
|
9
|
+
constructor (options) {
|
|
10
|
+
const { pino, level, ...opts } = options
|
|
11
|
+
|
|
12
|
+
super({ ...opts, decodeStrings: false })
|
|
13
|
+
this.#write = pino[level].bind(pino)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
_write (chunk, encoding, callback) {
|
|
17
|
+
this.#write({ raw: encoding === 'buffer' ? inspect(chunk) : chunk.toString(encoding ?? 'utf-8') })
|
|
18
|
+
callback()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// We don't define _writev as we have to serialize messages one by one so batching wouldn't make any sense.
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function createPinoWritable (pino, level) {
|
|
25
|
+
const writable = new PinoWritable({ pino, level })
|
|
26
|
+
writable.write = writable.write.bind(writable)
|
|
27
|
+
return writable
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = { PinoWritable, createPinoWritable }
|
package/lib/upgrade.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { join } = require('path')
|
|
3
|
+
const { join } = require('node:path')
|
|
4
|
+
|
|
4
5
|
const pkg = require('../package.json')
|
|
5
6
|
|
|
6
7
|
module.exports = async function upgrade (config, version) {
|
|
@@ -10,7 +11,7 @@ module.exports = async function upgrade (config, version) {
|
|
|
10
11
|
version,
|
|
11
12
|
path: join(__dirname, 'versions'),
|
|
12
13
|
input: config,
|
|
13
|
-
logger: this.logger.child({ name: '@platformatic/runtime' })
|
|
14
|
+
logger: this.logger.child({ name: '@platformatic/runtime' }),
|
|
14
15
|
})
|
|
15
16
|
|
|
16
17
|
let result
|
|
@@ -19,7 +20,7 @@ module.exports = async function upgrade (config, version) {
|
|
|
19
20
|
result = updated.result
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
result.$schema = `https://platformatic.dev/
|
|
23
|
+
result.$schema = `https://schemas.platformatic.dev/@platformatic/runtime/${pkg.version}.json`
|
|
23
24
|
|
|
24
25
|
return result
|
|
25
26
|
}
|
package/lib/utils.js
CHANGED
|
@@ -1,10 +1,58 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
+
|
|
3
|
+
const { createHash } = require('node:crypto')
|
|
4
|
+
const { tmpdir } = require('node:os')
|
|
5
|
+
const { join } = require('node:path')
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
Store,
|
|
9
|
+
loadConfig: pltConfigLoadConfig,
|
|
10
|
+
loadEmptyConfig: pltConfigLoadEmptyConfig,
|
|
11
|
+
} = require('@platformatic/config')
|
|
12
|
+
|
|
13
|
+
const { platformaticRuntime } = require('./config')
|
|
14
|
+
|
|
2
15
|
function getArrayDifference (a, b) {
|
|
3
16
|
return a.filter(element => {
|
|
4
17
|
return !b.includes(element)
|
|
5
18
|
})
|
|
6
19
|
}
|
|
7
20
|
|
|
21
|
+
function getServiceUrl (id) {
|
|
22
|
+
return `http://${id}.plt.local`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getRuntimeTmpDir (runtimeDir) {
|
|
26
|
+
const platformaticTmpDir = join(tmpdir(), 'platformatic', 'applications')
|
|
27
|
+
const runtimeDirHash = createHash('md5').update(runtimeDir).digest('hex')
|
|
28
|
+
return join(platformaticTmpDir, runtimeDirHash)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getRuntimeLogsDir (runtimeDir, runtimePID) {
|
|
32
|
+
const runtimeTmpDir = getRuntimeTmpDir(runtimeDir)
|
|
33
|
+
return join(runtimeTmpDir, runtimePID.toString(), 'logs')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function loadConfig (minimistConfig, args, overrides, replaceEnv = true) {
|
|
37
|
+
const { default: platformaticBasic } = await import('@platformatic/basic')
|
|
38
|
+
const store = new Store()
|
|
39
|
+
store.add(platformaticRuntime)
|
|
40
|
+
store.add(platformaticBasic)
|
|
41
|
+
|
|
42
|
+
return pltConfigLoadConfig(minimistConfig, args, store, overrides, replaceEnv)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function loadEmptyConfig (path, overrides, replaceEnv = true) {
|
|
46
|
+
const { default: platformaticBasic } = await import('@platformatic/basic')
|
|
47
|
+
|
|
48
|
+
return pltConfigLoadEmptyConfig(path, platformaticBasic, overrides, replaceEnv)
|
|
49
|
+
}
|
|
50
|
+
|
|
8
51
|
module.exports = {
|
|
9
|
-
getArrayDifference
|
|
52
|
+
getArrayDifference,
|
|
53
|
+
getRuntimeLogsDir,
|
|
54
|
+
getRuntimeTmpDir,
|
|
55
|
+
getServiceUrl,
|
|
56
|
+
loadConfig,
|
|
57
|
+
loadEmptyConfig,
|
|
10
58
|
}
|