-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathcheckly-config-loader.ts
149 lines (137 loc) · 4.19 KB
/
checkly-config-loader.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import * as path from 'path'
import { existsSync } from 'fs'
import { loadJsFile, loadTsFile } from './util'
import { CheckProps } from '../constructs/check'
import { Session } from '../constructs'
import { Construct } from '../constructs/construct'
import type { Region } from '..'
import { ReporterType } from '../reporters/reporter'
import * as fs from 'fs'
import { PlaywrightConfig } from '../constructs/playwright-config'
export type CheckConfigDefaults = Pick<CheckProps, 'activated' | 'muted' | 'doubleCheck'
| 'shouldFail' | 'runtimeId' | 'locations' | 'tags' | 'frequency' | 'environmentVariables'
| 'alertChannels' | 'privateLocations' | 'retryStrategy' | 'alertEscalationPolicy'>
export type ChecklyConfig = {
/**
* Friendly name for your project.
*/
projectName: string,
/**
* Unique project identifier.
*/
logicalId: string,
/**
* Git repository URL.
*/
repoUrl?: string,
/**
* Checks default configuration properties.
*/
checks?: CheckConfigDefaults & {
/**
* Glob pattern where the CLI looks for files containing Check constructs, i.e. all `.checks.ts` files
*/
checkMatch?: string | string[],
/**
* List of glob patterns with directories to ignore.
*/
ignoreDirectoriesMatch?: string[],
playwrightConfig?: PlaywrightConfig,
/**
* Browser checks default configuration properties.
*/
browserChecks?: CheckConfigDefaults & {
/**
* Glob pattern where the CLI looks for Playwright test files, i.e. all `.spec.ts` files
*/
testMatch?: string | string[],
},
/**
* Multistep checks default configuration properties.
*/
multiStepChecks?: CheckConfigDefaults & {
/**
* Glob pattern where the CLI looks for Playwright test files, i.e. all `.spec.ts` files
*/
testMatch?: string | string[],
},
},
/**
* CLI default configuration properties.
*/
cli?: {
runLocation?: keyof Region,
privateRunLocation?: string,
verbose?: boolean,
failOnNoMatching?: boolean,
reporters?: ReporterType[],
retries?: number,
}
}
// eslint-disable-next-line no-restricted-syntax
enum Extension {
JS = '.js',
MJS = '.mjs',
TS = '.ts',
}
export function loadFile (file: string) {
if (!existsSync(file)) {
return Promise.resolve(null)
}
switch (path.extname(file)) {
case Extension.JS:
return loadJsFile(file)
case Extension.MJS:
return loadJsFile(file)
case Extension.TS:
return loadTsFile(file)
default:
throw new Error(`Unsupported file extension ${file} for the config file`)
}
}
function isString (obj: any) {
return (Object.prototype.toString.call(obj) === '[object String]')
}
export function getChecklyConfigFile (): {checklyConfig: string, fileName: string} | undefined {
const filenames: string[] = ['checkly.config.ts', 'checkly.config.js', 'checkly.config.mjs']
let config
for (const configFile of filenames) {
const dir = path.resolve(path.dirname(configFile))
if (!existsSync(path.resolve(dir, configFile))) {
continue
}
const file = fs.readFileSync(path.resolve(dir, configFile))
if (file) {
config = {
checklyConfig: file.toString(),
fileName: configFile,
}
break
}
}
return config
}
export async function loadChecklyConfig (dir: string, filenames = ['checkly.config.ts', 'checkly.config.js', 'checkly.config.mjs']): Promise<{ config: ChecklyConfig, constructs: Construct[] }> {
let config
Session.loadingChecklyConfigFile = true
Session.checklyConfigFileConstructs = []
for (const filename of filenames) {
config = await loadFile(path.join(dir, filename))
if (config) {
break
}
}
if (!config) {
throw new Error(`Unable to locate a config at ${dir} with ${filenames.join(', ')}.`)
}
for (const field of ['logicalId', 'projectName']) {
const requiredField = config?.[field]
if (!requiredField || !(isString(requiredField))) {
throw new Error(`Config object missing a ${field} as type string`)
}
}
const constructs = Session.checklyConfigFileConstructs
Session.loadingChecklyConfigFile = false
Session.checklyConfigFileConstructs = []
return { config, constructs }
}