@elastic/synthetics 1.0.0-beta.32 → 1.0.0-beta.34

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.
Files changed (51) hide show
  1. package/dist/cli.js +6 -4
  2. package/dist/cli.js.map +1 -1
  3. package/dist/common_types.d.ts +7 -4
  4. package/dist/common_types.d.ts.map +1 -1
  5. package/dist/config.d.ts +1 -0
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js +2 -1
  8. package/dist/config.js.map +1 -1
  9. package/dist/generator/index.d.ts +1 -6
  10. package/dist/generator/index.d.ts.map +1 -1
  11. package/dist/generator/index.js +5 -14
  12. package/dist/generator/index.js.map +1 -1
  13. package/dist/generator/utils.d.ts.map +1 -1
  14. package/dist/generator/utils.js +3 -0
  15. package/dist/generator/utils.js.map +1 -1
  16. package/dist/helpers.d.ts +1 -0
  17. package/dist/helpers.d.ts.map +1 -1
  18. package/dist/helpers.js +5 -1
  19. package/dist/helpers.js.map +1 -1
  20. package/dist/push/bundler.d.ts +1 -0
  21. package/dist/push/bundler.d.ts.map +1 -1
  22. package/dist/push/bundler.js +16 -1
  23. package/dist/push/bundler.js.map +1 -1
  24. package/dist/push/index.d.ts +7 -2
  25. package/dist/push/index.d.ts.map +1 -1
  26. package/dist/push/index.js +49 -28
  27. package/dist/push/index.js.map +1 -1
  28. package/dist/push/monitor.d.ts +6 -1
  29. package/dist/push/monitor.d.ts.map +1 -1
  30. package/dist/push/monitor.js +3 -3
  31. package/dist/push/monitor.js.map +1 -1
  32. package/dist/push/plugin.d.ts.map +1 -1
  33. package/dist/push/plugin.js +30 -7
  34. package/dist/push/plugin.js.map +1 -1
  35. package/dist/push/request.d.ts.map +1 -1
  36. package/dist/push/request.js +1 -0
  37. package/dist/push/request.js.map +1 -1
  38. package/dist/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +5 -3
  40. package/src/cli.ts +11 -7
  41. package/src/common_types.ts +8 -4
  42. package/src/config.ts +1 -1
  43. package/src/generator/index.ts +5 -20
  44. package/src/generator/utils.ts +3 -0
  45. package/src/helpers.ts +5 -1
  46. package/src/push/bundler.ts +21 -2
  47. package/src/push/index.ts +65 -36
  48. package/src/push/monitor.ts +5 -4
  49. package/src/push/plugin.ts +38 -9
  50. package/src/push/request.ts +1 -0
  51. package/templates/synthetics.config.ts +8 -0
package/src/cli.ts CHANGED
@@ -72,7 +72,7 @@ program
72
72
  .addOption(match)
73
73
  .addOption(params)
74
74
  .addOption(
75
- new Option('--reporter <value>', `output repoter format`).choices(
75
+ new Option('--reporter <value>', `output reporter format`).choices(
76
76
  Object.keys(reporters)
77
77
  )
78
78
  )
@@ -152,9 +152,13 @@ program
152
152
  .description(
153
153
  'Push all journeys in the current directory to create monitors within the Kibana monitor management UI'
154
154
  )
155
- .requiredOption(
156
- '--auth <auth>',
157
- 'API key used for Kibana authentication(https://www.elastic.co/guide/en/kibana/master/api-keys.html).'
155
+ .addOption(
156
+ new Option(
157
+ '--auth <auth>',
158
+ 'API key used for Kibana authentication(https://www.elastic.co/guide/en/kibana/master/api-keys.html).'
159
+ )
160
+ .env('SYNTHETICS_API_KEY')
161
+ .makeOptionMandatory(true)
158
162
  )
159
163
  .option(
160
164
  '--schedule <time-in-minutes>',
@@ -173,8 +177,8 @@ program
173
177
  )
174
178
  .option('--url <url>', 'Kibana URL to upload the monitors')
175
179
  .option(
176
- '--project <id>',
177
- 'id that will be used for logically grouping monitors'
180
+ '--id <id>',
181
+ 'project id that will be used for logically grouping monitors'
178
182
  )
179
183
  .option(
180
184
  '--space <space>',
@@ -187,8 +191,8 @@ program
187
191
  .addOption(playwrightOpts)
188
192
  .action(async (cmdOpts: PushOptions) => {
189
193
  try {
190
- const settings = await loadSettings();
191
194
  await loadTestFiles({ inline: false }, [cwd()]);
195
+ const settings = await loadSettings();
192
196
  const options = normalizeOptions({
193
197
  ...program.opts(),
194
198
  ...settings,
@@ -241,21 +241,25 @@ export type RunOptions = BaseArgs & {
241
241
  reporter?: BuiltInReporterName | ReporterInstance;
242
242
  };
243
243
 
244
- export type PushOptions = {
244
+ export type PushOptions = ProjectSettings & {
245
245
  auth: string;
246
- url: string;
247
- project: string;
248
- space: string;
249
246
  schedule?: MonitorConfig['schedule'];
250
247
  locations?: MonitorConfig['locations'];
251
248
  privateLocations?: MonitorConfig['privateLocations'];
252
249
  };
253
250
 
251
+ export type ProjectSettings = {
252
+ id: string;
253
+ url: string;
254
+ space: string;
255
+ };
256
+
254
257
  export type PlaywrightOptions = LaunchOptions & BrowserContextOptions;
255
258
  export type SyntheticsConfig = {
256
259
  params?: Params;
257
260
  playwrightOptions?: PlaywrightOptions;
258
261
  monitor?: MonitorConfig;
262
+ project?: ProjectSettings;
259
263
  };
260
264
 
261
265
  /** Runner Payload types */
package/src/config.ts CHANGED
@@ -80,7 +80,7 @@ function getConfigFile(ext: string) {
80
80
  return 'synthetics.config' + ext;
81
81
  }
82
82
 
83
- function findSyntheticsConfig(resolvePath, cwd) {
83
+ export function findSyntheticsConfig(resolvePath, cwd) {
84
84
  const configPath = ['.js', '.ts']
85
85
  .map(ext => resolve(resolvePath, getConfigFile(ext)))
86
86
  .find(isFile);
@@ -37,16 +37,11 @@ import {
37
37
  cloudIDToKibanaURL,
38
38
  } from './utils';
39
39
  import { formatLocations, getLocations, groupLocations } from '../locations';
40
+ import type { ProjectSettings } from '../common_types';
40
41
 
41
42
  // Templates that are required for setting up new synthetics project
42
43
  const templateDir = join(__dirname, '..', '..', 'templates');
43
44
 
44
- export type ProjectSettings = {
45
- url: string;
46
- space: string;
47
- project: string;
48
- };
49
-
50
45
  type PromptOptions = ProjectSettings & {
51
46
  locations: Array<string>;
52
47
  privateLocations: Array<string>;
@@ -61,11 +56,10 @@ export const REGULAR_FILES_PATH = [
61
56
  '.github/workflows/run-synthetics.yml',
62
57
  'README.md',
63
58
  ];
64
- export const SETTINGS_PATH = '.synthetics/project.json';
65
59
  export const CONFIG_PATH = 'synthetics.config.ts';
66
60
 
67
61
  // Files to be overriden by default if the project is initialized multiple times
68
- const DEFAULT_OVERRIDES = [SETTINGS_PATH, CONFIG_PATH];
62
+ const DEFAULT_OVERRIDES = [CONFIG_PATH];
69
63
 
70
64
  export class Generator {
71
65
  pkgManager = 'npm';
@@ -123,8 +117,7 @@ export class Generator {
123
117
  const allLocations = await getLocations({ url, auth });
124
118
  const locChoices = formatLocations(allLocations);
125
119
  if (locChoices.length === 0) {
126
- // TODO - Add link to docs
127
- throw 'Follow the docs to set up your first private locations - <link>';
120
+ throw 'Follow the docs to set up your first private locations - https://www.elastic.co/guide/en/observability/current/uptime-set-up-choose-agent.html#private-locations';
128
121
  }
129
122
 
130
123
  const monitorQues = [
@@ -147,7 +140,7 @@ export class Generator {
147
140
  },
148
141
  {
149
142
  type: 'input',
150
- name: 'project',
143
+ name: 'id',
151
144
  message: 'Choose project id to logically group monitors',
152
145
  initial: basename(this.projectDir),
153
146
  },
@@ -168,14 +161,6 @@ export class Generator {
168
161
  async files(answers: PromptOptions) {
169
162
  const fileMap = new Map<string, string>();
170
163
 
171
- // Setup project.json
172
- const projectJSON = {
173
- url: answers.url,
174
- space: answers.space,
175
- project: answers.project,
176
- };
177
- fileMap.set(SETTINGS_PATH, JSON.stringify(projectJSON, null, 2) + '\n');
178
-
179
164
  // Setup Synthetics config file
180
165
  fileMap.set(
181
166
  CONFIG_PATH,
@@ -261,7 +246,7 @@ export class Generator {
261
246
  pkgJSON.scripts.test = 'npx @elastic/synthetics journeys';
262
247
 
263
248
  // Add push command
264
- pkgJSON.scripts.push = `npx @elastic/synthetics push --auth $SYNTHETICS_API_KEY`;
249
+ pkgJSON.scripts.push = 'npx @elastic/synthetics push';
265
250
 
266
251
  await this.createFile(
267
252
  filename,
@@ -52,6 +52,9 @@ export function replaceTemplates(input: string, values: Record<string, any>) {
52
52
  if (typeof finalValue == 'number') {
53
53
  return Number(finalValue);
54
54
  }
55
+ if (typeof finalValue == 'string') {
56
+ return `'${finalValue}'`;
57
+ }
55
58
  return finalValue;
56
59
  });
57
60
  }
package/src/helpers.ts CHANGED
@@ -23,7 +23,7 @@
23
23
  *
24
24
  */
25
25
 
26
- import { red, green, yellow, cyan, bold } from 'kleur/colors';
26
+ import { red, green, yellow, cyan, bold, grey } from 'kleur/colors';
27
27
  import os from 'os';
28
28
  import { resolve, join, dirname } from 'path';
29
29
  import fs from 'fs';
@@ -347,6 +347,10 @@ export function progress(message: string) {
347
347
  write(cyan(bold(`${symbols.progress} ${message}`)));
348
348
  }
349
349
 
350
+ export function apiProgress(message: string) {
351
+ write(grey(`> ${message}`));
352
+ }
353
+
350
354
  export function error(message: string) {
351
355
  write(red(message));
352
356
  }
@@ -24,12 +24,15 @@
24
24
  */
25
25
 
26
26
  import path from 'path';
27
- import { unlink, readFile } from 'fs/promises';
27
+ import { stat, unlink, readFile } from 'fs/promises';
28
28
  import { createWriteStream } from 'fs';
29
29
  import * as esbuild from 'esbuild';
30
+ import NodeResolve from '@esbuild-plugins/node-resolve';
30
31
  import archiver from 'archiver';
31
32
  import { commonOptions, MultiAssetPlugin, PluginData } from './plugin';
32
33
 
34
+ const SIZE_LIMIT_KB = 800;
35
+
33
36
  function relativeToCwd(entry: string) {
34
37
  return path.relative(process.cwd(), entry);
35
38
  }
@@ -49,7 +52,12 @@ export class Bundler {
49
52
  entryPoints: {
50
53
  [absPath]: absPath,
51
54
  },
52
- plugins: [MultiAssetPlugin(addToMap)],
55
+ plugins: [
56
+ MultiAssetPlugin(addToMap),
57
+ NodeResolve({
58
+ extensions: ['.ts', '.js'],
59
+ }),
60
+ ],
53
61
  },
54
62
  };
55
63
  const result = await esbuild.build(options);
@@ -85,6 +93,7 @@ export class Bundler {
85
93
  await this.prepare(entry);
86
94
  await this.zip(output);
87
95
  const data = await this.encode(output);
96
+ await this.checkSize(output);
88
97
  await this.cleanup(output);
89
98
  return data;
90
99
  }
@@ -93,6 +102,16 @@ export class Bundler {
93
102
  return await readFile(outputPath, 'base64');
94
103
  }
95
104
 
105
+ async checkSize(outputPath: string) {
106
+ const { size } = await stat(outputPath);
107
+ const sizeKb = size / 1024;
108
+ if (sizeKb > SIZE_LIMIT_KB) {
109
+ throw new Error(
110
+ `You have monitors whose size exceeds the ${SIZE_LIMIT_KB}KB limit.`
111
+ );
112
+ }
113
+ }
114
+
96
115
  async cleanup(outputPath: string) {
97
116
  this.moduleMap = new Map<string, string>();
98
117
  await unlink(outputPath);
package/src/push/index.ts CHANGED
@@ -23,8 +23,6 @@
23
23
  *
24
24
  */
25
25
 
26
- import { join } from 'path';
27
- import { existsSync } from 'fs';
28
26
  import { readFile, writeFile } from 'fs/promises';
29
27
  import { prompt } from 'enquirer';
30
28
  import { bold, yellow } from 'kleur/colors';
@@ -35,26 +33,25 @@ import {
35
33
  formatNotFoundError,
36
34
  formatStaleMonitors,
37
35
  } from './request';
38
- import { buildMonitorSchema, createMonitors } from './monitor';
39
- import { ProjectSettings } from '../generator';
36
+ import { buildMonitorSchema, createMonitors, MonitorSchema } from './monitor';
40
37
  import { Monitor } from '../dsl/monitor';
41
38
  import {
42
39
  progress,
40
+ apiProgress,
43
41
  write,
44
42
  error,
45
- SYNTHETICS_PATH,
46
43
  aborted,
47
44
  indent,
48
45
  safeNDJSONParse,
49
46
  done,
50
47
  } from '../helpers';
51
- import type { PushOptions } from '../common_types';
48
+ import type { PushOptions, ProjectSettings } from '../common_types';
49
+ import { findSyntheticsConfig, readConfig } from '../config';
52
50
 
53
51
  export async function push(monitors: Monitor[], options: PushOptions) {
54
52
  if (monitors.length === 0) {
55
53
  throw 'No Monitors found';
56
54
  }
57
-
58
55
  const duplicates = trackDuplicates(monitors);
59
56
  if (duplicates.size > 0) {
60
57
  throw error(formatDuplicateError(duplicates));
@@ -62,9 +59,32 @@ export async function push(monitors: Monitor[], options: PushOptions) {
62
59
 
63
60
  progress(`preparing all monitors`);
64
61
  const schemas = await buildMonitorSchema(monitors);
62
+
63
+ progress(`creating all monitors`);
64
+ for (const schema of schemas) {
65
+ await pushMonitors({ schemas: [schema], keepStale: true, options });
66
+ }
67
+
68
+ progress(`deleting all stale monitors`);
69
+ await pushMonitors({ schemas, keepStale: false, options });
70
+ done('Pushed');
71
+ }
72
+
73
+ export async function pushMonitors({
74
+ schemas,
75
+ keepStale,
76
+ options,
77
+ }: {
78
+ schemas: MonitorSchema[];
79
+ keepStale: boolean;
80
+ options: PushOptions;
81
+ }) {
65
82
  try {
66
- progress(`creating all monitors`);
67
- const { body, statusCode } = await createMonitors(schemas, options);
83
+ const { body, statusCode } = await createMonitors(
84
+ schemas,
85
+ options,
86
+ keepStale
87
+ );
68
88
  if (statusCode === 404) {
69
89
  throw formatNotFoundError(await body.text());
70
90
  }
@@ -80,7 +100,9 @@ export async function push(monitors: Monitor[], options: PushOptions) {
80
100
  const chunks = safeNDJSONParse(data);
81
101
  for (const chunk of chunks) {
82
102
  if (typeof chunk === 'string') {
83
- progress(chunk);
103
+ // TODO: add progress back for all states once we get the fix
104
+ // on kibana side
105
+ keepStale && apiProgress(chunk);
84
106
  continue;
85
107
  }
86
108
  const { failedMonitors, failedStaleMonitors } = chunk;
@@ -92,7 +114,6 @@ export async function push(monitors: Monitor[], options: PushOptions) {
92
114
  }
93
115
  }
94
116
  }
95
- done('Pushed');
96
117
  } catch (e) {
97
118
  error(e);
98
119
  }
@@ -124,34 +145,39 @@ export function formatDuplicateError(monitors: Set<Monitor>) {
124
145
  return outer;
125
146
  }
126
147
 
127
- const PROJECT_SETTINGS_PATH = join(SYNTHETICS_PATH, 'project.json');
128
148
  const INSTALLATION_HELP = `Run 'npx @elastic/synthetics init' to create project with default settings.`;
129
149
 
130
150
  export async function loadSettings() {
131
- if (!existsSync(PROJECT_SETTINGS_PATH)) {
132
- throw error(`Aborted. Synthetics project not set up.
151
+ try {
152
+ const config = await readConfig('asd');
153
+ // Missing config file, fake throw to capture as missing file
154
+ if (Object.keys(config).length === 0) {
155
+ throw '';
156
+ }
157
+ return config.project || ({} as ProjectSettings);
158
+ } catch (e) {
159
+ throw error(`Aborted (missing synthetics config file), Project not set up corrrectly.
133
160
 
134
161
  ${INSTALLATION_HELP}`);
135
162
  }
136
-
137
- const contents = await readFile(PROJECT_SETTINGS_PATH, 'utf-8');
138
- return JSON.parse(contents) as ProjectSettings;
139
163
  }
140
164
 
141
165
  export function validateSettings(opts: PushOptions) {
142
166
  const INVALID = 'Aborted. Invalid synthetics project settings.';
143
167
 
144
168
  let reason = '';
145
- if (!opts.project) {
146
- reason = 'Set project id via CLI as `--project <id>`';
169
+ if (!opts.id) {
170
+ reason = `Set project id via
171
+ - CLI '--id <id>'
172
+ - Config file 'project.id' field`;
147
173
  } else if (!opts.locations && !opts.privateLocations) {
148
174
  reason = `Set default location for all monitors via
149
- - CLI as '--locations <values...> or --privateLocations <values...>'
150
- - Synthetics config file 'monitors.locations' | 'monitors.privateLocations' field`;
175
+ - CLI '--locations <values...> or --privateLocations <values...>'
176
+ - Config file 'monitors.locations' | 'monitors.privateLocations' field`;
151
177
  } else if (!opts.schedule) {
152
178
  reason = `Set default schedule in minutes for all monitors via
153
- - CLI as '--schedule <mins>'
154
- - Synthetics config file 'monitors.schedule' field`;
179
+ - CLI '--schedule <mins>'
180
+ - Config file 'monitors.schedule' field`;
155
181
  }
156
182
 
157
183
  if (!reason) return;
@@ -163,24 +189,27 @@ ${reason}
163
189
  ${INSTALLATION_HELP}`);
164
190
  }
165
191
 
166
- async function overrideSettings(project: string) {
167
- const settings = JSON.parse(await readFile(PROJECT_SETTINGS_PATH, 'utf-8'));
168
- settings.project = project;
169
-
170
- await writeFile(
171
- PROJECT_SETTINGS_PATH,
172
- JSON.stringify(settings, null, 2),
173
- 'utf-8'
192
+ async function overrideSettings(oldValue: string, newValue: string) {
193
+ const cwd = process.cwd();
194
+ const configPath = await findSyntheticsConfig(cwd, cwd);
195
+ if (!configPath) {
196
+ throw aborted(`Unable to find synthetics config file: ${configPath}`);
197
+ }
198
+ const config = await readFile(configPath, 'utf-8');
199
+ const updatedConfig = config.replace(
200
+ `id: '${oldValue}'`,
201
+ `id: '${newValue}'`
174
202
  );
203
+ await writeFile(configPath, updatedConfig, 'utf-8');
175
204
  }
176
205
 
177
206
  export async function catchIncorrectSettings(
178
207
  settings: ProjectSettings,
179
208
  options: PushOptions
180
209
  ) {
181
- let override = !settings.project;
182
- if (settings.project && settings.project !== options.project) {
183
- if (typeof process.env.TEST_OVERRIDE != null) {
210
+ let override = !settings.id;
211
+ if (settings.id && settings.id !== options.id) {
212
+ if (process.env.TEST_OVERRIDE != null) {
184
213
  override = Boolean(process.env.TEST_OVERRIDE);
185
214
  } else {
186
215
  // Add an extra line to make it easier to read the prompt
@@ -188,7 +217,7 @@ export async function catchIncorrectSettings(
188
217
  ({ override } = await prompt<{ override: boolean }>({
189
218
  type: 'confirm',
190
219
  name: 'override',
191
- message: `Monitors were pushed under the '${settings.project}' project. Are you sure you want to push them under the new '${options.project}' (note that this will duplicate the monitors, the old ones being orphaned)`,
220
+ message: `Monitors were pushed under the '${settings.id}' project. Are you sure you want to push them under the new '${options.id}' (note that this will duplicate the monitors, the old ones being orphaned)`,
192
221
  initial: false,
193
222
  }));
194
223
  }
@@ -197,6 +226,6 @@ export async function catchIncorrectSettings(
197
226
  }
198
227
  }
199
228
  if (override) {
200
- await overrideSettings(options.project);
229
+ await overrideSettings(settings.id, options.id);
201
230
  }
202
231
  }
@@ -38,7 +38,7 @@ export type MonitorSchema = Omit<MonitorConfig, 'locations'> & {
38
38
  filter: Monitor['filter'];
39
39
  };
40
40
 
41
- type APISchema = {
41
+ export type APISchema = {
42
42
  project: string;
43
43
  keep_stale: boolean;
44
44
  monitors: MonitorSchema[];
@@ -77,11 +77,12 @@ export async function buildMonitorSchema(monitors: Monitor[]) {
77
77
 
78
78
  export async function createMonitors(
79
79
  monitors: MonitorSchema[],
80
- options: PushOptions
80
+ options: PushOptions,
81
+ keepStale: boolean
81
82
  ) {
82
83
  const schema: APISchema = {
83
- project: options.project,
84
- keep_stale: false,
84
+ project: options.id,
85
+ keep_stale: keepStale,
85
86
  monitors,
86
87
  };
87
88
 
@@ -23,14 +23,17 @@
23
23
  *
24
24
  */
25
25
 
26
- import path from 'path';
26
+ import { isAbsolute, dirname, extname, join } from 'path';
27
27
  import fs from 'fs/promises';
28
28
  import * as esbuild from 'esbuild';
29
29
 
30
+ const SOURCE_DIR = join(__dirname, '..', '..');
31
+ const SOURCE_NODE_MODULES = join(SOURCE_DIR, 'node_modules');
32
+
30
33
  export function commonOptions(): esbuild.BuildOptions {
31
34
  return {
32
35
  bundle: true,
33
- external: ['node_modules', '@elastic/synthetics'],
36
+ external: ['@elastic/synthetics'],
34
37
  minify: false,
35
38
  platform: 'node',
36
39
  logLevel: 'silent',
@@ -55,27 +58,49 @@ export function MultiAssetPlugin(callback: PluginCallback): esbuild.Plugin {
55
58
  // Note that we use `isAbsolute` to handle UNC/windows style paths like C:\path\to\thing
56
59
  // This is not necessary for relative directories since `.\file` is not supported as an import
57
60
  // nor is `~/path/to/file`.
58
- if (path.isAbsolute(str) || str.startsWith('./') || str.startsWith('../')) {
61
+ if (isAbsolute(str) || str.startsWith('./') || str.startsWith('../')) {
59
62
  return true;
60
63
  }
61
64
  return false;
62
65
  };
63
66
 
67
+ // If we're importing the @elastic/synthetics package
68
+ // directly from source instead of using the fully
69
+ // qualified name, we must skip it too. That's just
70
+ // so it doesn't get bundled on tests or when we locally
71
+ // refer to the package itself.
72
+ const isLocalSynthetics = (entryPath: string) => {
73
+ return entryPath.startsWith(SOURCE_DIR);
74
+ };
75
+
76
+ // When importing the local synthetics module directly
77
+ // it may import its own local dependencies, so we must
78
+ // make sure those will be resolved using Node's resolution
79
+ // algorithm, as they're still "node_modules" that we must bundle
80
+ const isLocalSyntheticsModule = (str: string) => {
81
+ return str.startsWith(SOURCE_NODE_MODULES);
82
+ };
83
+
64
84
  return {
65
85
  name: 'esbuild-multiasset-plugin',
66
86
  setup(build) {
67
87
  build.onResolve({ filter: /.*?/ }, async args => {
68
88
  // External and other packages need be marked external to
69
89
  // be removed from the bundle
70
- if (
71
- build.initialOptions.external?.includes(args.path) ||
72
- !isBare(args.path)
73
- ) {
90
+ if (build.initialOptions.external?.includes(args.path)) {
74
91
  return {
75
92
  external: true,
76
93
  };
77
94
  }
78
95
 
96
+ if (
97
+ !isBare(args.path) ||
98
+ args.importer.includes('/node_modules/') ||
99
+ isLocalSyntheticsModule(args.importer)
100
+ ) {
101
+ return;
102
+ }
103
+
79
104
  if (args.kind === 'entry-point') {
80
105
  return {
81
106
  path: args.path,
@@ -86,8 +111,12 @@ export function MultiAssetPlugin(callback: PluginCallback): esbuild.Plugin {
86
111
  // If the modules are resolved locally, then
87
112
  // use the imported path to get full path
88
113
  const entryPath =
89
- path.join(path.dirname(args.importer), args.path) +
90
- path.extname(args.importer);
114
+ join(dirname(args.importer), args.path) + extname(args.importer);
115
+
116
+ if (isLocalSynthetics(entryPath)) {
117
+ return { external: true };
118
+ }
119
+
91
120
  // Spin off another build to copy over the imported modules without bundling
92
121
  const result = await esbuild.build({
93
122
  ...commonOptions(),
@@ -47,6 +47,7 @@ export async function sendRequest(options: APIRequestOptions) {
47
47
  'user-agent': `Elastic/Synthetics ${version}`,
48
48
  'kbn-xsrf': 'true',
49
49
  },
50
+ headersTimeout: 60 * 1000
50
51
  });
51
52
  }
52
53
 
@@ -16,6 +16,14 @@ export default env => {
16
16
  locations: ['{{locations}}'],
17
17
  privateLocations: ['{{privateLocations}}'],
18
18
  },
19
+ /**
20
+ * Project monitors settings
21
+ */
22
+ project: {
23
+ id: '{{id}}',
24
+ url: '{{url}}',
25
+ space: '{{space}}',
26
+ },
19
27
  };
20
28
  if (env !== 'development') {
21
29
  /**