@elastic/synthetics 1.6.0 → 1.7.1

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/src/core/index.ts CHANGED
@@ -23,7 +23,13 @@
23
23
  *
24
24
  */
25
25
 
26
- import { Journey, JourneyCallback, JourneyOptions } from '../dsl';
26
+ import {
27
+ Journey,
28
+ JourneyCallback,
29
+ JourneyOptions,
30
+ JourneyWithAnnotations,
31
+ StepWithAnnotations,
32
+ } from '../dsl';
27
33
  import Runner from './runner';
28
34
  import { VoidCallback, HooksCallback, Location } from '../common_types';
29
35
  import { wrapFnWithLocation } from '../helpers';
@@ -41,28 +47,48 @@ if (!global[SYNTHETICS_RUNNER]) {
41
47
 
42
48
  export const runner: Runner = global[SYNTHETICS_RUNNER];
43
49
 
44
- export const journey = wrapFnWithLocation(
45
- (
46
- location: Location,
47
- options: JourneyOptions | string,
48
- callback: JourneyCallback
49
- ) => {
50
- log(`Journey register: ${JSON.stringify(options)}`);
51
- if (typeof options === 'string') {
52
- options = { name: options, id: options };
50
+ const createJourney = (type?: 'skip' | 'only') =>
51
+ wrapFnWithLocation(
52
+ (
53
+ location: Location,
54
+ options: JourneyOptions | string,
55
+ callback: JourneyCallback
56
+ ) => {
57
+ log(`Journey register: ${JSON.stringify(options)}`);
58
+ if (typeof options === 'string') {
59
+ options = { name: options, id: options };
60
+ }
61
+ const j = new Journey(options, callback, location);
62
+
63
+ if (type) {
64
+ j[type] = true;
65
+ }
66
+
67
+ runner.addJourney(j);
68
+ return j;
53
69
  }
54
- const j = new Journey(options, callback, location);
55
- runner.addJourney(j);
56
- return j;
57
- }
58
- );
70
+ );
59
71
 
60
- export const step = wrapFnWithLocation(
61
- (location: Location, name: string, callback: VoidCallback) => {
62
- log(`Step register: ${name}`);
63
- return runner.currentJourney?.addStep(name, callback, location);
64
- }
65
- );
72
+ export const journey = createJourney() as JourneyWithAnnotations;
73
+ journey.skip = createJourney('skip');
74
+ journey.only = createJourney('only');
75
+
76
+ const createStep = (type?: 'skip' | 'soft' | 'only') =>
77
+ wrapFnWithLocation(
78
+ (location: Location, name: string, callback: VoidCallback) => {
79
+ log(`Step register: ${name}`);
80
+ const step = runner.currentJourney?.addStep(name, callback, location);
81
+ if (type) {
82
+ step[type] = true;
83
+ }
84
+ return step;
85
+ }
86
+ );
87
+
88
+ export const step = createStep() as StepWithAnnotations;
89
+ step.skip = createStep('skip');
90
+ step.soft = createStep('soft');
91
+ step.only = createStep('only');
66
92
 
67
93
  export const monitor = {
68
94
  use: wrapFnWithLocation((location: Location, config: MonitorConfig) => {
@@ -256,19 +256,30 @@ export default class Runner {
256
256
  options: RunOptions
257
257
  ) {
258
258
  const results: Array<StepResult> = [];
259
+ const isOnlyExists = journey.steps.filter(s => s.only).length > 0;
259
260
  let skipStep = false;
260
261
  for (const step of journey.steps) {
261
262
  const start = monotonicTimeInSeconds();
262
263
  this.#reporter?.onStepStart?.(journey, step);
263
264
  let data: StepResult = { status: 'succeeded' };
264
- if (skipStep) {
265
+ /**
266
+ * Skip the step
267
+ * - if the step is marked as skip
268
+ * - if the previous step fails and the current step is not marked as soft
269
+ * - if the step is not marked as only and there are steps marked as only
270
+ */
271
+ if (
272
+ step.skip ||
273
+ (skipStep && !step.only) ||
274
+ (isOnlyExists && !step.only)
275
+ ) {
265
276
  data.status = 'skipped';
266
277
  } else {
267
278
  data = await this.runStep(step, context, options);
268
279
  /**
269
280
  * skip next steps if the previous step returns error
270
281
  */
271
- if (data.error) skipStep = true;
282
+ if (data.error && !step.soft) skipStep = true;
272
283
  }
273
284
  this.#reporter?.onStepEnd?.(journey, step, {
274
285
  start,
@@ -366,6 +377,7 @@ export default class Runner {
366
377
  result.error = stepResult.error;
367
378
  }
368
379
  }
380
+ result.steps = stepResults;
369
381
  await this.runAfterHook(journey, hookArgs);
370
382
  } catch (e) {
371
383
  result.status = 'failed';
@@ -410,6 +422,11 @@ export default class Runner {
410
422
  const monitors: Monitor[] = [];
411
423
  for (const journey of this.journeys) {
412
424
  this.#currentJourney = journey;
425
+ if (journey.skip) {
426
+ throw new Error(
427
+ `Journey ${journey.name} is skipped. Please remove the journey.skip annotation and try again.`
428
+ );
429
+ }
413
430
  /**
414
431
  * Execute dummy callback to get all monitor specific
415
432
  * configurations for the current journey
@@ -436,6 +453,14 @@ export default class Runner {
436
453
  }).catch(e => (this.hookError = e));
437
454
 
438
455
  const { dryRun, match, tags } = options;
456
+ /**
457
+ * Skip other journeys when using `.only`
458
+ */
459
+ const onlyJournerys = this.journeys.filter(j => j.only);
460
+ if (onlyJournerys.length > 0) {
461
+ this.journeys = onlyJournerys;
462
+ }
463
+
439
464
  for (const journey of this.journeys) {
440
465
  /**
441
466
  * Used by heartbeat to gather all registered journeys
@@ -444,7 +469,7 @@ export default class Runner {
444
469
  this.#reporter.onJourneyRegister?.(journey);
445
470
  continue;
446
471
  }
447
- if (!journey.isMatch(match, tags)) {
472
+ if (!journey.isMatch(match, tags) || journey.skip) {
448
473
  continue;
449
474
  }
450
475
  const journeyResult: JourneyResult = this.hookError
@@ -81,9 +81,6 @@ export function commonOptions(): CommonOptions {
81
81
  */
82
82
  return {
83
83
  minify: false,
84
- minifyIdentifiers: false,
85
- minifySyntax: false,
86
- minifyWhitespace: false,
87
84
  sourcemap: 'both',
88
85
  sourcesContent: false,
89
86
  platform: 'node',
@@ -61,6 +61,8 @@ export class Journey {
61
61
  steps: Step[] = [];
62
62
  hooks: Hooks = { before: [], after: [] };
63
63
  monitor: Monitor;
64
+ skip = false;
65
+ only = false;
64
66
 
65
67
  constructor(
66
68
  options: JourneyOptions,
@@ -107,3 +109,19 @@ export class Journey {
107
109
  return isMatch(this.tags, this.name, tagsPattern, matchPattern);
108
110
  }
109
111
  }
112
+
113
+ type JourneyType = (
114
+ options: string | JourneyOptions,
115
+ callback: JourneyCallback
116
+ ) => Journey;
117
+
118
+ export type JourneyWithAnnotations = JourneyType & {
119
+ /**
120
+ * Skip this journey and all its steps
121
+ */
122
+ skip: JourneyType;
123
+ /**
124
+ * Run only this journey and skip rest of the journeys
125
+ */
126
+ only: JourneyType;
127
+ };
package/src/dsl/step.ts CHANGED
@@ -30,6 +30,9 @@ export class Step {
30
30
  index: number;
31
31
  callback: VoidCallback;
32
32
  location?: Location;
33
+ skip = false;
34
+ soft = false;
35
+ only = false;
33
36
 
34
37
  constructor(
35
38
  name: string,
@@ -43,3 +46,20 @@ export class Step {
43
46
  this.location = location;
44
47
  }
45
48
  }
49
+
50
+ type StepType = (name: string, callback: VoidCallback) => Step;
51
+
52
+ export type StepWithAnnotations = StepType & {
53
+ /**
54
+ * Skip this step on the journey
55
+ */
56
+ skip: StepType;
57
+ /**
58
+ * Failure of soft step will not skip rest of the steps in the journey
59
+ */
60
+ soft: StepType;
61
+ /**
62
+ * Run only this step and skip rest of the steps in the journey
63
+ */
64
+ only: StepType;
65
+ };
package/src/helpers.ts CHANGED
@@ -312,7 +312,7 @@ export function wrapFnWithLocation<A extends unknown[], R>(
312
312
  };
313
313
  }
314
314
 
315
- // Safely parse ND JSON (Newline delimitted JSON) chunks
315
+ // Safely parse ND JSON (Newline delimited JSON) chunks
316
316
  export function safeNDJSONParse(data: string | string[]) {
317
317
  // data may not be at proper newline boundaries, so we make sure everything is split
318
318
  // on proper newlines
package/src/index.ts CHANGED
@@ -73,7 +73,13 @@ export type {
73
73
  StartEvent,
74
74
  } from './common_types';
75
75
 
76
- export type { Journey, JourneyCallback } from './dsl';
76
+ export type {
77
+ Journey,
78
+ JourneyCallback,
79
+ JourneyWithAnnotations,
80
+ JourneyOptions,
81
+ StepWithAnnotations,
82
+ } from './dsl';
77
83
 
78
84
  export type {
79
85
  Action,
@@ -31,7 +31,8 @@ import archiver from 'archiver';
31
31
  import { commonOptions } from '../core/transform';
32
32
  import { SyntheticsBundlePlugin } from './plugin';
33
33
 
34
- const SIZE_LIMIT_KB = 800;
34
+ // 1500KB Max Gzipped limit for bundled code to be pushed as Kibana project monitors.
35
+ const SIZE_LIMIT_KB = 1500;
35
36
 
36
37
  function relativeToCwd(entry: string) {
37
38
  return path.relative(process.cwd(), entry);
@@ -48,6 +49,7 @@ export class Bundler {
48
49
  entryPoints: [absPath],
49
50
  bundle: true,
50
51
  write: false,
52
+ minifyWhitespace: true,
51
53
  sourcemap: 'inline',
52
54
  external: ['@elastic/synthetics'],
53
55
  plugins: [SyntheticsBundlePlugin()],
@@ -100,7 +102,7 @@ export class Bundler {
100
102
  const sizeKb = size / 1024;
101
103
  if (sizeKb > SIZE_LIMIT_KB) {
102
104
  throw new Error(
103
- `You have monitors whose size exceeds the ${SIZE_LIMIT_KB}KB limit.`
105
+ `Bundled monitor code exceeds the recommended ${SIZE_LIMIT_KB}KB limit. Please check your dependencies and try again.`
104
106
  );
105
107
  }
106
108
  }