@backstage/backend-defaults 0.17.4-next.0 → 0.17.4
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/CHANGELOG.md +2 -10
- package/config.d.ts +1475 -0
- package/dist/entrypoints/scheduler/lib/TaskWorker.cjs.js +4 -2
- package/dist/entrypoints/scheduler/lib/TaskWorker.cjs.js.map +1 -1
- package/dist/entrypoints/urlReader/lib/AwsS3UrlReader.cjs.js +26 -45
- package/dist/entrypoints/urlReader/lib/AwsS3UrlReader.cjs.js.map +1 -1
- package/dist/package.json.cjs.js +1 -1
- package/package.json +19 -19
- package/config.schema.json +0 -2396
package/config.d.ts
ADDED
|
@@ -0,0 +1,1475 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2020 The Backstage Authors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { HumanDuration, JsonObject } from '@backstage/types';
|
|
18
|
+
|
|
19
|
+
export interface Config {
|
|
20
|
+
app: {
|
|
21
|
+
baseUrl: string; // defined in core, but repeated here without doc
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
backend?: {
|
|
25
|
+
/**
|
|
26
|
+
* The full base URL of the backend, as seen from the browser's point of
|
|
27
|
+
* view as it makes calls to the backend.
|
|
28
|
+
*/
|
|
29
|
+
baseUrl: string;
|
|
30
|
+
|
|
31
|
+
lifecycle?: {
|
|
32
|
+
/**
|
|
33
|
+
* The maximum time that paused requests will wait for the service to start, before returning an error.
|
|
34
|
+
* Defaults to 5 seconds
|
|
35
|
+
* Supported formats:
|
|
36
|
+
* - A string in the format of '1d', '2 seconds' etc. as supported by the `ms`
|
|
37
|
+
* library.
|
|
38
|
+
* - A standard ISO formatted duration string, e.g. 'P2DT6H' or 'PT1M'.
|
|
39
|
+
* - An object with individual units (in plural) as keys, e.g. `{ days: 2, hours: 6 }`.
|
|
40
|
+
*/
|
|
41
|
+
startupRequestPauseTimeout?: string | HumanDuration;
|
|
42
|
+
/**
|
|
43
|
+
* The minimum time that the HTTP server will delay the shutdown of the backend. During this delay health checks will be set to failing, allowing traffic to drain.
|
|
44
|
+
* Defaults to 0 seconds.
|
|
45
|
+
* Supported formats:
|
|
46
|
+
* - A string in the format of '1d', '2 seconds' etc. as supported by the `ms`
|
|
47
|
+
* library.
|
|
48
|
+
* - A standard ISO formatted duration string, e.g. 'P2DT6H' or 'PT1M'.
|
|
49
|
+
* - An object with individual units (in plural) as keys, e.g. `{ days: 2, hours: 6 }`.
|
|
50
|
+
*/
|
|
51
|
+
serverShutdownDelay?: string | HumanDuration;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Corresponds to the Express `trust proxy` setting.
|
|
56
|
+
*
|
|
57
|
+
* @see https://expressjs.com/en/guide/behind-proxies.html
|
|
58
|
+
* @remarks
|
|
59
|
+
*
|
|
60
|
+
* This setting is used to determine whether the backend should trust the
|
|
61
|
+
* `X-Forwarded-*` headers that are set by proxies. This is important for
|
|
62
|
+
* determining the original client IP address and protocol (HTTP/HTTPS) when
|
|
63
|
+
* the backend is behind a reverse proxy or load balancer.
|
|
64
|
+
*/
|
|
65
|
+
trustProxy?: boolean | number | string | string[];
|
|
66
|
+
|
|
67
|
+
/** Address that the backend should listen to. */
|
|
68
|
+
listen?:
|
|
69
|
+
| string
|
|
70
|
+
| {
|
|
71
|
+
/** Address of the interface that the backend should bind to. */
|
|
72
|
+
host?: string;
|
|
73
|
+
/** Port that the backend should listen to. */
|
|
74
|
+
port?: string | number;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* HTTPS configuration for the backend. If omitted the backend will serve HTTP.
|
|
79
|
+
*
|
|
80
|
+
* Setting this to `true` will cause self-signed certificates to be generated, which
|
|
81
|
+
* can be useful for local development or other non-production scenarios.
|
|
82
|
+
*/
|
|
83
|
+
https?:
|
|
84
|
+
| true
|
|
85
|
+
| {
|
|
86
|
+
/** Certificate configuration */
|
|
87
|
+
certificate?: {
|
|
88
|
+
/** PEM encoded certificate. Use $file to load in a file */
|
|
89
|
+
cert: string;
|
|
90
|
+
/**
|
|
91
|
+
* PEM encoded certificate key. Use $file to load in a file.
|
|
92
|
+
* @visibility secret
|
|
93
|
+
*/
|
|
94
|
+
key: string;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Server-level HTTP options configuration for the backend.
|
|
100
|
+
* These options are passed directly to the underlying Node.js HTTP server.
|
|
101
|
+
*
|
|
102
|
+
* Timeout values support multiple formats:
|
|
103
|
+
* - A number in milliseconds
|
|
104
|
+
* - A string in the format of '1d', '2 seconds' etc. as supported by the `ms` library
|
|
105
|
+
* - A standard ISO formatted duration string, e.g. 'P2DT6H' or 'PT1M'
|
|
106
|
+
* - An object with individual units (in plural) as keys, e.g. `{ days: 2, hours: 6 }`
|
|
107
|
+
*/
|
|
108
|
+
server?: {
|
|
109
|
+
/** Sets the timeout value for receiving the complete HTTP headers from the client. */
|
|
110
|
+
headersTimeout?: number | string | HumanDuration;
|
|
111
|
+
/** Sets the timeout value for receiving the entire request (headers and body) from the client. */
|
|
112
|
+
requestTimeout?: number | string | HumanDuration;
|
|
113
|
+
/** Sets the timeout value for inactivity on a socket during keep-alive. */
|
|
114
|
+
keepAliveTimeout?: number | string | HumanDuration;
|
|
115
|
+
/** Sets the timeout value for sockets. */
|
|
116
|
+
timeout?: number | string | HumanDuration;
|
|
117
|
+
/** Limits maximum incoming headers count. */
|
|
118
|
+
maxHeadersCount?: number;
|
|
119
|
+
/** Sets the maximum number of requests socket can handle before closing keep alive connection. */
|
|
120
|
+
maxRequestsPerSocket?: number;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Options used by the default auditor service.
|
|
125
|
+
*/
|
|
126
|
+
auditor?: {
|
|
127
|
+
/**
|
|
128
|
+
* Defines how audit event severity levels are mapped to log levels.
|
|
129
|
+
* This allows you to control the verbosity of audit logs based on the
|
|
130
|
+
* severity of the event. For example, you might want to log 'low' severity
|
|
131
|
+
* events as 'debug' messages, while logging 'critical' events as 'error'
|
|
132
|
+
* messages. Each severity level ('low', 'medium', 'high', 'critical')
|
|
133
|
+
* can be mapped to one of the standard log levels ('debug', 'info', 'warn', 'error').
|
|
134
|
+
*
|
|
135
|
+
* By default, audit events are mapped to log levels as follows:
|
|
136
|
+
* - `low`: `debug`
|
|
137
|
+
* - `medium`: `info`
|
|
138
|
+
* - `high`: `info`
|
|
139
|
+
* - `critical`: `info`
|
|
140
|
+
*/
|
|
141
|
+
severityLogLevelMappings?: {
|
|
142
|
+
low?: 'debug' | 'info' | 'warn' | 'error';
|
|
143
|
+
medium?: 'debug' | 'info' | 'warn' | 'error';
|
|
144
|
+
high?: 'debug' | 'info' | 'warn' | 'error';
|
|
145
|
+
critical?: 'debug' | 'info' | 'warn' | 'error';
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Options used by the default actions service.
|
|
151
|
+
*/
|
|
152
|
+
actions?: {
|
|
153
|
+
/**
|
|
154
|
+
* List of plugin sources to load actions from.
|
|
155
|
+
*/
|
|
156
|
+
pluginSources?: string[];
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Filter configuration for actions. Allows controlling which actions
|
|
160
|
+
* are exposed to consumers based on patterns and attributes.
|
|
161
|
+
*/
|
|
162
|
+
filter?: {
|
|
163
|
+
/**
|
|
164
|
+
* Rules for actions to include. An action must match at least one rule to be included.
|
|
165
|
+
* Each rule can specify an id pattern and/or attribute constraints.
|
|
166
|
+
* If no include rules are specified, all actions are included by default.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```yaml
|
|
170
|
+
* include:
|
|
171
|
+
* - id: 'catalog:*'
|
|
172
|
+
* attributes:
|
|
173
|
+
* destructive: false
|
|
174
|
+
* - id: 'scaffolder:*'
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
include?: Array<{
|
|
178
|
+
/**
|
|
179
|
+
* Glob pattern for action IDs to match.
|
|
180
|
+
* Action IDs have the format `{pluginId}:{actionName}`.
|
|
181
|
+
* @example 'catalog:*'
|
|
182
|
+
*/
|
|
183
|
+
id?: string;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Attribute constraints. All specified attributes must match.
|
|
187
|
+
* Actions are compared against their resolved attributes (with defaults applied).
|
|
188
|
+
*/
|
|
189
|
+
attributes?: {
|
|
190
|
+
/**
|
|
191
|
+
* If specified, only match actions where destructive matches this value.
|
|
192
|
+
* Actions default to destructive: true if not explicitly set.
|
|
193
|
+
*/
|
|
194
|
+
destructive?: boolean;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* If specified, only match actions where readOnly matches this value.
|
|
198
|
+
* Actions default to readOnly: false if not explicitly set.
|
|
199
|
+
*/
|
|
200
|
+
readOnly?: boolean;
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* If specified, only match actions where idempotent matches this value.
|
|
204
|
+
* Actions default to idempotent: false if not explicitly set.
|
|
205
|
+
*/
|
|
206
|
+
idempotent?: boolean;
|
|
207
|
+
};
|
|
208
|
+
}>;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Rules for actions to exclude. Exclusions take precedence over inclusions.
|
|
212
|
+
* Each rule can specify an id pattern and/or attribute constraints.
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```yaml
|
|
216
|
+
* exclude:
|
|
217
|
+
* - id: '*:delete-*'
|
|
218
|
+
* - attributes:
|
|
219
|
+
* readOnly: false
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
exclude?: Array<{
|
|
223
|
+
/**
|
|
224
|
+
* Glob pattern for action IDs to match.
|
|
225
|
+
* Action IDs have the format `{pluginId}:{actionName}`.
|
|
226
|
+
* @example '*:delete-*'
|
|
227
|
+
*/
|
|
228
|
+
id?: string;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Attribute constraints. All specified attributes must match.
|
|
232
|
+
* Actions are compared against their resolved attributes (with defaults applied).
|
|
233
|
+
*/
|
|
234
|
+
attributes?: {
|
|
235
|
+
/**
|
|
236
|
+
* If specified, only match actions where destructive matches this value.
|
|
237
|
+
* Actions default to destructive: true if not explicitly set.
|
|
238
|
+
*/
|
|
239
|
+
destructive?: boolean;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* If specified, only match actions where readOnly matches this value.
|
|
243
|
+
* Actions default to readOnly: false if not explicitly set.
|
|
244
|
+
*/
|
|
245
|
+
readOnly?: boolean;
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* If specified, only match actions where idempotent matches this value.
|
|
249
|
+
* Actions default to idempotent: false if not explicitly set.
|
|
250
|
+
*/
|
|
251
|
+
idempotent?: boolean;
|
|
252
|
+
};
|
|
253
|
+
}>;
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Options used by the default auth, httpAuth and userInfo services.
|
|
259
|
+
*/
|
|
260
|
+
auth?: {
|
|
261
|
+
/**
|
|
262
|
+
* Keys shared by all backends for signing and validating backend tokens.
|
|
263
|
+
* @deprecated this will be removed when the backwards compatibility is no longer needed with backend-common
|
|
264
|
+
*/
|
|
265
|
+
keys?: {
|
|
266
|
+
/**
|
|
267
|
+
* Secret for generating tokens. Should be a base64 string, recommended
|
|
268
|
+
* length is 24 bytes.
|
|
269
|
+
*
|
|
270
|
+
* @visibility secret
|
|
271
|
+
*/
|
|
272
|
+
secret: string;
|
|
273
|
+
}[];
|
|
274
|
+
/**
|
|
275
|
+
* This disables the otherwise default auth policy, which requires all
|
|
276
|
+
* requests to be authenticated with either user or service credentials.
|
|
277
|
+
*
|
|
278
|
+
* Disabling this check means that the backend will no longer block
|
|
279
|
+
* unauthenticated requests, but instead allow them to pass through to
|
|
280
|
+
* plugins.
|
|
281
|
+
*
|
|
282
|
+
* If permissions are enabled, unauthenticated requests will be treated
|
|
283
|
+
* exactly as such, leaving it to the permission policy to determine what
|
|
284
|
+
* permissions should be allowed for an unauthenticated identity. Note
|
|
285
|
+
* that this will also apply to service-to-service calls between plugins
|
|
286
|
+
* unless you configure credentials for service calls.
|
|
287
|
+
*/
|
|
288
|
+
dangerouslyDisableDefaultAuthPolicy?: boolean;
|
|
289
|
+
|
|
290
|
+
/** Controls how to store keys for plugin-to-plugin auth */
|
|
291
|
+
pluginKeyStore?:
|
|
292
|
+
| { type: 'database' }
|
|
293
|
+
| {
|
|
294
|
+
type: 'static';
|
|
295
|
+
static: {
|
|
296
|
+
/**
|
|
297
|
+
* Must be declared at least once and the first one will be used for signing.
|
|
298
|
+
*/
|
|
299
|
+
keys: Array<{
|
|
300
|
+
/**
|
|
301
|
+
* Path to the public key file in the SPKI format. Should be an absolute path.
|
|
302
|
+
*/
|
|
303
|
+
publicKeyFile: string;
|
|
304
|
+
/**
|
|
305
|
+
* Path to the matching private key file in the PKCS#8 format. Should be an absolute path.
|
|
306
|
+
*
|
|
307
|
+
* The first array entry must specify a private key file, the rest must not.
|
|
308
|
+
*/
|
|
309
|
+
privateKeyFile?: string;
|
|
310
|
+
/**
|
|
311
|
+
* ID to uniquely identify this key within the JWK set.
|
|
312
|
+
*/
|
|
313
|
+
keyId: string;
|
|
314
|
+
/**
|
|
315
|
+
* JWS "alg" (Algorithm) Header Parameter value. Defaults to ES256.
|
|
316
|
+
* Must match the algorithm used to generate the keys in the provided files
|
|
317
|
+
*/
|
|
318
|
+
algorithm?: string;
|
|
319
|
+
}>;
|
|
320
|
+
};
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Configures methods of external access, ie ways for callers outside of
|
|
325
|
+
* the Backstage ecosystem to get authorized for access to APIs that do
|
|
326
|
+
* not permit unauthorized access.
|
|
327
|
+
*/
|
|
328
|
+
externalAccess?: Array<
|
|
329
|
+
| {
|
|
330
|
+
/**
|
|
331
|
+
* This is the legacy service-to-service access method, where a set
|
|
332
|
+
* of static keys were shared among plugins and used for symmetric
|
|
333
|
+
* signing and verification. These correspond to the old
|
|
334
|
+
* `backend.auth.keys` set and retain their behavior for backwards
|
|
335
|
+
* compatibility. Please migrate to other access methods when
|
|
336
|
+
* possible.
|
|
337
|
+
*
|
|
338
|
+
* Callers generate JWT tokens with the following payload:
|
|
339
|
+
*
|
|
340
|
+
* ```json
|
|
341
|
+
* {
|
|
342
|
+
* "sub": "backstage-plugin",
|
|
343
|
+
* "exp": <epoch seconds one hour in the future>
|
|
344
|
+
* }
|
|
345
|
+
* ```
|
|
346
|
+
*
|
|
347
|
+
* And sign them with HS256, using the base64 decoded secret. The
|
|
348
|
+
* tokens are then passed along with requests in the Authorization
|
|
349
|
+
* header:
|
|
350
|
+
*
|
|
351
|
+
* ```
|
|
352
|
+
* Authorization: Bearer eyJhbGciOiJIUzI...
|
|
353
|
+
* ```
|
|
354
|
+
*/
|
|
355
|
+
type: 'legacy';
|
|
356
|
+
options: {
|
|
357
|
+
/**
|
|
358
|
+
* Any set of base64 encoded random bytes to be used as both the
|
|
359
|
+
* signing and verification key. Should be sufficiently long so as
|
|
360
|
+
* not to be easy to guess by brute force.
|
|
361
|
+
*
|
|
362
|
+
* Can be generated eg using
|
|
363
|
+
*
|
|
364
|
+
* ```sh
|
|
365
|
+
* node -p 'require("crypto").randomBytes(24).toString("base64")'
|
|
366
|
+
* ```
|
|
367
|
+
*
|
|
368
|
+
* @visibility secret
|
|
369
|
+
*/
|
|
370
|
+
secret: string;
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Sets the subject of the principal, when matching this token.
|
|
374
|
+
* Useful for debugging and tracking purposes.
|
|
375
|
+
*/
|
|
376
|
+
subject: string;
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Restricts what types of access that are permitted for this access
|
|
380
|
+
* method. If no access restrictions are given, it'll have unlimited
|
|
381
|
+
* access. This access restriction applies for the framework level;
|
|
382
|
+
* individual plugins may have their own access control mechanisms
|
|
383
|
+
* on top of this.
|
|
384
|
+
*/
|
|
385
|
+
accessRestrictions?: Array<{
|
|
386
|
+
/**
|
|
387
|
+
* Permit access to make requests to this plugin.
|
|
388
|
+
*
|
|
389
|
+
* Can be further refined by setting additional fields below.
|
|
390
|
+
*/
|
|
391
|
+
plugin: string;
|
|
392
|
+
/**
|
|
393
|
+
* If given, this method is limited to only performing actions
|
|
394
|
+
* with these named permissions in this plugin.
|
|
395
|
+
*
|
|
396
|
+
* Note that this only applies where permissions checks are
|
|
397
|
+
* enabled in the first place. Endpoints that are not protected by
|
|
398
|
+
* the permissions system at all, are not affected by this
|
|
399
|
+
* setting.
|
|
400
|
+
*/
|
|
401
|
+
permission?: string | Array<string>;
|
|
402
|
+
/**
|
|
403
|
+
* If given, this method is limited to only performing actions
|
|
404
|
+
* whose permissions have these attributes.
|
|
405
|
+
*
|
|
406
|
+
* Note that this only applies where permissions checks are
|
|
407
|
+
* enabled in the first place. Endpoints that are not protected by
|
|
408
|
+
* the permissions system at all, are not affected by this
|
|
409
|
+
* setting.
|
|
410
|
+
*/
|
|
411
|
+
permissionAttribute?: {
|
|
412
|
+
/**
|
|
413
|
+
* One of more of 'create', 'read', 'update', or 'delete'.
|
|
414
|
+
*/
|
|
415
|
+
action?: string | Array<string>;
|
|
416
|
+
};
|
|
417
|
+
}>;
|
|
418
|
+
}
|
|
419
|
+
| {
|
|
420
|
+
/**
|
|
421
|
+
* This access method consists of random static tokens that can be
|
|
422
|
+
* handed out to callers.
|
|
423
|
+
*
|
|
424
|
+
* The tokens are then passed along verbatim with requests in the
|
|
425
|
+
* Authorization header:
|
|
426
|
+
*
|
|
427
|
+
* ```
|
|
428
|
+
* Authorization: Bearer eZv5o+fW3KnR3kVabMW4ZcDNLPl8nmMW
|
|
429
|
+
* ```
|
|
430
|
+
*/
|
|
431
|
+
type: 'static';
|
|
432
|
+
options: {
|
|
433
|
+
/**
|
|
434
|
+
* A raw token that can be any string, but for security reasons
|
|
435
|
+
* should be sufficiently long so as not to be easy to guess by
|
|
436
|
+
* brute force.
|
|
437
|
+
*
|
|
438
|
+
* Can be generated eg using
|
|
439
|
+
*
|
|
440
|
+
* ```sh
|
|
441
|
+
* node -p 'require("crypto").randomBytes(24).toString("base64")'
|
|
442
|
+
* ```
|
|
443
|
+
*
|
|
444
|
+
* Since the tokens can be any string, you are free to add
|
|
445
|
+
* additional identifying data to them if you like. For example,
|
|
446
|
+
* adding a `freben-local-dev-` prefix for debugging purposes to a
|
|
447
|
+
* token that you know will be handed out for use as a personal
|
|
448
|
+
* access token during development.
|
|
449
|
+
*
|
|
450
|
+
* @visibility secret
|
|
451
|
+
*/
|
|
452
|
+
token: string;
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Sets the subject of the principal, when matching this token.
|
|
456
|
+
* Useful for debugging and tracking purposes.
|
|
457
|
+
*/
|
|
458
|
+
subject: string;
|
|
459
|
+
};
|
|
460
|
+
/**
|
|
461
|
+
* Restricts what types of access that are permitted for this access
|
|
462
|
+
* method. If no access restrictions are given, it'll have unlimited
|
|
463
|
+
* access. This access restriction applies for the framework level;
|
|
464
|
+
* individual plugins may have their own access control mechanisms
|
|
465
|
+
* on top of this.
|
|
466
|
+
*/
|
|
467
|
+
accessRestrictions?: Array<{
|
|
468
|
+
/**
|
|
469
|
+
* Permit access to make requests to this plugin.
|
|
470
|
+
*
|
|
471
|
+
* Can be further refined by setting additional fields below.
|
|
472
|
+
*/
|
|
473
|
+
plugin: string;
|
|
474
|
+
/**
|
|
475
|
+
* If given, this method is limited to only performing actions
|
|
476
|
+
* with these named permissions in this plugin.
|
|
477
|
+
*
|
|
478
|
+
* Note that this only applies where permissions checks are
|
|
479
|
+
* enabled in the first place. Endpoints that are not protected by
|
|
480
|
+
* the permissions system at all, are not affected by this
|
|
481
|
+
* setting.
|
|
482
|
+
*/
|
|
483
|
+
permission?: string | Array<string>;
|
|
484
|
+
/**
|
|
485
|
+
* If given, this method is limited to only performing actions
|
|
486
|
+
* whose permissions have these attributes.
|
|
487
|
+
*
|
|
488
|
+
* Note that this only applies where permissions checks are
|
|
489
|
+
* enabled in the first place. Endpoints that are not protected by
|
|
490
|
+
* the permissions system at all, are not affected by this
|
|
491
|
+
* setting.
|
|
492
|
+
*/
|
|
493
|
+
permissionAttribute?: {
|
|
494
|
+
/**
|
|
495
|
+
* One of more of 'create', 'read', 'update', or 'delete'.
|
|
496
|
+
*/
|
|
497
|
+
action?: string | Array<string>;
|
|
498
|
+
};
|
|
499
|
+
}>;
|
|
500
|
+
}
|
|
501
|
+
| {
|
|
502
|
+
/**
|
|
503
|
+
* This access method consists of a JWKS endpoint that can be used to
|
|
504
|
+
* verify JWT tokens.
|
|
505
|
+
*
|
|
506
|
+
* Callers generate JWT tokens via 3rd party tooling
|
|
507
|
+
* and pass them in the Authorization header:
|
|
508
|
+
*
|
|
509
|
+
* ```
|
|
510
|
+
* Authorization: Bearer eZv5o+fW3KnR3kVabMW4ZcDNLPl8nmMW
|
|
511
|
+
* ```
|
|
512
|
+
*/
|
|
513
|
+
type: 'jwks';
|
|
514
|
+
options: {
|
|
515
|
+
/**
|
|
516
|
+
* The full URL of the JWKS endpoint.
|
|
517
|
+
*/
|
|
518
|
+
url: string;
|
|
519
|
+
/**
|
|
520
|
+
* Sets the algorithm(s) that should be used to verify the JWT tokens.
|
|
521
|
+
* The passed JWTs must have been signed using one of the listed algorithms.
|
|
522
|
+
*/
|
|
523
|
+
algorithm?: string | string[];
|
|
524
|
+
/**
|
|
525
|
+
* Sets the issuer(s) that should be used to verify the JWT tokens.
|
|
526
|
+
* Passed JWTs must have an `iss` claim which matches one of the specified issuers.
|
|
527
|
+
*/
|
|
528
|
+
issuer?: string | string[];
|
|
529
|
+
/**
|
|
530
|
+
* Sets the audience(s) that should be used to verify the JWT tokens.
|
|
531
|
+
* The passed JWTs must have an "aud" claim that matches one of the audiences specified,
|
|
532
|
+
* or have no audience specified.
|
|
533
|
+
*/
|
|
534
|
+
audience?: string | string[];
|
|
535
|
+
/**
|
|
536
|
+
* Sets an optional subject prefix. Passes the subject to called plugins.
|
|
537
|
+
* Useful for debugging and tracking purposes.
|
|
538
|
+
*/
|
|
539
|
+
subjectPrefix?: string;
|
|
540
|
+
};
|
|
541
|
+
/**
|
|
542
|
+
* Restricts what types of access that are permitted for this access
|
|
543
|
+
* method. If no access restrictions are given, it'll have unlimited
|
|
544
|
+
* access. This access restriction applies for the framework level;
|
|
545
|
+
* individual plugins may have their own access control mechanisms
|
|
546
|
+
* on top of this.
|
|
547
|
+
*/
|
|
548
|
+
accessRestrictions?: Array<{
|
|
549
|
+
/**
|
|
550
|
+
* Permit access to make requests to this plugin.
|
|
551
|
+
*
|
|
552
|
+
* Can be further refined by setting additional fields below.
|
|
553
|
+
*/
|
|
554
|
+
plugin: string;
|
|
555
|
+
/**
|
|
556
|
+
* If given, this method is limited to only performing actions
|
|
557
|
+
* with these named permissions in this plugin.
|
|
558
|
+
*
|
|
559
|
+
* Note that this only applies where permissions checks are
|
|
560
|
+
* enabled in the first place. Endpoints that are not protected by
|
|
561
|
+
* the permissions system at all, are not affected by this
|
|
562
|
+
* setting.
|
|
563
|
+
*/
|
|
564
|
+
permission?: string | Array<string>;
|
|
565
|
+
/**
|
|
566
|
+
* If given, this method is limited to only performing actions
|
|
567
|
+
* whose permissions have these attributes.
|
|
568
|
+
*
|
|
569
|
+
* Note that this only applies where permissions checks are
|
|
570
|
+
* enabled in the first place. Endpoints that are not protected by
|
|
571
|
+
* the permissions system at all, are not affected by this
|
|
572
|
+
* setting.
|
|
573
|
+
*/
|
|
574
|
+
permissionAttribute?: {
|
|
575
|
+
/**
|
|
576
|
+
* One of more of 'create', 'read', 'update', or 'delete'.
|
|
577
|
+
*/
|
|
578
|
+
action?: string | Array<string>;
|
|
579
|
+
};
|
|
580
|
+
}>;
|
|
581
|
+
}
|
|
582
|
+
>;
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
/** Database connection configuration, select base database type using the `client` field */
|
|
586
|
+
database: {
|
|
587
|
+
/** Default database client to use */
|
|
588
|
+
client: 'better-sqlite3' | 'sqlite3' | 'pg' | 'embedded-postgres';
|
|
589
|
+
/**
|
|
590
|
+
* Base database connection string, or object with individual connection properties
|
|
591
|
+
* @visibility secret
|
|
592
|
+
*/
|
|
593
|
+
connection:
|
|
594
|
+
| string
|
|
595
|
+
| {
|
|
596
|
+
/**
|
|
597
|
+
* The specific config for Azure database for PostgreSQL connections with Entra authentication
|
|
598
|
+
*/
|
|
599
|
+
type: 'azure';
|
|
600
|
+
/**
|
|
601
|
+
* Optional Azure token credential configuration
|
|
602
|
+
*/
|
|
603
|
+
tokenCredential?: {
|
|
604
|
+
/**
|
|
605
|
+
* How early before an access token expires to refresh it with a new one.
|
|
606
|
+
* Defaults to 5 minutes
|
|
607
|
+
* Supported formats:
|
|
608
|
+
* - A string in the format of '1d', '2 seconds' etc. as supported by the `ms` library.
|
|
609
|
+
* - A standard ISO formatted duration string, e.g. 'P2DT6H' or 'PT1M'.
|
|
610
|
+
* - An object with individual units (in plural) as keys, e.g. `{ days: 2, hours: 6 }`.
|
|
611
|
+
*/
|
|
612
|
+
tokenRenewableOffsetTime?: string | HumanDuration;
|
|
613
|
+
clientId?: string;
|
|
614
|
+
/**
|
|
615
|
+
* @visibility secret
|
|
616
|
+
*/
|
|
617
|
+
clientSecret?: string;
|
|
618
|
+
tenantId?: string;
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
| {
|
|
622
|
+
/**
|
|
623
|
+
* The specific config for cloudsql connections
|
|
624
|
+
*/
|
|
625
|
+
type: 'cloudsql';
|
|
626
|
+
/**
|
|
627
|
+
* The instance connection name for the cloudsql instance, e.g. `project:region:instance`
|
|
628
|
+
*/
|
|
629
|
+
instance: string;
|
|
630
|
+
/**
|
|
631
|
+
* The ip address type to use for the connection. Defaults to 'PUBLIC'
|
|
632
|
+
*/
|
|
633
|
+
ipAddressType?: 'PUBLIC' | 'PRIVATE' | 'PSC';
|
|
634
|
+
}
|
|
635
|
+
| {
|
|
636
|
+
/**
|
|
637
|
+
* The specific config for AWS RDS connections with IAM authentication.
|
|
638
|
+
* Requires the `@aws-sdk/rds-signer` package to be installed.
|
|
639
|
+
* The IAM role or user must have the `rds-db:connect` permission for the database user.
|
|
640
|
+
*/
|
|
641
|
+
type: 'rds';
|
|
642
|
+
/**
|
|
643
|
+
* The hostname of the RDS instance.
|
|
644
|
+
*/
|
|
645
|
+
host: string;
|
|
646
|
+
/**
|
|
647
|
+
* The port number the database is listening on.
|
|
648
|
+
*/
|
|
649
|
+
port: number;
|
|
650
|
+
/**
|
|
651
|
+
* The database user to authenticate as. This user must have the `rds_iam` role granted.
|
|
652
|
+
*/
|
|
653
|
+
user: string;
|
|
654
|
+
/**
|
|
655
|
+
* The AWS region where the RDS instance is located.
|
|
656
|
+
* Falls back to the AWS_REGION or AWS_DEFAULT_REGION environment variables if not set.
|
|
657
|
+
*/
|
|
658
|
+
region?: string;
|
|
659
|
+
/**
|
|
660
|
+
* Other connection settings
|
|
661
|
+
*/
|
|
662
|
+
[key: string]: unknown;
|
|
663
|
+
}
|
|
664
|
+
| {
|
|
665
|
+
/**
|
|
666
|
+
* The rest config for default, regular connections
|
|
667
|
+
*/
|
|
668
|
+
type?: 'default';
|
|
669
|
+
/**
|
|
670
|
+
* Password that belongs to the client User
|
|
671
|
+
* @visibility secret
|
|
672
|
+
*/
|
|
673
|
+
password?: string;
|
|
674
|
+
/**
|
|
675
|
+
* Other connection settings
|
|
676
|
+
*/
|
|
677
|
+
[key: string]: unknown;
|
|
678
|
+
};
|
|
679
|
+
/** Database name prefix override */
|
|
680
|
+
prefix?: string;
|
|
681
|
+
/**
|
|
682
|
+
* Whether to ensure the given database exists by creating it if it does not.
|
|
683
|
+
* Defaults to true if unspecified.
|
|
684
|
+
*/
|
|
685
|
+
ensureExists?: boolean;
|
|
686
|
+
/**
|
|
687
|
+
* Whether to ensure the given database schema exists by creating it if it does not.
|
|
688
|
+
* Defaults to false if unspecified.
|
|
689
|
+
*
|
|
690
|
+
* NOTE: Currently only supported by the `pg` client when pluginDivisionMode: schema
|
|
691
|
+
*/
|
|
692
|
+
ensureSchemaExists?: boolean;
|
|
693
|
+
/**
|
|
694
|
+
* How plugins databases are managed/divided in the provided database instance.
|
|
695
|
+
*
|
|
696
|
+
* `database` -> Plugins are each given their own database to manage their schemas/tables.
|
|
697
|
+
*
|
|
698
|
+
* `schema` -> Plugins will be given their own schema (in the specified/default database)
|
|
699
|
+
* to manage their tables.
|
|
700
|
+
*
|
|
701
|
+
* NOTE: Currently only supported by the `pg` client.
|
|
702
|
+
*
|
|
703
|
+
* @default database
|
|
704
|
+
*/
|
|
705
|
+
pluginDivisionMode?: 'database' | 'schema';
|
|
706
|
+
/** Configures the ownership of newly created schemas in pg databases. */
|
|
707
|
+
role?: string;
|
|
708
|
+
/**
|
|
709
|
+
* Arbitrary config object to pass to knex when initializing
|
|
710
|
+
* (https://knexjs.org/#Installation-client). Most notable is the debug
|
|
711
|
+
* and asyncStackTraces booleans
|
|
712
|
+
*/
|
|
713
|
+
knexConfig?: object;
|
|
714
|
+
/** Skip running database migrations. */
|
|
715
|
+
skipMigrations?: boolean;
|
|
716
|
+
/** Plugin specific database configuration and client override */
|
|
717
|
+
plugin?: {
|
|
718
|
+
[pluginId: string]: {
|
|
719
|
+
/** Database client override */
|
|
720
|
+
client?: 'better-sqlite3' | 'sqlite3' | 'pg';
|
|
721
|
+
/**
|
|
722
|
+
* Database connection string or Knex object override
|
|
723
|
+
* @visibility secret
|
|
724
|
+
*/
|
|
725
|
+
connection?:
|
|
726
|
+
| string
|
|
727
|
+
| {
|
|
728
|
+
/**
|
|
729
|
+
* The specific config for cloudsql connections
|
|
730
|
+
*/
|
|
731
|
+
type: 'cloudsql';
|
|
732
|
+
/**
|
|
733
|
+
* The instance connection name for the cloudsql instance, e.g. `project:region:instance`
|
|
734
|
+
*/
|
|
735
|
+
instance: string;
|
|
736
|
+
}
|
|
737
|
+
| {
|
|
738
|
+
/**
|
|
739
|
+
* Password that belongs to the client User
|
|
740
|
+
* @visibility secret
|
|
741
|
+
*/
|
|
742
|
+
password?: string;
|
|
743
|
+
/**
|
|
744
|
+
* Other connection settings
|
|
745
|
+
*/
|
|
746
|
+
[key: string]: unknown;
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Whether to ensure the given database exists by creating it if it does not.
|
|
751
|
+
* Defaults to base config if unspecified.
|
|
752
|
+
*/
|
|
753
|
+
ensureExists?: boolean;
|
|
754
|
+
/**
|
|
755
|
+
* Whether to ensure the given database schema exists by creating it if it does not.
|
|
756
|
+
* Defaults to false if unspecified.
|
|
757
|
+
*
|
|
758
|
+
* NOTE: Currently only supported by the `pg` client when pluginDivisionMode: schema
|
|
759
|
+
*/
|
|
760
|
+
ensureSchemaExists?: boolean;
|
|
761
|
+
/**
|
|
762
|
+
* Arbitrary config object to pass to knex when initializing
|
|
763
|
+
* (https://knexjs.org/#Installation-client). Most notable is the
|
|
764
|
+
* debug and asyncStackTraces booleans.
|
|
765
|
+
*
|
|
766
|
+
* This is merged recursively into the base knexConfig
|
|
767
|
+
*/
|
|
768
|
+
knexConfig?: object;
|
|
769
|
+
/** Configures the ownership of newly created schemas in pg databases. */
|
|
770
|
+
role?: string;
|
|
771
|
+
/** Skip running database migrations. */
|
|
772
|
+
skipMigrations?: boolean;
|
|
773
|
+
};
|
|
774
|
+
};
|
|
775
|
+
};
|
|
776
|
+
|
|
777
|
+
/** Cache connection configuration, select cache type using the `store` field */
|
|
778
|
+
cache?:
|
|
779
|
+
| {
|
|
780
|
+
store: 'memory';
|
|
781
|
+
/** An optional default TTL (in milliseconds, if given as a number). */
|
|
782
|
+
defaultTtl?: number | HumanDuration | string;
|
|
783
|
+
}
|
|
784
|
+
| {
|
|
785
|
+
store: 'redis';
|
|
786
|
+
/**
|
|
787
|
+
* A redis connection string in the form `redis://user:pass@host:port`.
|
|
788
|
+
* @visibility secret
|
|
789
|
+
*/
|
|
790
|
+
connection: string;
|
|
791
|
+
/** An optional default TTL (in milliseconds, if given as a number). */
|
|
792
|
+
defaultTtl?: number | HumanDuration | string;
|
|
793
|
+
redis?: {
|
|
794
|
+
/**
|
|
795
|
+
* An optional Redis client configuration. These options are passed to the `@keyv/redis` client.
|
|
796
|
+
*/
|
|
797
|
+
client?: {
|
|
798
|
+
/**
|
|
799
|
+
* Namespace for the current instance.
|
|
800
|
+
*/
|
|
801
|
+
namespace?: string;
|
|
802
|
+
/**
|
|
803
|
+
* Separator to use between namespace and key.
|
|
804
|
+
*/
|
|
805
|
+
keyPrefixSeparator?: string;
|
|
806
|
+
/**
|
|
807
|
+
* Number of keys to delete in a single batch.
|
|
808
|
+
*/
|
|
809
|
+
clearBatchSize?: number;
|
|
810
|
+
/**
|
|
811
|
+
* Enable Unlink instead of using Del for clearing keys. This is more performant but may not be supported by all Redis versions.
|
|
812
|
+
*/
|
|
813
|
+
useUnlink?: boolean;
|
|
814
|
+
/**
|
|
815
|
+
* Whether to allow clearing all keys when no namespace is set.
|
|
816
|
+
* If set to true and no namespace is set, iterate() will return all keys.
|
|
817
|
+
* Defaults to `false`.
|
|
818
|
+
*/
|
|
819
|
+
noNamespaceAffectsAll?: boolean;
|
|
820
|
+
};
|
|
821
|
+
/**
|
|
822
|
+
* An optional Redis cluster configuration.
|
|
823
|
+
*/
|
|
824
|
+
cluster?: {
|
|
825
|
+
/**
|
|
826
|
+
* Cluster configuration options to be passed to the `@keyv/redis` client (and node-redis under the hood)
|
|
827
|
+
* https://github.com/redis/node-redis/blob/master/docs/clustering.md
|
|
828
|
+
*
|
|
829
|
+
* @visibility secret
|
|
830
|
+
*/
|
|
831
|
+
rootNodes: Array<object>;
|
|
832
|
+
/**
|
|
833
|
+
* Cluster node default configuration options to be passed to the `@keyv/redis` client (and node-redis under the hood)
|
|
834
|
+
* https://github.com/redis/node-redis/blob/master/docs/clustering.md
|
|
835
|
+
*
|
|
836
|
+
* @visibility secret
|
|
837
|
+
*/
|
|
838
|
+
defaults?: Partial<object>;
|
|
839
|
+
/**
|
|
840
|
+
* When `true`, `.connect()` will only discover the cluster topology, without actually connecting to all the nodes.
|
|
841
|
+
* Useful for short-term or PubSub-only connections.
|
|
842
|
+
*/
|
|
843
|
+
minimizeConnections?: boolean;
|
|
844
|
+
/**
|
|
845
|
+
* When `true`, distribute load by executing readonly commands (such as `GET`, `GEOSEARCH`, etc.) across all cluster nodes. When `false`, only use master nodes.
|
|
846
|
+
*/
|
|
847
|
+
useReplicas?: boolean;
|
|
848
|
+
/**
|
|
849
|
+
* The maximum number of times a command will be redirected due to `MOVED` or `ASK` errors.
|
|
850
|
+
*/
|
|
851
|
+
maxCommandRedirections?: number;
|
|
852
|
+
};
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
| {
|
|
856
|
+
store: 'valkey';
|
|
857
|
+
/**
|
|
858
|
+
* A valkey connection string in the form `redis://user:pass@host:port`.
|
|
859
|
+
* @visibility secret
|
|
860
|
+
*/
|
|
861
|
+
connection: string;
|
|
862
|
+
/** An optional default TTL (in milliseconds, if given as a number). */
|
|
863
|
+
defaultTtl?: number | HumanDuration | string;
|
|
864
|
+
valkey?: {
|
|
865
|
+
/**
|
|
866
|
+
* An optional Valkey client configuration. These options are passed to the `@keyv/valkey` client.
|
|
867
|
+
*/
|
|
868
|
+
client?: {
|
|
869
|
+
/**
|
|
870
|
+
* Namespace and separator used for prefixing keys.
|
|
871
|
+
*/
|
|
872
|
+
keyPrefix?: string;
|
|
873
|
+
};
|
|
874
|
+
/**
|
|
875
|
+
* An optional Valkey cluster (redis cluster under the hood) configuration.
|
|
876
|
+
*/
|
|
877
|
+
cluster?: {
|
|
878
|
+
/**
|
|
879
|
+
* Cluster configuration options to be passed to the `@keyv/valkey` client (and node-redis under the hood)
|
|
880
|
+
* https://github.com/redis/node-redis/blob/master/docs/clustering.md
|
|
881
|
+
*
|
|
882
|
+
* @visibility secret
|
|
883
|
+
*/
|
|
884
|
+
rootNodes: Array<object>;
|
|
885
|
+
/**
|
|
886
|
+
* Cluster node default configuration options to be passed to the `@keyv/redis` client (and node-redis under the hood)
|
|
887
|
+
* https://github.com/redis/node-redis/blob/master/docs/clustering.md
|
|
888
|
+
*
|
|
889
|
+
* @visibility secret
|
|
890
|
+
*/
|
|
891
|
+
defaults?: Partial<object>;
|
|
892
|
+
/**
|
|
893
|
+
* When `true`, `.connect()` will only discover the cluster topology, without actually connecting to all the nodes.
|
|
894
|
+
* Useful for short-term or PubSub-only connections.
|
|
895
|
+
*/
|
|
896
|
+
minimizeConnections?: boolean;
|
|
897
|
+
/**
|
|
898
|
+
* When `true`, distribute load by executing readonly commands (such as `GET`, `GEOSEARCH`, etc.) across all cluster nodes. When `false`, only use master nodes.
|
|
899
|
+
*/
|
|
900
|
+
useReplicas?: boolean;
|
|
901
|
+
/**
|
|
902
|
+
* The maximum number of times a command will be redirected due to `MOVED` or `ASK` errors.
|
|
903
|
+
*/
|
|
904
|
+
maxCommandRedirections?: number;
|
|
905
|
+
};
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
| {
|
|
909
|
+
store: 'memcache';
|
|
910
|
+
/**
|
|
911
|
+
* A memcache connection string in the form `user:pass@host:port`.
|
|
912
|
+
* @visibility secret
|
|
913
|
+
*/
|
|
914
|
+
connection: string;
|
|
915
|
+
/** An optional default TTL (in milliseconds). */
|
|
916
|
+
defaultTtl?: number | HumanDuration | string;
|
|
917
|
+
}
|
|
918
|
+
| {
|
|
919
|
+
/**
|
|
920
|
+
* Infinispan cache store configuration.
|
|
921
|
+
* @see https://docs.jboss.org/infinispan/hotrod-clients/javascript/1.0/apidocs/module-infinispan.html
|
|
922
|
+
*/
|
|
923
|
+
store: 'infinispan';
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* An optional default TTL (in milliseconds).
|
|
927
|
+
*/
|
|
928
|
+
defaultTtl?: number | HumanDuration | string;
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* Configuration for the Infinispan cache store.
|
|
932
|
+
*/
|
|
933
|
+
infinispan?: {
|
|
934
|
+
/**
|
|
935
|
+
* Version of client/server protocol.
|
|
936
|
+
* @default '2.9' is the latest version.
|
|
937
|
+
*/
|
|
938
|
+
version?: '2.9' | '2.5' | '2.2';
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* Infinispan Cache Name if not provided default is `cache` recommended to set this.
|
|
942
|
+
*/
|
|
943
|
+
cacheName?: string;
|
|
944
|
+
|
|
945
|
+
/**
|
|
946
|
+
* Optional number of retries for operation.
|
|
947
|
+
* Defaults to 3.
|
|
948
|
+
*/
|
|
949
|
+
maxRetries?: number;
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* Optional flag to controls whether the client deals with topology updates or not.
|
|
953
|
+
* @default true
|
|
954
|
+
*/
|
|
955
|
+
topologyUpdates?: boolean;
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* Media type of the cache contents.
|
|
959
|
+
* @default 'text/plain'
|
|
960
|
+
*/
|
|
961
|
+
mediaType?: 'text/plain' | 'application/json';
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* Optional data format configuration.
|
|
965
|
+
* If not provided, defaults to text/plain for both key and value.
|
|
966
|
+
*/
|
|
967
|
+
dataFormat?: {
|
|
968
|
+
/**
|
|
969
|
+
* Type of the key in the cache.
|
|
970
|
+
* @default 'text/plain'
|
|
971
|
+
*/
|
|
972
|
+
keyType?: 'text/plain' | 'application/json';
|
|
973
|
+
/**
|
|
974
|
+
* Type of the value in the cache.
|
|
975
|
+
* @default 'text/plain'
|
|
976
|
+
*/
|
|
977
|
+
valueType?: 'text/plain' | 'application/json';
|
|
978
|
+
};
|
|
979
|
+
/**
|
|
980
|
+
* Infinispan server host and port configuration.
|
|
981
|
+
* If this is an array, the client will connect to all servers in the list based on TOPOLOGY_AWARE routing.
|
|
982
|
+
* If this is a single object, it will be used as the default server.
|
|
983
|
+
*/
|
|
984
|
+
servers?:
|
|
985
|
+
| Array<{
|
|
986
|
+
/**
|
|
987
|
+
* Infinispan server host.
|
|
988
|
+
*/
|
|
989
|
+
host: string;
|
|
990
|
+
/**
|
|
991
|
+
* Infinispan server port (Hot Rod protocol). Defaults to `11222`.
|
|
992
|
+
*/
|
|
993
|
+
port?: number;
|
|
994
|
+
}>
|
|
995
|
+
| {
|
|
996
|
+
/**
|
|
997
|
+
* Infinispan server host. Defaults to `127.0.0.1`.
|
|
998
|
+
*/
|
|
999
|
+
host?: string;
|
|
1000
|
+
/**
|
|
1001
|
+
* Infinispan server port (Hot Rod protocol). Defaults to `11222`.
|
|
1002
|
+
*/
|
|
1003
|
+
port?: number;
|
|
1004
|
+
};
|
|
1005
|
+
authentication?: {
|
|
1006
|
+
/**
|
|
1007
|
+
* Enable authentication. Defaults to `false`.
|
|
1008
|
+
*/
|
|
1009
|
+
enabled?: boolean;
|
|
1010
|
+
/**
|
|
1011
|
+
* Select the SASL mechanism to use. Can be one of PLAIN, DIGEST-MD5, SCRAM-SHA-1, SCRAM-SHA-256, SCRAM-SHA-384, SCRAM-SHA-512, EXTERNAL, OAUTHBEARER
|
|
1012
|
+
*/
|
|
1013
|
+
saslMechanism?: string;
|
|
1014
|
+
/**
|
|
1015
|
+
* userName for authentication.
|
|
1016
|
+
*/
|
|
1017
|
+
userName?: string;
|
|
1018
|
+
/**
|
|
1019
|
+
* Password for authentication.
|
|
1020
|
+
* @visibility secret
|
|
1021
|
+
*/
|
|
1022
|
+
password?: string;
|
|
1023
|
+
/**
|
|
1024
|
+
* The OAuth token. Required by the OAUTHBEARER mechanism.
|
|
1025
|
+
* @visibility secret
|
|
1026
|
+
*/
|
|
1027
|
+
token?: string;
|
|
1028
|
+
/**
|
|
1029
|
+
* The SASL authorization ID.
|
|
1030
|
+
*/
|
|
1031
|
+
authzid?: string;
|
|
1032
|
+
};
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* TLS/SSL configuration.
|
|
1036
|
+
*/
|
|
1037
|
+
ssl?: {
|
|
1038
|
+
/**
|
|
1039
|
+
* Enable ssl connection. Defaults to `false`.
|
|
1040
|
+
* @default false
|
|
1041
|
+
*/
|
|
1042
|
+
enabled?: boolean;
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* Optional field with secure protocol in use.
|
|
1046
|
+
* @default TLSv1_2_method
|
|
1047
|
+
*/
|
|
1048
|
+
secureProtocol?: string;
|
|
1049
|
+
|
|
1050
|
+
/**
|
|
1051
|
+
* Optional paths of trusted SSL certificates.
|
|
1052
|
+
*/
|
|
1053
|
+
trustCerts?: Array<string>;
|
|
1054
|
+
|
|
1055
|
+
clientAuth?: {
|
|
1056
|
+
/**
|
|
1057
|
+
* Optional path to client authentication key
|
|
1058
|
+
*/
|
|
1059
|
+
key?: string;
|
|
1060
|
+
/**
|
|
1061
|
+
* Optional password for client key
|
|
1062
|
+
*/
|
|
1063
|
+
passphrase?: string;
|
|
1064
|
+
/**
|
|
1065
|
+
* Optional client certificate
|
|
1066
|
+
*/
|
|
1067
|
+
cert?: string;
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1070
|
+
/**
|
|
1071
|
+
* Optional SNI host name.
|
|
1072
|
+
*/
|
|
1073
|
+
sniHostName?: string;
|
|
1074
|
+
|
|
1075
|
+
/**
|
|
1076
|
+
* Optional crypto store configuration.
|
|
1077
|
+
*/
|
|
1078
|
+
cryptoStore?: {
|
|
1079
|
+
/** Optional crypto store path. */
|
|
1080
|
+
path?: string;
|
|
1081
|
+
/** Optional password for crypto store. */
|
|
1082
|
+
passphrase?: string;
|
|
1083
|
+
};
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
/**
|
|
1087
|
+
* Optional additional clusters for cross-site failovers.
|
|
1088
|
+
* Array.<Cluster>
|
|
1089
|
+
*/
|
|
1090
|
+
clusters?: Array<{
|
|
1091
|
+
/**
|
|
1092
|
+
* Optional Cluster name
|
|
1093
|
+
*/
|
|
1094
|
+
name?: string;
|
|
1095
|
+
|
|
1096
|
+
/**
|
|
1097
|
+
* Cluster servers details.
|
|
1098
|
+
* Array.<ServerAddress>
|
|
1099
|
+
*/
|
|
1100
|
+
servers: Array<{
|
|
1101
|
+
/**
|
|
1102
|
+
* Infinispan cluster server host.
|
|
1103
|
+
*/
|
|
1104
|
+
host: string;
|
|
1105
|
+
/**
|
|
1106
|
+
* Infinispan server port (Hot Rod protocol). Defaults to `11222`.
|
|
1107
|
+
*/
|
|
1108
|
+
port?: number;
|
|
1109
|
+
}>;
|
|
1110
|
+
}>;
|
|
1111
|
+
};
|
|
1112
|
+
};
|
|
1113
|
+
|
|
1114
|
+
cors?: {
|
|
1115
|
+
origin?: string | string[];
|
|
1116
|
+
methods?: string | string[];
|
|
1117
|
+
allowedHeaders?: string | string[];
|
|
1118
|
+
exposedHeaders?: string | string[];
|
|
1119
|
+
credentials?: boolean;
|
|
1120
|
+
maxAge?: number;
|
|
1121
|
+
preflightContinue?: boolean;
|
|
1122
|
+
optionsSuccessStatus?: number;
|
|
1123
|
+
};
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Content Security Policy options.
|
|
1127
|
+
*
|
|
1128
|
+
* The keys are the plain policy ID, e.g. "upgrade-insecure-requests". The
|
|
1129
|
+
* values are on the format that the helmet library expects them, as an
|
|
1130
|
+
* array of strings. There is also the special value false, which means to
|
|
1131
|
+
* remove the default value that Backstage puts in place for that policy.
|
|
1132
|
+
*/
|
|
1133
|
+
csp?: { [policyId: string]: string[] | false };
|
|
1134
|
+
|
|
1135
|
+
/**
|
|
1136
|
+
* Referrer Policy options
|
|
1137
|
+
*/
|
|
1138
|
+
referrer?: {
|
|
1139
|
+
policy: string[];
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1142
|
+
/**
|
|
1143
|
+
* Options for the health check service and endpoint.
|
|
1144
|
+
*/
|
|
1145
|
+
health?: {
|
|
1146
|
+
/**
|
|
1147
|
+
* Additional headers to always include in the health check response.
|
|
1148
|
+
*
|
|
1149
|
+
* It can be a good idea to set a header that uniquely identifies your service
|
|
1150
|
+
* in a multi-service environment. This ensures that the health check that is
|
|
1151
|
+
* configured for your service is actually hitting your service and not another.
|
|
1152
|
+
*
|
|
1153
|
+
* For example, if using Envoy you can use the `service_name_matcher` configuration
|
|
1154
|
+
* and set the `x-envoy-upstream-healthchecked-cluster` header to a matching value.
|
|
1155
|
+
*/
|
|
1156
|
+
headers?: { [name: string]: string };
|
|
1157
|
+
};
|
|
1158
|
+
|
|
1159
|
+
/**
|
|
1160
|
+
* Options for the metrics service.
|
|
1161
|
+
*/
|
|
1162
|
+
metrics?: {
|
|
1163
|
+
/**
|
|
1164
|
+
* Plugin-specific metrics configuration. Each plugin can override meter metadata.
|
|
1165
|
+
*/
|
|
1166
|
+
plugin?: {
|
|
1167
|
+
[pluginId: string]: {
|
|
1168
|
+
/**
|
|
1169
|
+
* Meter configuration for this plugin.
|
|
1170
|
+
*/
|
|
1171
|
+
meter?: {
|
|
1172
|
+
/**
|
|
1173
|
+
* Custom meter name. If not set, defaults to backstage-plugin-{pluginId}.
|
|
1174
|
+
*/
|
|
1175
|
+
name?: string;
|
|
1176
|
+
/**
|
|
1177
|
+
* Version for the meter.
|
|
1178
|
+
*/
|
|
1179
|
+
version?: string;
|
|
1180
|
+
/**
|
|
1181
|
+
* Schema URL for the meter.
|
|
1182
|
+
*/
|
|
1183
|
+
schemaUrl?: string;
|
|
1184
|
+
};
|
|
1185
|
+
};
|
|
1186
|
+
};
|
|
1187
|
+
};
|
|
1188
|
+
|
|
1189
|
+
/**
|
|
1190
|
+
* Tracing-related backend configuration. Honored by Backstage backend
|
|
1191
|
+
* plugins that emit OpenTelemetry trace spans.
|
|
1192
|
+
*/
|
|
1193
|
+
tracing?: {
|
|
1194
|
+
/**
|
|
1195
|
+
* Opt-in capture of attributes that may identify users or contain
|
|
1196
|
+
* sensitive data on backend trace spans.
|
|
1197
|
+
*/
|
|
1198
|
+
capture?: {
|
|
1199
|
+
/**
|
|
1200
|
+
* When true, backend plugins emitting trace spans for authenticated
|
|
1201
|
+
* requests SHOULD include the authenticated principal's identity as
|
|
1202
|
+
* `enduser.id` (the user entity ref for a user principal, or the
|
|
1203
|
+
* service subject for a service principal). Defaults to false.
|
|
1204
|
+
*/
|
|
1205
|
+
endUser?: boolean;
|
|
1206
|
+
};
|
|
1207
|
+
/**
|
|
1208
|
+
* Plugin-specific tracing configuration. Each plugin can override
|
|
1209
|
+
* tracer instrumentation scope metadata.
|
|
1210
|
+
*/
|
|
1211
|
+
plugin?: {
|
|
1212
|
+
[pluginId: string]: {
|
|
1213
|
+
/**
|
|
1214
|
+
* Tracer configuration for this plugin.
|
|
1215
|
+
*/
|
|
1216
|
+
tracer?: {
|
|
1217
|
+
/**
|
|
1218
|
+
* Custom tracer name. If not set, defaults to
|
|
1219
|
+
* backstage-plugin-{pluginId}.
|
|
1220
|
+
*/
|
|
1221
|
+
name?: string;
|
|
1222
|
+
/**
|
|
1223
|
+
* Version for the tracer.
|
|
1224
|
+
*/
|
|
1225
|
+
version?: string;
|
|
1226
|
+
/**
|
|
1227
|
+
* Schema URL for the tracer.
|
|
1228
|
+
*/
|
|
1229
|
+
schemaUrl?: string;
|
|
1230
|
+
};
|
|
1231
|
+
};
|
|
1232
|
+
};
|
|
1233
|
+
};
|
|
1234
|
+
|
|
1235
|
+
/**
|
|
1236
|
+
* Options to configure the default RootLoggerService.
|
|
1237
|
+
*/
|
|
1238
|
+
logger?: {
|
|
1239
|
+
/**
|
|
1240
|
+
* Configures the global log level for messages.
|
|
1241
|
+
*
|
|
1242
|
+
* This can also be configured using the LOG_LEVEL environment variable, which
|
|
1243
|
+
* takes precedence over this configuration.
|
|
1244
|
+
*
|
|
1245
|
+
* Defaults to 'info'.
|
|
1246
|
+
*/
|
|
1247
|
+
level?: 'debug' | 'info' | 'warn' | 'error';
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* Additional metadata to include with every log entry.
|
|
1251
|
+
*/
|
|
1252
|
+
meta?: JsonObject;
|
|
1253
|
+
|
|
1254
|
+
/**
|
|
1255
|
+
* List of logger overrides.
|
|
1256
|
+
*
|
|
1257
|
+
* Can be used to configure a different level for logs matching certain criterias.
|
|
1258
|
+
* For example, it can be used to ignore 'info' logs of given plugins.
|
|
1259
|
+
*
|
|
1260
|
+
* @example
|
|
1261
|
+
*
|
|
1262
|
+
* ```yaml
|
|
1263
|
+
* logger:
|
|
1264
|
+
* level: info
|
|
1265
|
+
* overrides:
|
|
1266
|
+
* # For catalog and auth plugins, messages less important than 'warn' will be ignored.
|
|
1267
|
+
* - matchers:
|
|
1268
|
+
* plugin: [catalog, auth]
|
|
1269
|
+
* level: warn
|
|
1270
|
+
* # Ignore all messages that starts with 'Forget'
|
|
1271
|
+
* - matchers:
|
|
1272
|
+
* message: '/^Forget/'
|
|
1273
|
+
* level: warn
|
|
1274
|
+
* ```
|
|
1275
|
+
*/
|
|
1276
|
+
overrides?: Array<{
|
|
1277
|
+
/**
|
|
1278
|
+
* Conditions that must be met to override the log level.
|
|
1279
|
+
*
|
|
1280
|
+
* A matcher can be:
|
|
1281
|
+
*
|
|
1282
|
+
* - A string (exact match or regex pattern delimited by slashes, e.g. `/pattern/`)
|
|
1283
|
+
* - A non-string value (compared by strict equality)
|
|
1284
|
+
* - An array of matchers (returns true if any matcher matches)
|
|
1285
|
+
*/
|
|
1286
|
+
matchers: JsonObject;
|
|
1287
|
+
|
|
1288
|
+
/**
|
|
1289
|
+
* Log level to use for matched entries.
|
|
1290
|
+
*/
|
|
1291
|
+
level: 'debug' | 'info' | 'warn' | 'error';
|
|
1292
|
+
}>;
|
|
1293
|
+
};
|
|
1294
|
+
|
|
1295
|
+
/**
|
|
1296
|
+
* Rate limiting options. Defining this as `true` will enable rate limiting with default values.
|
|
1297
|
+
*/
|
|
1298
|
+
rateLimit?:
|
|
1299
|
+
| true
|
|
1300
|
+
| {
|
|
1301
|
+
store?:
|
|
1302
|
+
| {
|
|
1303
|
+
type: 'redis';
|
|
1304
|
+
connection: string;
|
|
1305
|
+
}
|
|
1306
|
+
| {
|
|
1307
|
+
type: 'memory';
|
|
1308
|
+
};
|
|
1309
|
+
/**
|
|
1310
|
+
* Enable/disable global rate limiting. If this is disabled, plugin specific rate limiting must be
|
|
1311
|
+
* used.
|
|
1312
|
+
*/
|
|
1313
|
+
global?: boolean;
|
|
1314
|
+
/**
|
|
1315
|
+
* Time frame in milliseconds or as human duration for which requests are checked/remembered.
|
|
1316
|
+
* Defaults to one minute.
|
|
1317
|
+
*/
|
|
1318
|
+
window?: string | HumanDuration;
|
|
1319
|
+
/**
|
|
1320
|
+
* The maximum number of connections to allow during the `window` before rate limiting the client.
|
|
1321
|
+
* Defaults to 5.
|
|
1322
|
+
*/
|
|
1323
|
+
incomingRequestLimit?: number;
|
|
1324
|
+
/**
|
|
1325
|
+
* Whether to pass requests in case of store failure.
|
|
1326
|
+
* Defaults to false.
|
|
1327
|
+
*/
|
|
1328
|
+
passOnStoreError?: boolean;
|
|
1329
|
+
/**
|
|
1330
|
+
* List of allowed IP addresses that are not rate limited.
|
|
1331
|
+
* Defaults to [127.0.0.1, 0:0:0:0:0:0:0:1, ::1].
|
|
1332
|
+
*/
|
|
1333
|
+
ipAllowList?: string[];
|
|
1334
|
+
/**
|
|
1335
|
+
* Skip rate limiting for requests that have been successful.
|
|
1336
|
+
* Defaults to false.
|
|
1337
|
+
*/
|
|
1338
|
+
skipSuccessfulRequests?: boolean;
|
|
1339
|
+
/**
|
|
1340
|
+
* Skip rate limiting for requests that have failed.
|
|
1341
|
+
* Defaults to false.
|
|
1342
|
+
*/
|
|
1343
|
+
skipFailedRequests?: boolean;
|
|
1344
|
+
/** Plugin specific rate limiting configuration */
|
|
1345
|
+
plugin?: {
|
|
1346
|
+
[pluginId: string]: {
|
|
1347
|
+
/**
|
|
1348
|
+
* Time frame in milliseconds or as human duration for which requests are checked/remembered.
|
|
1349
|
+
* Defaults to one minute.
|
|
1350
|
+
*/
|
|
1351
|
+
window?: string | HumanDuration;
|
|
1352
|
+
/**
|
|
1353
|
+
* The maximum number of connections to allow during the `window` before rate limiting the client.
|
|
1354
|
+
* Defaults to 5.
|
|
1355
|
+
*/
|
|
1356
|
+
incomingRequestLimit?: number;
|
|
1357
|
+
/**
|
|
1358
|
+
* Whether to pass requests in case of store failure.
|
|
1359
|
+
* Defaults to false.
|
|
1360
|
+
*/
|
|
1361
|
+
passOnStoreError?: boolean;
|
|
1362
|
+
/**
|
|
1363
|
+
* List of allowed IP addresses that are not rate limited.
|
|
1364
|
+
* Defaults to [127.0.0.1, 0:0:0:0:0:0:0:1, ::1].
|
|
1365
|
+
*/
|
|
1366
|
+
ipAllowList?: string[];
|
|
1367
|
+
/**
|
|
1368
|
+
* Skip rate limiting for requests that have been successful.
|
|
1369
|
+
* Defaults to false.
|
|
1370
|
+
*/
|
|
1371
|
+
skipSuccessfulRequests?: boolean;
|
|
1372
|
+
/**
|
|
1373
|
+
* Skip rate limiting for requests that have failed.
|
|
1374
|
+
* Defaults to false.
|
|
1375
|
+
*/
|
|
1376
|
+
skipFailedRequests?: boolean;
|
|
1377
|
+
};
|
|
1378
|
+
};
|
|
1379
|
+
};
|
|
1380
|
+
|
|
1381
|
+
/**
|
|
1382
|
+
* Configuration related to URL reading, used for example for reading catalog info
|
|
1383
|
+
* files, scaffolder templates, and techdocs content.
|
|
1384
|
+
*/
|
|
1385
|
+
reading?: {
|
|
1386
|
+
/**
|
|
1387
|
+
* A list of targets to allow outgoing requests to. Users will be able to make
|
|
1388
|
+
* requests on behalf of the backend to the targets that are allowed by this list.
|
|
1389
|
+
*/
|
|
1390
|
+
allow?: Array<{
|
|
1391
|
+
/**
|
|
1392
|
+
* A host to allow outgoing requests to, being either a full host or
|
|
1393
|
+
* a subdomain wildcard pattern with a leading `*`. For example `example.com`
|
|
1394
|
+
* and `*.example.com` are valid values, `prod.*.example.com` is not.
|
|
1395
|
+
* The host may also contain a port, for example `example.com:8080`.
|
|
1396
|
+
*/
|
|
1397
|
+
host: string;
|
|
1398
|
+
|
|
1399
|
+
/**
|
|
1400
|
+
* An optional list of paths. In case they are present only targets matching
|
|
1401
|
+
* any of them will are allowed. You can use trailing slashes to make sure only
|
|
1402
|
+
* subdirectories are allowed, for example `/mydir/` will allow targets with
|
|
1403
|
+
* paths like `/mydir/a` but will block paths like `/mydir2`.
|
|
1404
|
+
*/
|
|
1405
|
+
paths?: string[];
|
|
1406
|
+
}>;
|
|
1407
|
+
};
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1410
|
+
/**
|
|
1411
|
+
* Options used by the default discovery service.
|
|
1412
|
+
*/
|
|
1413
|
+
discovery?: {
|
|
1414
|
+
/**
|
|
1415
|
+
* A list of target base URLs and their associated plugins.
|
|
1416
|
+
*
|
|
1417
|
+
* @example
|
|
1418
|
+
*
|
|
1419
|
+
* ```yaml
|
|
1420
|
+
* discovery:
|
|
1421
|
+
* endpoints:
|
|
1422
|
+
* - target: https://internal.example.com/internal-catalog
|
|
1423
|
+
* plugins: [catalog]
|
|
1424
|
+
* - target: https://internal.example.com/secure/api/{{pluginId}}
|
|
1425
|
+
* plugins: [auth, permission]
|
|
1426
|
+
* - target:
|
|
1427
|
+
* internal: http+srv://backstage-plugin-{{pluginId}}.http.${SERVICE_DOMAIN}/search
|
|
1428
|
+
* external: https://example.com/search
|
|
1429
|
+
* plugins: [search]
|
|
1430
|
+
* ```
|
|
1431
|
+
*/
|
|
1432
|
+
endpoints: Array<{
|
|
1433
|
+
/**
|
|
1434
|
+
* The target base URL to use for the given set of plugins. Note that this
|
|
1435
|
+
* needs to be a full URL including the protocol and path parts that fully
|
|
1436
|
+
* address the root of a plugin's API endpoints.
|
|
1437
|
+
*
|
|
1438
|
+
* @remarks
|
|
1439
|
+
*
|
|
1440
|
+
* Can be either a single URL or an object where you can explicitly give a
|
|
1441
|
+
* dedicated URL for internal (as seen from the backend) and/or external (as
|
|
1442
|
+
* seen from the frontend) lookups.
|
|
1443
|
+
*
|
|
1444
|
+
* The default behavior is to use the backend base URL for external lookups,
|
|
1445
|
+
* and a URL formed from the `.listen` and `.https` configs for internal
|
|
1446
|
+
* lookups. Adding discovery endpoints as described here overrides one or both
|
|
1447
|
+
* of those behaviors for a given set of plugins.
|
|
1448
|
+
*
|
|
1449
|
+
* URLs can be in the form of a regular HTTP or HTTPS URL if you are using
|
|
1450
|
+
* A/AAAA/CNAME records or IP addresses. Specifically for internal URLs, if
|
|
1451
|
+
* you add `+src` to the protocol part then the hostname is treated as an SRV
|
|
1452
|
+
* record name and resolved. For example, if you pass in
|
|
1453
|
+
* `http+srv://<srv-record>/path` then the record part is resolved into an
|
|
1454
|
+
* actual host and port (with random weighted choice as usual when there is
|
|
1455
|
+
* more than one match).
|
|
1456
|
+
*
|
|
1457
|
+
* Any strings with `{{pluginId}}` or `{{ pluginId }}` placeholders in them
|
|
1458
|
+
* will have them replaced with the plugin ID.
|
|
1459
|
+
*
|
|
1460
|
+
* Example URLs:
|
|
1461
|
+
*
|
|
1462
|
+
* - `https://internal.example.com/secure/api/{{pluginId}}`
|
|
1463
|
+
* - `http+srv://backstage-plugin-{{pluginId}}.http.${SERVICE_DOMAIN}/api/{{pluginId}}`
|
|
1464
|
+
* (can only be used in the `internal` key)
|
|
1465
|
+
*/
|
|
1466
|
+
target: string | { internal?: string; external?: string };
|
|
1467
|
+
/**
|
|
1468
|
+
* Array of plugins which use that target base URL.
|
|
1469
|
+
*
|
|
1470
|
+
* The special value `*` can be used to match all plugins.
|
|
1471
|
+
*/
|
|
1472
|
+
plugins: string[];
|
|
1473
|
+
}>;
|
|
1474
|
+
};
|
|
1475
|
+
}
|