1 | import * as exp from "express";
|
2 | import { HandleCommand } from "./HandleCommand";
|
3 | import { HandleEvent } from "./HandleEvent";
|
4 | import { ExpressServerOptions } from "./internal/transport/express/ExpressServer";
|
5 | import { AutomationEventListener } from "./server/AutomationEventListener";
|
6 | import { AutomationMetadataProcessor } from "./spi/env/MetadataProcessor";
|
7 | import { SecretResolver } from "./spi/env/SecretResolver";
|
8 | import { HttpClientFactory } from "./spi/http/httpClient";
|
9 | import { Maker } from "./util/constructionUtils";
|
10 | /**
|
11 | * Customize the express server configuration: For example to add custom routes
|
12 | *
|
13 | * Example:
|
14 | *
|
15 | * const newRouteCustomizer = (express: exp.Express, ...handlers: exp.RequestHandler[]) => {
|
16 | * express.get("/new-route", ...handlers, (req, res) => {
|
17 | * res.json({ key: "value" });
|
18 | * });
|
19 | * }
|
20 | */
|
21 | export declare type ExpressCustomizer = (express: exp.Express, ...handlers: exp.RequestHandler[]) => void;
|
22 | /**
|
23 | * Post process the configuration after is has been merged from the various locations, but
|
24 | * before starting the automation client.
|
25 | */
|
26 | export declare type ConfigurationPostProcessor<T = AnyOptions> = (configuration: Configuration) => Promise<Configuration & T>;
|
27 | /**
|
28 | * A computed banner
|
29 | */
|
30 | export interface Banner {
|
31 | /**
|
32 | * Banner content
|
33 | */
|
34 | banner: string;
|
35 | /**
|
36 | * Whether or not the banner content should be asciified
|
37 | */
|
38 | asciify: boolean;
|
39 | color: "black" | "red" | "green" | "yellow" | "blue" | "magenta" | "cyan" | "white" | "gray";
|
40 | }
|
41 | /**
|
42 | * A section that should be displayed in the banner.
|
43 | */
|
44 | export interface BannerSection {
|
45 | title: string;
|
46 | body: string;
|
47 | }
|
48 | /**
|
49 | * Custom configuration you can abuse to your benefit
|
50 | */
|
51 | export interface AnyOptions {
|
52 | /** Abuse goes here */
|
53 | [key: string]: any;
|
54 | }
|
55 | /**
|
56 | * Options for an automation node.
|
57 | */
|
58 | export interface AutomationOptions extends AnyOptions {
|
59 | /**
|
60 | * Automation name. If not given, the name is extracted from
|
61 | * the package.json.
|
62 | */
|
63 | name?: string;
|
64 | /**
|
65 | * Automation version. Must be a valid semantic version,
|
66 | * https://semver.org/. If not given, the version is extracted
|
67 | * from the package.json.
|
68 | */
|
69 | version?: string;
|
70 | /**
|
71 | * Atomist workspaces this automation will be registered with. Must be
|
72 | * specified if groups is not specified. Cannot be specified if
|
73 | * groups is specified.
|
74 | */
|
75 | workspaceIds?: string[];
|
76 | /**
|
77 | * DO NOT USE. Groups this automation will be registered with.
|
78 | * Must be specified if teams is not specified. Cannot be
|
79 | * specified if teams is specified. Providing groups indicates
|
80 | * this is a global automation, which can only successfully be
|
81 | * registered by Atomist.
|
82 | */
|
83 | groups?: string[];
|
84 | /**
|
85 | * If events should be queued when the registration is not
|
86 | * connected to the websocket, specificy "durable". "ephemeral"
|
87 | * is suited for testing and running locally and is the default.
|
88 | */
|
89 | policy?: "ephemeral" | "durable";
|
90 | /**
|
91 | * Atomist API Key used to authenticate the user starting the client.
|
92 | */
|
93 | apiKey?: string;
|
94 | /** HTTP configuration, useful for health checks */
|
95 | http?: {
|
96 | enabled?: boolean;
|
97 | client?: {
|
98 | factory?: HttpClientFactory;
|
99 | };
|
100 | } & Partial<ExpressServerOptions>;
|
101 | /** websocket configuration */
|
102 | ws?: {
|
103 | enabled?: boolean;
|
104 | termination?: {
|
105 | /**
|
106 | * if true, give in-flight transactions `gracePeriod`
|
107 | * milliseconds to complete when shutting down
|
108 | */
|
109 | graceful?: boolean;
|
110 | /** grace period in millisends */
|
111 | gracePeriod?: number;
|
112 | };
|
113 | /** compress messages over websocket */
|
114 | compress?: boolean;
|
115 | /** timeout in milliseconds */
|
116 | timeout?: number;
|
117 | };
|
118 | /** Atomist API endpoints */
|
119 | endpoints?: {
|
120 | graphql?: string;
|
121 | api?: string;
|
122 | };
|
123 | /**
|
124 | * Post-processors can be used to modify the configuration after
|
125 | * all standard configuration loading has been done and before the
|
126 | * client is started. Post-processors return a configuration
|
127 | * promise so they can be asynchronous.
|
128 | */
|
129 | postProcessors?: ConfigurationPostProcessor[];
|
130 | }
|
131 | /**
|
132 | * Options useful when running an automation client in server mode.
|
133 | */
|
134 | export interface AutomationServerOptions extends AutomationOptions {
|
135 | /** environment automation is running in, e.g., "production" or "testing" */
|
136 | environment?: string;
|
137 | /**
|
138 | * Application identifier used for metrics send to statsd. If not
|
139 | * set, the automation client package name with any namespace
|
140 | * prefix removed is used.
|
141 | */
|
142 | application?: string;
|
143 | /** keywords useful for discovery */
|
144 | keywords?: string[];
|
145 | /** Whether and where to send application start and stop events to Atomist. */
|
146 | applicationEvents?: {
|
147 | enabled?: boolean;
|
148 | workspaceId?: string;
|
149 | };
|
150 | /**
|
151 | * Whether and how many workers to start up. If enabled is true
|
152 | * and workers is false, a number of workers equal to the number
|
153 | * of available CPUs will be started.
|
154 | */
|
155 | cluster?: {
|
156 | enabled?: boolean;
|
157 | workers?: number;
|
158 | };
|
159 | /** Logging configuration */
|
160 | logging?: {
|
161 | /** Log level, default is "info" */
|
162 | level?: "debug" | "info" | "warn" | "error";
|
163 | /**
|
164 | * Custom log configuration, useful if your logging solution
|
165 | * requires host, port, token, etc. configuration.
|
166 | */
|
167 | custom?: any;
|
168 | /**
|
169 | * Print welcome banner; set to an arbitrary string to display,
|
170 | * default is name of automation-client
|
171 | */
|
172 | banner?: {
|
173 | enabled?: boolean;
|
174 | /** Message or Banner to be printed at the top of the banner */
|
175 | message?: string | ((configuration: Configuration) => Banner);
|
176 | /**
|
177 | * Add content to the banner which shows up between handlers and
|
178 | * footer
|
179 | */
|
180 | contributors?: Array<(configuration: Configuration) => string | BannerSection>;
|
181 | };
|
182 | /**
|
183 | * Log to file; set to file path to overwrite location and name of logfile,
|
184 | * defaults to ./log/automation-client.log in current working directory
|
185 | */
|
186 | file?: {
|
187 | enabled?: boolean;
|
188 | name?: string;
|
189 | level?: string;
|
190 | };
|
191 | };
|
192 | /** statsd config */
|
193 | statsd?: {
|
194 | /** Whether to send metrics statsd, default is false */
|
195 | enabled?: boolean;
|
196 | /**
|
197 | * statsd host. If not set, use the host-shots default,
|
198 | * "localhost" at the time of this writing.
|
199 | */
|
200 | host?: string;
|
201 | /**
|
202 | * statsd port. If not set, use the hot-shots default, 8125
|
203 | * at the time of this writing.
|
204 | */
|
205 | port?: number;
|
206 | };
|
207 | /** Register a custom secret resolver */
|
208 | secretResolver?: SecretResolver;
|
209 | /** Register a custom AutomationMetadataProcessor */
|
210 | metadataProcessor?: AutomationMetadataProcessor;
|
211 | }
|
212 | /**
|
213 | * Atomist automation configuration.
|
214 | */
|
215 | export interface Configuration extends AutomationServerOptions {
|
216 | /**
|
217 | * Automation commands this package provides. If empty or null,
|
218 | * the package will be scanned for commands, which must be under a
|
219 | * directory named "commands".
|
220 | */
|
221 | commands?: Array<Maker<HandleCommand>>;
|
222 | /**
|
223 | * Automation event handlers this package provides. If empty or
|
224 | * null, the package will be scanned for event handlers, which
|
225 | * must be under a directory named "events".
|
226 | */
|
227 | events?: Array<Maker<HandleEvent>>;
|
228 | /** Custom event ingester */
|
229 | ingesters?: string[];
|
230 | /** Log and metric sinks */
|
231 | listeners?: AutomationEventListener[];
|
232 | }
|
233 | /**
|
234 | * User per-automation configuration
|
235 | */
|
236 | export interface ModuleOptions extends AutomationServerOptions {
|
237 | /** Automation name this configuration applies to. */
|
238 | name: string;
|
239 | /**
|
240 | * A valid version or version range, as defined by
|
241 | * https://www.npmjs.com/package/semver, this configuration
|
242 | * applies to. If not provided, it applies to all versions of the
|
243 | * named automation.
|
244 | */
|
245 | version?: string;
|
246 | }
|
247 | /**
|
248 | * User-wide configuration and user per-automation configuration
|
249 | */
|
250 | export interface UserConfig extends AutomationServerOptions {
|
251 | modules?: ModuleOptions[];
|
252 | }
|
253 | /**
|
254 | * Generate defaults for various configuration option values. These
|
255 | * will only be used if values are not provided by any source. Values
|
256 | * not provided here will be `undefined`.
|
257 | *
|
258 | * @return default configuration
|
259 | */
|
260 | export declare function defaultConfiguration(): Configuration;
|
261 | /**
|
262 | * Exposes the configuration for lookup of configuration values.
|
263 | * This is useful for components to obtain values eg. from configuration.custom
|
264 | * like user provided secrets etc.
|
265 | * @param {string} path the property path evaluated against the configuration instance
|
266 | * @returns {T}
|
267 | */
|
268 | export declare function configurationValue<T>(path: string, defaultValue?: T): T;
|
269 | /**
|
270 | * Return user automation client configuration path.
|
271 | */
|
272 | export declare function userConfigPath(): string;
|
273 | /**
|
274 | * Write user config securely, creating directories as necessary.
|
275 | */
|
276 | export declare function writeUserConfig(cfg: UserConfig): Promise<void>;
|
277 | /**
|
278 | * Read and return user config from UserConfigFile.
|
279 | */
|
280 | export declare function getUserConfig(): UserConfig;
|
281 | /**
|
282 | * Overwrite values in the former configuration with values in the
|
283 | * latter. The start object is modified.
|
284 | *
|
285 | * @param obj starting configuration
|
286 | * @param override configuration values to add/override those in start
|
287 | * @return resulting merged configuration
|
288 | */
|
289 | export declare function mergeConfigs(obj: Configuration, ...sources: Configuration[]): Configuration;
|
290 | /**
|
291 | * Merge a user's global and proper per-module configuration, if it
|
292 | * exists. Values from the per-module configuration take precedence
|
293 | * over the user-wide values. Per-module configuration is gotten from
|
294 | * the first per-module configuration that matches name and,
|
295 | * optionally, the version is within the per-module configuration's
|
296 | * version range. A module configuration without a version range
|
297 | * matches the named module with any version. If no version is
|
298 | * provided, any version range is satisfied, meaning the first
|
299 | * per-module configuration with a matching name is used. If no name
|
300 | * is provide, only the user configuration is loaded. The first
|
301 | * per-module match is used. This means if you have multiple
|
302 | * configurations for the same named module and you want to include a
|
303 | * default configuration for that module, put a configuration without
|
304 | * a version range _after_ all the configurations with version ranges.
|
305 | * Note that only values from the first per-module match are used.
|
306 | *
|
307 | * @param userConfig the user's configuration, which may include per-module configuration
|
308 | * @param name automation client package name to load as module config if it exists
|
309 | * @param version automation client package version to load as module config if
|
310 | * version satifies module config version range
|
311 | * @return the merged module and user configuration
|
312 | */
|
313 | export declare function resolveModuleConfig(userConfig: UserConfig, name?: string, version?: string): AutomationServerOptions;
|
314 | /**
|
315 | * Try to read user config, overriding its values with a per-module
|
316 | * configuration that matches this automation.
|
317 | *
|
318 | * @param name automation client package name to load as module config if it exists
|
319 | * @param version automation client package version to load as module config if
|
320 | * version satifies module config version range
|
321 | * @return module-specific config with user config supplying defaults
|
322 | */
|
323 | export declare function loadUserConfiguration(name?: string, version?: string): AutomationServerOptions;
|
324 | /**
|
325 | * Load the automation configuration from the configuration object
|
326 | * exported from cfgPath and return it. If no configuration path is
|
327 | * provided, the package will be searched for a file named
|
328 | * atomist.config.js. If no atomist.config.js is found, an empty
|
329 | * object is returned. If more than one is found, an exception is
|
330 | * thrown.
|
331 | *
|
332 | * @param cfgPath location of automation configuration
|
333 | * @return automation configuration
|
334 | */
|
335 | export declare function loadAutomationConfig(cfgPath?: string): Configuration;
|
336 | /**
|
337 | * Load configuration from the file defined by the ATOMIST_CONFIG_PATH
|
338 | * environment variable, if it the variable is defined and the file
|
339 | * exists, and return it. The contents of the ATOMIST_CONFIG_PATH
|
340 | * file should be serialized JSON of AutomationServerOptions. If the
|
341 | * environment variable is not defined or the file path specified by
|
342 | * its value cannot be read as JSON, an empty object is returned.
|
343 | *
|
344 | * @return automation server options
|
345 | */
|
346 | export declare function loadAtomistConfigPath(): AutomationServerOptions;
|
347 | /**
|
348 | * Load configuration from the ATOMIST_CONFIG environment variable, if
|
349 | * it the variable is defined, and merge it into the passed in
|
350 | * configuration. The value of the ATOMIST_CONFIG environment
|
351 | * variable should be serialized JSON of AutomationServerOptions. The
|
352 | * values from the environment variable will override values in the
|
353 | * passed in configuration. If the environment variable is not
|
354 | * defined, the passed in configuration is returned unchanged.
|
355 | *
|
356 | * @return automation server options
|
357 | */
|
358 | export declare function loadAtomistConfig(): AutomationServerOptions;
|
359 | /**
|
360 | * Examine environment, config, and cfg for Atomist workspace IDs.
|
361 | * The ATOMIST_WORKSPACES environment variable takes precedence over
|
362 | * the configuration "workspaceIds", which takes precedence over
|
363 | * cfg.workspaceId, which may be undefined, null, or an empty array.
|
364 | * If the ATOMIST_WORKSPACES environment variable is not set,
|
365 | * workspaceIds is not set in config, and workspaceIds is falsey in
|
366 | * cfg and teamIds is resolvable from the configuration, workspaceIds
|
367 | * is set to teamIds.
|
368 | *
|
369 | * @param cfg current configuration, whose workspaceIds and teamIds
|
370 | * properties may be modified by this function
|
371 | * @return the resolved workspace IDs
|
372 | */
|
373 | export declare function resolveWorkspaceIds(cfg: Configuration): string[];
|
374 | /**
|
375 | * Resolve a value from a environment variables or configuration keys.
|
376 | * The environment variables are checked in order and take precedence
|
377 | * over the configuration key, which are also checked in order. If
|
378 | * no truthy values are found, undefined is returned.
|
379 | *
|
380 | * @param environmentVariables environment variables to check
|
381 | * @param configKeyPaths configuration keys, as JSON paths, to check
|
382 | * @param defaultValue value to use if no environment variables or config keys have values
|
383 | * @return first truthy value found, or defaultValue
|
384 | */
|
385 | export declare function resolveConfigurationValue(environmentVariables: string[], configKeyPaths: string[], defaultValue?: string): string;
|
386 | /**
|
387 | * Resolve the HTTP port from the environment and configuration. The
|
388 | * PORT environment variable takes precedence over the config value.
|
389 | */
|
390 | export declare function resolvePort(cfg: Configuration): number;
|
391 | /**
|
392 | * Resolve ATOMIST_ environment variables and add them to config.
|
393 | * Variables of like ATOMIST_custom_foo_bar will be converted to
|
394 | * a json path of custom.foo.bar.
|
395 | * @param {Configuration} cfg
|
396 | */
|
397 | export declare function resolveEnvironmentVariables(cfg: Configuration): void;
|
398 | /**
|
399 | * Resolve placeholders against the process.env.
|
400 | * Placeholders should be of form ${ENV_VAR}. Placeholders support default values
|
401 | * in case they aren't defined: ${ENV_VAR:default value}
|
402 | * @param {Configuration} config
|
403 | */
|
404 | export declare function resolvePlaceholders(cfg: Configuration): void;
|
405 | /**
|
406 | * Invoke postProcessors on the provided configuration.
|
407 | */
|
408 | export declare function invokePostProcessors(cfg: Configuration): Promise<Configuration>;
|
409 | /**
|
410 | * Make sure final configuration has the minimum configuration it
|
411 | * needs. It will throw an error if required properties are missing.
|
412 | *
|
413 | * @param cfg final configuration
|
414 | */
|
415 | export declare function validateConfiguration(cfg: Configuration): void;
|
416 | /**
|
417 | * Load and populate the automation configuration. The configuration
|
418 | * is loaded from several locations with the following precedence from
|
419 | * highest to lowest.
|
420 | *
|
421 | * 0. Recognized environment variables (see below)
|
422 | * 1. The value of the ATOMIST_CONFIG environment variable, parsed as
|
423 | * JSON and cast to AutomationServerOptions
|
424 | * 2. The contents of the ATOMIST_CONFIG_PATH file as AutomationServerOptions
|
425 | * 3. The automation's atomist.config.js exported configuration as
|
426 | * Configuration
|
427 | * 4. The contents of the user's client.config.json as UserConfig
|
428 | * resolving user and per-module configuration into Configuration
|
429 | * 5. ProductionDefaultConfiguration if ATOMIST_ENV or NODE_ENV is set
|
430 | * to "production" or TestingDefaultConfiguration if ATOMIST_ENV or
|
431 | * NODE_ENV is set to "staging" or "testing", with ATOMIST_ENV
|
432 | * taking precedence over NODE_ENV.
|
433 | * 6. LocalDefaultConfiguration
|
434 | *
|
435 | * If any of the sources are missing, they are ignored. Any truthy
|
436 | * configuration values specified by sources of higher precedence
|
437 | * cause any values provided by sources of lower precedence to be
|
438 | * ignored. Arrays are replaced, not merged. Typically the only
|
439 | * required values in the configuration for a successful registration
|
440 | * are the apiKey and non-empty workspaceIds.
|
441 | *
|
442 | * Placeholder of the form `${ENV_VARIABLE}` in string configuration
|
443 | * values will get resolved against the environment. The resolution
|
444 | * happens at the very end when all configs have been merged.
|
445 | *
|
446 | * The configuration exported from the atomist.config.js is modified
|
447 | * to contain the final configuration values and returned from this
|
448 | * function.
|
449 | *
|
450 | * @param cfgPath path to file exporting the configuration object, if
|
451 | * not provided the package is searched for one
|
452 | * @return merged configuration object
|
453 | */
|
454 | export declare function loadConfiguration(cfgPath?: string): Promise<Configuration>;
|
455 | /**
|
456 | * Default configuration when running in neither testing or
|
457 | * production.
|
458 | */
|
459 | export declare const LocalDefaultConfiguration: Configuration;
|
460 | /**
|
461 | * Configuration defaults for production environments.
|
462 | */
|
463 | export declare const ProductionDefaultConfiguration: Partial<Configuration>;
|
464 | /**
|
465 | * Configuration defaults for pre-production environments.
|
466 | */
|
467 | export declare const TestingDefaultConfiguration: Partial<Configuration>;
|
468 | //# sourceMappingURL=configuration.d.ts.map |
\ | No newline at end of file |