@elastic/synthetics 1.0.0-beta.37 → 1.0.0-beta.39

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 (39) hide show
  1. package/dist/core/runner.d.ts.map +1 -1
  2. package/dist/core/runner.js +1 -0
  3. package/dist/core/runner.js.map +1 -1
  4. package/dist/dsl/monitor.d.ts +3 -1
  5. package/dist/dsl/monitor.d.ts.map +1 -1
  6. package/dist/dsl/monitor.js +17 -1
  7. package/dist/dsl/monitor.js.map +1 -1
  8. package/dist/generator/index.d.ts.map +1 -1
  9. package/dist/generator/index.js +10 -3
  10. package/dist/generator/index.js.map +1 -1
  11. package/dist/generator/utils.d.ts.map +1 -1
  12. package/dist/generator/utils.js +1 -0
  13. package/dist/generator/utils.js.map +1 -1
  14. package/dist/helpers.d.ts +3 -1
  15. package/dist/helpers.d.ts.map +1 -1
  16. package/dist/helpers.js +16 -4
  17. package/dist/helpers.js.map +1 -1
  18. package/dist/push/index.d.ts.map +1 -1
  19. package/dist/push/index.js +28 -22
  20. package/dist/push/index.js.map +1 -1
  21. package/dist/push/monitor.d.ts +2 -1
  22. package/dist/push/monitor.d.ts.map +1 -1
  23. package/dist/push/monitor.js +29 -6
  24. package/dist/push/monitor.js.map +1 -1
  25. package/dist/push/plugin.d.ts.map +1 -1
  26. package/dist/push/plugin.js +20 -3
  27. package/dist/push/plugin.js.map +1 -1
  28. package/dist/tsconfig.tsbuildinfo +1 -1
  29. package/package.json +9 -9
  30. package/src/core/runner.ts +1 -0
  31. package/src/dsl/monitor.ts +22 -1
  32. package/src/generator/index.ts +15 -6
  33. package/src/generator/utils.ts +1 -0
  34. package/src/helpers.ts +15 -3
  35. package/src/push/index.ts +32 -24
  36. package/src/push/monitor.ts +29 -8
  37. package/src/push/plugin.ts +19 -3
  38. package/templates/.github/workflows/run-synthetics.yml +9 -8
  39. package/templates/lightweight/heartbeat.yml +7 -0
package/src/push/index.ts CHANGED
@@ -25,7 +25,7 @@
25
25
 
26
26
  import { readFile, writeFile } from 'fs/promises';
27
27
  import { prompt } from 'enquirer';
28
- import { bold } from 'kleur/colors';
28
+ import { bold, grey } from 'kleur/colors';
29
29
  import {
30
30
  ok,
31
31
  formatAPIError,
@@ -34,7 +34,7 @@ import {
34
34
  formatStaleMonitors,
35
35
  } from './request';
36
36
  import { buildMonitorSchema, createMonitors, MonitorSchema } from './monitor';
37
- import { Monitor } from '../dsl/monitor';
37
+ import { ALLOWED_SCHEDULES, Monitor } from '../dsl/monitor';
38
38
  import {
39
39
  progress,
40
40
  apiProgress,
@@ -44,6 +44,8 @@ import {
44
44
  indent,
45
45
  safeNDJSONParse,
46
46
  done,
47
+ getMonitorManagementURL,
48
+ getArrayChunks,
47
49
  } from '../helpers';
48
50
  import type { PushOptions, ProjectSettings } from '../common_types';
49
51
  import { findSyntheticsConfig, readConfig } from '../config';
@@ -60,8 +62,9 @@ export async function push(monitors: Monitor[], options: PushOptions) {
60
62
  schemas = await buildMonitorSchema(monitors);
61
63
 
62
64
  progress(`creating all monitors`);
63
- for (const schema of schemas) {
64
- await pushMonitors({ schemas: [schema], keepStale: true, options });
65
+ const chunks = getArrayChunks(schemas, 10);
66
+ for (const chunk of chunks) {
67
+ await pushMonitors({ schemas: chunk, keepStale: true, options });
65
68
  }
66
69
  } else {
67
70
  write('');
@@ -85,7 +88,7 @@ export async function push(monitors: Monitor[], options: PushOptions) {
85
88
  progress(`deleting all stale monitors`);
86
89
  await pushMonitors({ schemas, keepStale: false, options });
87
90
 
88
- done('Pushed');
91
+ done(`Pushed: ${grey(getMonitorManagementURL(options.url))}`);
89
92
  }
90
93
 
91
94
  export async function pushMonitors({
@@ -109,26 +112,27 @@ export async function pushMonitors({
109
112
  const { error, message } = await body.json();
110
113
  throw formatAPIError(statusCode, error, message);
111
114
  }
112
- body.setEncoding('utf-8');
115
+ const allchunks = [];
113
116
  for await (const data of body) {
114
- // Its kind of hacky for now where Kibana streams the response by
115
- // writing the data as NDJSON events (data can be interleaved), we
116
- // distinguish the final data by checking if the event was a progress vs complete event
117
- const chunks = safeNDJSONParse(data);
118
- for (const chunk of chunks) {
119
- if (typeof chunk === 'string') {
120
- // TODO: add progress back for all states once we get the fix
121
- // on kibana side
122
- keepStale && apiProgress(chunk);
123
- continue;
124
- }
125
- const { failedMonitors, failedStaleMonitors } = chunk;
126
- if (failedMonitors && failedMonitors.length > 0) {
127
- throw formatFailedMonitors(failedMonitors);
128
- }
129
- if (failedStaleMonitors.length > 0) {
130
- throw formatStaleMonitors(failedStaleMonitors);
131
- }
117
+ allchunks.push(Buffer.from(data));
118
+ }
119
+ const chunks = safeNDJSONParse(Buffer.concat(allchunks).toString('utf-8'));
120
+ // Its kind of hacky for now where Kibana streams the response by
121
+ // writing the data as NDJSON events (data can be interleaved), we
122
+ // distinguish the final data by checking if the event was a progress vs complete event
123
+ for (const chunk of chunks) {
124
+ if (typeof chunk === 'string') {
125
+ // TODO: add progress back for all states once we get the fix
126
+ // on kibana side
127
+ keepStale && apiProgress(chunk);
128
+ continue;
129
+ }
130
+ const { failedMonitors, failedStaleMonitors } = chunk;
131
+ if (failedMonitors && failedMonitors.length > 0) {
132
+ throw formatFailedMonitors(failedMonitors);
133
+ }
134
+ if (failedStaleMonitors.length > 0) {
135
+ throw formatStaleMonitors(failedStaleMonitors);
132
136
  }
133
137
  }
134
138
  }
@@ -192,6 +196,10 @@ export function validateSettings(opts: PushOptions) {
192
196
  reason = `Set default schedule in minutes for all monitors via
193
197
  - CLI '--schedule <mins>'
194
198
  - Config file 'monitors.schedule' field`;
199
+ } else if (opts.schedule && !ALLOWED_SCHEDULES.includes(opts.schedule)) {
200
+ reason = `Set default schedule(${
201
+ opts.schedule
202
+ }) to one of the allowed values - ${ALLOWED_SCHEDULES.join(',')}`;
195
203
  }
196
204
 
197
205
  if (!reason) return;
@@ -37,7 +37,7 @@ import {
37
37
  warn,
38
38
  } from '../helpers';
39
39
  import { LocationsMap } from '../locations/public-locations';
40
- import { Monitor, MonitorConfig } from '../dsl/monitor';
40
+ import { ALLOWED_SCHEDULES, Monitor, MonitorConfig } from '../dsl/monitor';
41
41
  import { PushOptions } from '../common_types';
42
42
 
43
43
  export type MonitorSchema = Omit<MonitorConfig, 'locations'> & {
@@ -95,13 +95,8 @@ export async function createLightweightMonitors(
95
95
  lwFiles.add(abs);
96
96
  }
97
97
  });
98
- // Warn users about schedule that are less than 60 seconds
99
- if (lwFiles.size > 0) {
100
- warn(
101
- 'lightweight monitors schedule < 1 minute resolution are not supported, will get reset to their nearest minute interval.'
102
- );
103
- }
104
98
 
99
+ let warnOnce = false;
105
100
  const monitors: Monitor[] = [];
106
101
  for (const file of lwFiles.values()) {
107
102
  const content = await readFile(file, 'utf-8');
@@ -115,6 +110,13 @@ export async function createLightweightMonitors(
115
110
  if (!monitorSeq) {
116
111
  continue;
117
112
  }
113
+ // Warn users about schedule that are less than 60 seconds
114
+ if (!warnOnce) {
115
+ warn(
116
+ 'If you are using lightweight monitors with less than 1 minute resolution, these will be saved to the nearest supported frequency'
117
+ );
118
+ warnOnce = true;
119
+ }
118
120
 
119
121
  for (const monNode of monitorSeq.items) {
120
122
  // Skip browser monitors and disabled monitors from pushing
@@ -193,7 +195,26 @@ export function parseSchedule(schedule: string) {
193
195
  break;
194
196
  }
195
197
  }
196
- return minutes;
198
+ return nearestSchedule(minutes);
199
+ }
200
+
201
+ // Find the nearest schedule that is supported by the platform
202
+ // from the parsed schedule value
203
+ export function nearestSchedule(schedule: number) {
204
+ let start = 0;
205
+ let end = ALLOWED_SCHEDULES.length - 1;
206
+ while (start <= end) {
207
+ const mid = Math.floor((start + end) / 2);
208
+ const midValue = ALLOWED_SCHEDULES[mid];
209
+ if (midValue === schedule) {
210
+ return midValue;
211
+ } else if (midValue < schedule) {
212
+ start = mid + 1;
213
+ } else {
214
+ end = mid - 1;
215
+ }
216
+ }
217
+ return ALLOWED_SCHEDULES[end];
197
218
  }
198
219
 
199
220
  export async function createMonitors(
@@ -39,6 +39,11 @@ export function commonOptions(): esbuild.BuildOptions {
39
39
  bundle: true,
40
40
  external: ['@elastic/synthetics'],
41
41
  minify: false,
42
+ minifyIdentifiers: false,
43
+ minifySyntax: false,
44
+ minifyWhitespace: false,
45
+ treeShaking: false,
46
+ keepNames: false,
42
47
  platform: 'node',
43
48
  logLevel: 'silent',
44
49
  format: 'esm',
@@ -108,7 +113,7 @@ export function MultiAssetPlugin(callback: PluginCallback): esbuild.Plugin {
108
113
  if (args.kind === 'entry-point') {
109
114
  return {
110
115
  path: args.path,
111
- namespace: 'asset',
116
+ namespace: 'journey',
112
117
  };
113
118
  }
114
119
 
@@ -142,10 +147,21 @@ export function MultiAssetPlugin(callback: PluginCallback): esbuild.Plugin {
142
147
  };
143
148
  });
144
149
 
145
- build.onLoad({ filter: /.*?/, namespace: 'asset' }, async args => {
150
+ build.onLoad({ filter: /.*?/, namespace: 'journey' }, async args => {
146
151
  const contents = await fs.readFile(args.path, 'utf-8');
147
152
  callback({ path: args.path, contents });
148
- return { contents };
153
+
154
+ // Use correct loader for the journey entry path
155
+ let loader: esbuild.Loader = 'default';
156
+ const ext = extname(args.path).slice(1);
157
+ if (ext === 'cjs' || ext === 'mjs') {
158
+ loader = 'js';
159
+ } else if (ext === 'cts' || ext === 'mts') {
160
+ loader = 'ts';
161
+ } else {
162
+ loader = ext as esbuild.Loader;
163
+ }
164
+ return { contents, loader };
149
165
  });
150
166
  },
151
167
  };
@@ -8,19 +8,20 @@ on:
8
8
  - cron: '* 0 * * *'
9
9
  jobs:
10
10
  test:
11
+ defaults:
12
+ run:
13
+ working-directory: ./advanced-examples
11
14
  runs-on: ubuntu-latest
12
15
  steps:
13
- - uses: actions/checkout@v2
14
- - uses: actions/setup-node@v2
16
+ - uses: actions/checkout@v3
17
+ - uses: actions/setup-node@v3
15
18
  with:
16
- node-version: 16
19
+ node-version: 18
17
20
  - run: npm install
18
21
  - run: "SYNTHETICS_JUNIT_FILE='junit-synthetics.xml' npx @elastic/synthetics . --reporter=junit"
19
- continue-on-error: true
20
22
  - name: Publish Unit Test Results
21
- uses: EnricoMi/publish-unit-test-result-action@v1.19
23
+ uses: EnricoMi/publish-unit-test-result-action@v2
22
24
  if: always()
23
25
  with:
24
- files: '**/junit-*.xml'
25
- fail_on: 'test failures'
26
- check_name: Elastic Synthetics Tests
26
+ junit_files: '**/junit-*.xml'
27
+ check_name: Elastic Synthetics Tests
@@ -0,0 +1,7 @@
1
+ - type: http
2
+ name: Todos Lightweight
3
+ id: todos-lightweight
4
+ enabled: true
5
+ urls: "https://elastic.github.io/synthetics-demo/"
6
+ schedule: '@every 3m'
7
+ timeout: 16s