@platformatic/runtime 3.68.0 → 4.0.0-new-config.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 +5 -44
- package/index.d.ts +10 -14
- package/index.js +191 -6
- package/lib/config.js +122 -111
- package/lib/errors.js +5 -17
- package/lib/generator.js +19 -92
- package/lib/management-api.js +3 -5
- package/lib/management-handlers.js +3 -5
- package/lib/runtime.js +377 -187
- package/lib/schema.js +1 -1
- package/lib/upgrade.js +16 -1
- package/lib/versions/v4.0.0.js +31 -0
- package/lib/worker/controller.js +51 -64
- package/lib/worker/itc.js +5 -6
- package/lib/worker/main.js +4 -19
- package/lib/worker/management.js +0 -4
- package/lib/worker/symbols.js +2 -0
- package/lib/worker-scaler.js +8 -10
- package/package.json +17 -16
- package/schema.json +33 -159
package/config.d.ts
CHANGED
|
@@ -29,7 +29,6 @@ export type PlatformaticRuntimeConfig = {
|
|
|
29
29
|
build?: boolean;
|
|
30
30
|
}
|
|
31
31
|
)[];
|
|
32
|
-
entrypoint?: string;
|
|
33
32
|
basePath?: string;
|
|
34
33
|
autoload?: {
|
|
35
34
|
path: string;
|
|
@@ -43,9 +42,11 @@ export type PlatformaticRuntimeConfig = {
|
|
|
43
42
|
| {
|
|
44
43
|
[k: string]: boolean;
|
|
45
44
|
};
|
|
46
|
-
config?:
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
config?:
|
|
46
|
+
| string
|
|
47
|
+
| {
|
|
48
|
+
[k: string]: unknown;
|
|
49
|
+
};
|
|
49
50
|
reuseTcpPorts?: boolean;
|
|
50
51
|
workers?:
|
|
51
52
|
| number
|
|
@@ -219,46 +220,6 @@ export type PlatformaticRuntimeConfig = {
|
|
|
219
220
|
};
|
|
220
221
|
[k: string]: unknown;
|
|
221
222
|
};
|
|
222
|
-
server?: {
|
|
223
|
-
hostname?: string;
|
|
224
|
-
port?: number | string;
|
|
225
|
-
/**
|
|
226
|
-
* Configures how entrypoint server worker ports are assigned. When set to shared, all workers listen on the same port. When set to perWorkerIncrement, each worker will use its own port, starting from port (worker 0).
|
|
227
|
-
*/
|
|
228
|
-
portAssignment?: "shared" | "perWorkerIncrement";
|
|
229
|
-
/**
|
|
230
|
-
* The maximum length of the queue of pending connections
|
|
231
|
-
*/
|
|
232
|
-
backlog?: number;
|
|
233
|
-
http2?: boolean;
|
|
234
|
-
https?: {
|
|
235
|
-
allowHTTP1?: boolean;
|
|
236
|
-
key:
|
|
237
|
-
| string
|
|
238
|
-
| {
|
|
239
|
-
path?: string;
|
|
240
|
-
}
|
|
241
|
-
| (
|
|
242
|
-
| string
|
|
243
|
-
| {
|
|
244
|
-
path?: string;
|
|
245
|
-
}
|
|
246
|
-
)[];
|
|
247
|
-
cert:
|
|
248
|
-
| string
|
|
249
|
-
| {
|
|
250
|
-
path?: string;
|
|
251
|
-
}
|
|
252
|
-
| (
|
|
253
|
-
| string
|
|
254
|
-
| {
|
|
255
|
-
path?: string;
|
|
256
|
-
}
|
|
257
|
-
)[];
|
|
258
|
-
requestCert?: boolean;
|
|
259
|
-
rejectUnauthorized?: boolean;
|
|
260
|
-
};
|
|
261
|
-
};
|
|
262
223
|
reuseTcpPorts?: boolean;
|
|
263
224
|
startTimeout?: number;
|
|
264
225
|
restartOnError?: boolean | number;
|
package/index.d.ts
CHANGED
|
@@ -37,6 +37,8 @@ export interface LoopbackMessagingOptions {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export namespace errors {
|
|
40
|
+
export const AddressInUseError: (port: number, firstApplication: string, secondApplication: string) => FastifyError
|
|
41
|
+
export const WorkerAddressInUseError: (port: number, application: string) => FastifyError
|
|
40
42
|
export const RuntimeExitedError: () => FastifyError
|
|
41
43
|
export const UnknownRuntimeAPICommandError: (command: string) => FastifyError
|
|
42
44
|
export const ApplicationNotFoundError: (id: string) => FastifyError
|
|
@@ -46,8 +48,6 @@ export namespace errors {
|
|
|
46
48
|
export const RuntimeNotStartedError: () => FastifyError
|
|
47
49
|
export const ConfigPathMustBeStringError: () => FastifyError
|
|
48
50
|
export const NoConfigFileFoundError: (id: string) => FastifyError
|
|
49
|
-
export const InvalidEntrypointError: (entrypoint: string) => FastifyError
|
|
50
|
-
export const MissingEntrypointError: () => FastifyError
|
|
51
51
|
export const MissingDependencyError: (dependency: string) => FastifyError
|
|
52
52
|
export const InspectAndInspectBrkError: () => FastifyError
|
|
53
53
|
export const InspectorPortError: () => FastifyError
|
|
@@ -89,6 +89,7 @@ export namespace symbols {
|
|
|
89
89
|
export const kLastWorkerScalerELU: unique symbol
|
|
90
90
|
export const kWorkerStatus: unique symbol
|
|
91
91
|
export const kWorkerHealthSignals: unique symbol
|
|
92
|
+
export const kWorkerUrl: unique symbol
|
|
92
93
|
export const kStderrMarker: string
|
|
93
94
|
export const kWorkersBroadcast: unique symbol
|
|
94
95
|
}
|
|
@@ -119,14 +120,13 @@ export interface ApplicationDetails {
|
|
|
119
120
|
dependencies?: string[]
|
|
120
121
|
version?: string
|
|
121
122
|
localUrl?: string
|
|
122
|
-
entrypoint?: boolean
|
|
123
123
|
sourceMaps?: boolean
|
|
124
124
|
workers?: number
|
|
125
125
|
url?: string | null
|
|
126
|
+
urls?: string[]
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
export interface ApplicationsTopology {
|
|
129
|
-
entrypoint: string
|
|
130
130
|
production: boolean
|
|
131
131
|
applications: ApplicationDetails[]
|
|
132
132
|
}
|
|
@@ -196,8 +196,8 @@ export interface RuntimeMetadata {
|
|
|
196
196
|
projectDir: string
|
|
197
197
|
packageName: string | null
|
|
198
198
|
packageVersion: string | null
|
|
199
|
-
url: string | null
|
|
200
199
|
platformaticVersion: string
|
|
200
|
+
urls: Record<string, string>
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
export interface WorkerLifecycleEvent {
|
|
@@ -234,9 +234,7 @@ export interface HealthMetricsEvent extends WorkerLifecycleEvent {
|
|
|
234
234
|
healthSignals: RuntimeHealthSignal[]
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
export
|
|
238
|
-
constructor (allowedOperations?: string[])
|
|
239
|
-
|
|
237
|
+
export interface ManagementClient {
|
|
240
238
|
getRuntimeStatus (): Promise<string>
|
|
241
239
|
getRuntimeMetadata (): Promise<RuntimeMetadata>
|
|
242
240
|
getRuntimeConfig (): Promise<Record<string, unknown>>
|
|
@@ -250,7 +248,6 @@ export declare class ManagementClient {
|
|
|
250
248
|
getApplicationOpenapiSchema (id: string): Promise<unknown>
|
|
251
249
|
getApplicationGraphqlSchema (id: string): Promise<unknown>
|
|
252
250
|
getMetrics (format?: string): Promise<{ metrics: unknown }>
|
|
253
|
-
getScheduler (): Promise<SchedulerJob[]>
|
|
254
251
|
getSchedulerJobs (): Promise<SchedulerJob[]>
|
|
255
252
|
pauseSchedulerJob (name: string): Promise<SchedulerJob>
|
|
256
253
|
resumeSchedulerJob (name: string): Promise<SchedulerJob>
|
|
@@ -258,7 +255,7 @@ export declare class ManagementClient {
|
|
|
258
255
|
startApplication (id: string): Promise<void>
|
|
259
256
|
stopApplication (id: string): Promise<void>
|
|
260
257
|
restartApplication (id: string): Promise<void>
|
|
261
|
-
restart (applications?: string[]): Promise<
|
|
258
|
+
restart (applications?: string[]): Promise<void>
|
|
262
259
|
addApplications (applications: unknown[], start?: boolean): Promise<ApplicationDetails[]>
|
|
263
260
|
removeApplications (ids: string[]): Promise<ApplicationDetails[]>
|
|
264
261
|
inject (id: string, injectParams: InjectParams): Promise<InjectResponse>
|
|
@@ -370,12 +367,11 @@ export type RuntimeExtension = (
|
|
|
370
367
|
|
|
371
368
|
export declare class Runtime extends EventEmitter {
|
|
372
369
|
init (): Promise<void>
|
|
373
|
-
start (silent?: boolean): Promise<string
|
|
370
|
+
start (silent?: boolean): Promise<Record<string, string>>
|
|
374
371
|
stop (silent?: boolean): Promise<void>
|
|
375
372
|
close (silent?: boolean): Promise<void>
|
|
376
|
-
restart (applications?: string[]): Promise<
|
|
373
|
+
restart (applications?: string[]): Promise<void>
|
|
377
374
|
inject (id: string, injectParams: InjectParams): Promise<InjectResponse>
|
|
378
|
-
getUrl (): string | undefined
|
|
379
375
|
getRuntimeStatus (): string
|
|
380
376
|
getRuntimeMetadata (): Promise<RuntimeMetadata>
|
|
381
377
|
getRuntimeEnv (): Record<string, string>
|
|
@@ -386,6 +382,7 @@ export declare class Runtime extends EventEmitter {
|
|
|
386
382
|
getRuntimeConfig (includeMeta: true): RuntimeConfiguration
|
|
387
383
|
getRuntimeConfig (includeMeta?: boolean): Record<string, unknown>
|
|
388
384
|
getApplicationsIds (): string[]
|
|
385
|
+
getUrls (applicationId?: string): Record<string, string>
|
|
389
386
|
/**
|
|
390
387
|
* Returns topology for every configured application.
|
|
391
388
|
* When `allowUnloaded` is `true`, applications without running workers are
|
|
@@ -463,7 +460,6 @@ export declare class Runtime extends EventEmitter {
|
|
|
463
460
|
off (event: 'application:worker:health:metrics', listener: (event: HealthMetricsEvent) => void): this
|
|
464
461
|
off (event: string | symbol, listener: (...args: any[]) => void): this
|
|
465
462
|
|
|
466
|
-
getScheduler (): SchedulerJob[]
|
|
467
463
|
getSchedulerJobs (): SchedulerJob[]
|
|
468
464
|
pauseSchedulerJob (name: string): Promise<SchedulerJob>
|
|
469
465
|
resumeSchedulerJob (name: string): Promise<SchedulerJob>
|
package/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolve, validationOptions } from '@platformatic/basic'
|
|
1
|
+
import { importCapabilityPackage, resolve, validationOptions } from '@platformatic/basic'
|
|
2
2
|
import {
|
|
3
3
|
abstractLogger,
|
|
4
4
|
ensureLoggableError,
|
|
@@ -8,9 +8,17 @@ import {
|
|
|
8
8
|
loadConfigurationModule,
|
|
9
9
|
loadConfiguration as utilsLoadConfiguration
|
|
10
10
|
} from '@platformatic/foundation'
|
|
11
|
+
import {
|
|
12
|
+
isConfigurationFileName,
|
|
13
|
+
findDecidingFile,
|
|
14
|
+
loadConfiguration as loadV4Configuration,
|
|
15
|
+
validateCapabilityConfiguration
|
|
16
|
+
} from '@platformatic/foundation/lib/v4/index.js'
|
|
11
17
|
import closeWithGrace from 'close-with-grace'
|
|
18
|
+
import { stat } from 'node:fs/promises'
|
|
12
19
|
import inspector from 'node:inspector'
|
|
13
|
-
import {
|
|
20
|
+
import { basename, dirname, resolve as resolvePath } from 'node:path'
|
|
21
|
+
import { transform as v3Transform, transformV4, wrapInRuntimeConfig } from './lib/config.js'
|
|
14
22
|
import { NodeInspectorFlagsNotSupportedError } from './lib/errors.js'
|
|
15
23
|
import { Runtime } from './lib/runtime.js'
|
|
16
24
|
import { schema } from './lib/schema.js'
|
|
@@ -59,7 +67,86 @@ function handleSignal (runtime, config) {
|
|
|
59
67
|
})
|
|
60
68
|
}
|
|
61
69
|
|
|
70
|
+
/*
|
|
71
|
+
v4 configuration is code, evaluated by the loader in foundation: it walks to the deciding file,
|
|
72
|
+
resolves both views of the env ladder, evaluates the root in a worker and fans out one worker per
|
|
73
|
+
per-app file. Everything the runtime transform used to discover — the application list, each
|
|
74
|
+
application's capability, its schema and its worker environment — arrives already resolved.
|
|
75
|
+
|
|
76
|
+
Routing by filename keeps the v3 path intact while the in-tree JSON fixtures are converted; the
|
|
77
|
+
v3 half is what a later commit deletes, not something this one has to keep working around.
|
|
78
|
+
*/
|
|
79
|
+
/*
|
|
80
|
+
A configuration named outright does not have to carry one of the four discoverable names -- that
|
|
81
|
+
is what discovery is for, and --config exists precisely to point at something discovery would not
|
|
82
|
+
find. What decides the dialect is the extension: v4 configuration is code, and v3 configuration is
|
|
83
|
+
a document.
|
|
84
|
+
*/
|
|
85
|
+
function isV4ConfigurationPath (path) {
|
|
86
|
+
return isConfigurationFileName(basename(path)) || /\.(js|mjs|ts|mts)$/.test(path)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function findV4ConfigurationFile (configOrRoot, sourceOrConfig) {
|
|
90
|
+
// A programmatic object source is not this path: the v4 object entry point is
|
|
91
|
+
// loadObjectConfiguration, which skips the root eval worker entirely.
|
|
92
|
+
if (sourceOrConfig && typeof sourceOrConfig !== 'string') {
|
|
93
|
+
return null
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (typeof sourceOrConfig === 'string') {
|
|
97
|
+
const named = resolvePath(configOrRoot, sourceOrConfig)
|
|
98
|
+
|
|
99
|
+
return isV4ConfigurationPath(named) ? named : null
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (typeof configOrRoot !== 'string') {
|
|
103
|
+
return null
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (isV4ConfigurationPath(configOrRoot)) {
|
|
107
|
+
return configOrRoot
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/*
|
|
111
|
+
Only an actual directory is a place to search from. findDecidingFile walks toward the env root,
|
|
112
|
+
so handing it a path that does not exist would answer with whatever project sits above it: a
|
|
113
|
+
typo'd --config would boot the parent rather than failing. v3 looks in the named directory and
|
|
114
|
+
nowhere else, and a wrong path has to stay an error.
|
|
115
|
+
*/
|
|
116
|
+
const stats = await stat(configOrRoot).catch(() => null)
|
|
117
|
+
|
|
118
|
+
if (!stats?.isDirectory()) {
|
|
119
|
+
return null
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const deciding = await findDecidingFile(configOrRoot, { throwOnMissing: false })
|
|
124
|
+
|
|
125
|
+
return deciding?.path ?? null
|
|
126
|
+
} catch (error) {
|
|
127
|
+
/*
|
|
128
|
+
The walk refuses a v3 configuration wherever it consults, which is right once v3 is gone and
|
|
129
|
+
wrong while it is still supported: here a v3 file means "this project is not v4", and the v3
|
|
130
|
+
loader below is the one that should answer. Deleting this catch is part of deleting the v3
|
|
131
|
+
path, and at that point the refusal becomes the correct answer again.
|
|
132
|
+
*/
|
|
133
|
+
if (error.code === 'PLT_LEGACY_CONFIGURATION_FILE') {
|
|
134
|
+
return null
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
throw error
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
62
141
|
export async function loadConfiguration (configOrRoot, sourceOrConfig, context) {
|
|
142
|
+
// Checked before the v3 resolver, which throws when it finds no v3 file — a v4-only project has
|
|
143
|
+
// none by construction.
|
|
144
|
+
const v4ConfigurationFile = await findV4ConfigurationFile(configOrRoot, sourceOrConfig)
|
|
145
|
+
|
|
146
|
+
if (v4ConfigurationFile) {
|
|
147
|
+
return loadV4RuntimeConfiguration(v4ConfigurationFile, context)
|
|
148
|
+
}
|
|
149
|
+
|
|
63
150
|
const { root, source } = await resolve(configOrRoot, sourceOrConfig, 'runtime')
|
|
64
151
|
|
|
65
152
|
// First of all, load the configuration without any validation
|
|
@@ -81,7 +168,7 @@ export async function loadConfiguration (configOrRoot, sourceOrConfig, context)
|
|
|
81
168
|
|
|
82
169
|
return utilsLoadConfiguration(source, context?.schema ?? schema, {
|
|
83
170
|
validationOptions,
|
|
84
|
-
transform,
|
|
171
|
+
transform: v3Transform,
|
|
85
172
|
upgrade,
|
|
86
173
|
replaceEnv: true,
|
|
87
174
|
root,
|
|
@@ -89,6 +176,86 @@ export async function loadConfiguration (configOrRoot, sourceOrConfig, context)
|
|
|
89
176
|
})
|
|
90
177
|
}
|
|
91
178
|
|
|
179
|
+
async function loadV4RuntimeConfiguration (configurationFile, context) {
|
|
180
|
+
const production = context?.isProduction ?? context?.production ?? false
|
|
181
|
+
|
|
182
|
+
/*
|
|
183
|
+
The environment the loader treats as real. An embedder can add to it, and can ask for a
|
|
184
|
+
hermetic runtime that sees none of this process's -- v3 honours both through loadEnv, and a v4
|
|
185
|
+
runtime that ignored them would quietly hand every worker the parent's environment.
|
|
186
|
+
*/
|
|
187
|
+
const realEnv = context?.ignoreProcessEnv ? { ...context?.env } : { ...process.env, ...context?.env }
|
|
188
|
+
|
|
189
|
+
const loaded = await loadV4Configuration({
|
|
190
|
+
cwd: dirname(configurationFile),
|
|
191
|
+
configPath: configurationFile,
|
|
192
|
+
realEnv,
|
|
193
|
+
command: context?.command ?? (production ? 'start' : 'dev'),
|
|
194
|
+
mode: context?.mode,
|
|
195
|
+
production,
|
|
196
|
+
customEnvFile: context?.envFile,
|
|
197
|
+
/*
|
|
198
|
+
Validation imports each capability's schema, so it needs the capability installed — not
|
|
199
|
+
merely declared, which is all the detector needs. That moves the moment a capability must be
|
|
200
|
+
resolvable earlier than v3 ever needed it: v3 loaded fine and failed later, in the worker.
|
|
201
|
+
|
|
202
|
+
A caller that is loading only to discover the topology — a tool about to install those
|
|
203
|
+
dependencies, for instance — can say so rather than being made to install first.
|
|
204
|
+
*/
|
|
205
|
+
validateCapabilities: context?.validateCapabilities ?? true,
|
|
206
|
+
// The runtime is where the bundled capability copies live, so it is the fallback scope for
|
|
207
|
+
// both the schema import and the version stamp — the application's own dependencies still
|
|
208
|
+
// come first.
|
|
209
|
+
runtimeScope: import.meta.filename,
|
|
210
|
+
onWarning: warning => abstractLogger.warn(warning.message),
|
|
211
|
+
onInfo: info => abstractLogger.info(info.message)
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
const config = loaded.config
|
|
215
|
+
|
|
216
|
+
/*
|
|
217
|
+
The documented pipeline is validation with useDefaults, then kMetadata, then transform. The eval
|
|
218
|
+
worker's own check is a shape check that injects nothing — deliberately, so the resolve
|
|
219
|
+
projection carries authored values — so this is where the runtime schema's defaults arrive, and
|
|
220
|
+
without it the runtime reaches for settings like gracefulShutdown that nothing supplied.
|
|
221
|
+
*/
|
|
222
|
+
validateCapabilityConfiguration(config, context?.schema ?? schema, {
|
|
223
|
+
id: 'runtime',
|
|
224
|
+
module: '@platformatic/runtime',
|
|
225
|
+
root: loaded.root
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
// kMetadata is symbol-keyed and cannot cross a worker boundary, so each worker rebuilds it; this
|
|
229
|
+
// is the main process's copy. env is the runtime's own view — every application worker gets the
|
|
230
|
+
// per-application environment the loader resolved, not this one.
|
|
231
|
+
config[kMetadata] = {
|
|
232
|
+
root: loaded.root,
|
|
233
|
+
path: loaded.configPath,
|
|
234
|
+
env: process.env,
|
|
235
|
+
module: '@platformatic/runtime',
|
|
236
|
+
/*
|
|
237
|
+
The evaluation context, kept beside the envelope rather than inside it: applications added
|
|
238
|
+
after boot are evaluated with the same command, mode and production flags the boot pass used,
|
|
239
|
+
and its presence is also what tells the add path this runtime is v4 at all. A v3 runtime has
|
|
240
|
+
no such context and keeps resolving configuration files worker-side.
|
|
241
|
+
*/
|
|
242
|
+
v4: {
|
|
243
|
+
command: context?.command ?? (production ? 'start' : 'dev'),
|
|
244
|
+
mode: loaded.mode,
|
|
245
|
+
production: loaded.production
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/*
|
|
250
|
+
A caller-supplied transform replaces the built-in one, exactly as it does on the v3 path where
|
|
251
|
+
it arrives as part of ...context. Ignoring it here meant a test helper or an embedder that
|
|
252
|
+
customized the configuration was silently not consulted.
|
|
253
|
+
*/
|
|
254
|
+
const apply = context?.transform ?? transformV4
|
|
255
|
+
|
|
256
|
+
return apply(config, null, context)
|
|
257
|
+
}
|
|
258
|
+
|
|
92
259
|
export async function loadApplicationsCommands (executableName = '', configurationFile = null) {
|
|
93
260
|
const applications = {}
|
|
94
261
|
const commands = {}
|
|
@@ -123,8 +290,16 @@ export async function loadApplicationsCommands (executableName = '', configurati
|
|
|
123
290
|
|
|
124
291
|
for (const application of config.applications) {
|
|
125
292
|
try {
|
|
126
|
-
|
|
127
|
-
|
|
293
|
+
/*
|
|
294
|
+
A v4 application arrives with its configuration already evaluated and its capability
|
|
295
|
+
already named, so there is nothing to read and nothing to infer. Reading application.config
|
|
296
|
+
as a path threw into the catch below, which skipped the application silently -- the command
|
|
297
|
+
it contributes then simply did not exist, and the CLI said the command was unknown.
|
|
298
|
+
*/
|
|
299
|
+
const applicationConfig = application.resolvedConfig ?? (await utilsLoadConfiguration(application.config))
|
|
300
|
+
const pkg = application.module
|
|
301
|
+
? await importCapabilityPackage(application.path, application.module)
|
|
302
|
+
: await loadConfigurationModule(application.path, applicationConfig)
|
|
128
303
|
|
|
129
304
|
if (pkg.createCommands) {
|
|
130
305
|
const definition = await pkg.createCommands(application.id)
|
|
@@ -175,7 +350,17 @@ export async function create (configOrRoot, sourceOrConfig, context) {
|
|
|
175
350
|
return runtime
|
|
176
351
|
}
|
|
177
352
|
|
|
178
|
-
export { prepareApplication,
|
|
353
|
+
export { prepareApplication, wrapInRuntimeConfig } from './lib/config.js'
|
|
354
|
+
|
|
355
|
+
/*
|
|
356
|
+
The exported transform dispatches on the dialect. Callers wrap it -- they call it and then adjust
|
|
357
|
+
the result -- and a wrapper that reached the v3 transform with a v4 configuration would run the
|
|
358
|
+
wrong pipeline over it: autoload expansion and enabled filtering have already happened in the
|
|
359
|
+
eval worker. v4 configurations are recognizable by the evaluation context on kMetadata.
|
|
360
|
+
*/
|
|
361
|
+
export async function transform (config, schema, context) {
|
|
362
|
+
return config?.[kMetadata]?.v4 ? transformV4(config, schema, context) : v3Transform(config, schema, context)
|
|
363
|
+
}
|
|
179
364
|
export * as errors from './lib/errors.js'
|
|
180
365
|
export { RuntimeGenerator as Generator, WrappedGenerator } from './lib/generator.js'
|
|
181
366
|
export { setupLoopbackMessaging } from './lib/loopback-messaging.js'
|