Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { z } from '@kbn/zod';
import type { RuleResponse } from '../../model/rule_schema/rule_schemas.gen';
import type { PartialRuleDiff } from '../model';
import type { PartialThreeWayRuleDiff } from '../model';

export type GetPrebuiltRuleBaseVersionRequest = z.infer<typeof GetPrebuiltRuleBaseVersionRequest>;
export const GetPrebuiltRuleBaseVersionRequest = z.object({
Expand All @@ -22,5 +22,5 @@ export interface GetPrebuiltRuleBaseVersionResponseBody {
current_version: RuleResponse;

/** The resulting diff between the base and current versions of the rule */
diff: PartialRuleDiff;
diff: PartialThreeWayRuleDiff;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export * from './urls';
export * from './model/aggregated_prebuilt_rules_error';
export * from './model/diff/diffable_rule/diffable_field_types';
export * from './model/diff/diffable_rule/diffable_rule';
export type * from './model/diff/rule_diff/fields_diff';
export type * from './model/diff/rule_diff/rule_diff';
export type * from './model/diff/three_way_diff/three_way_fields_diff';
export type * from './model/diff/three_way_diff/three_way_rule_diff';
export * from './model/diff/three_way_diff/three_way_diff_outcome';
export * from './model/diff/three_way_diff/three_way_diff';
export * from './model/diff/three_way_diff/three_way_diff_conflict';
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ export const determineDiffOutcome = <TValue>(
currentVersion: TValue,
targetVersion: TValue
): ThreeWayDiffOutcome => {
const baseEqlCurrent = isEqual(baseVersion, currentVersion);
const baseEqlTarget = isEqual(baseVersion, targetVersion);
const currentEqlTarget = isEqual(currentVersion, targetVersion);
const baseEqualsCurrent = isEqual(baseVersion, currentVersion);
const baseEqualsTarget = isEqual(baseVersion, targetVersion);
const currentEqualsTarget = isEqual(currentVersion, targetVersion);

return getThreeWayDiffOutcome({
baseEqlCurrent,
baseEqlTarget,
currentEqlTarget,
baseEqualsCurrent,
baseEqualsTarget,
currentEqualsTarget,
hasBaseVersion: baseVersion !== MissingVersion,
});
};
Expand All @@ -65,14 +65,13 @@ export const determineOrderAgnosticDiffOutcome = <TValue>(
const baseSet = baseVersion === MissingVersion ? MissingVersion : new Set<TValue>(baseVersion);
const currentSet = new Set<TValue>(currentVersion);
const targetSet = new Set<TValue>(targetVersion);
const baseEqlCurrent = isEqual(baseSet, currentSet);
const baseEqlTarget = isEqual(baseSet, targetSet);
const currentEqlTarget = isEqual(currentSet, targetSet);

const baseEqualsCurrent = isEqual(baseSet, currentSet);
const baseEqualsTarget = isEqual(baseSet, targetSet);
const currentEqualsTarget = isEqual(currentSet, targetSet);
return getThreeWayDiffOutcome({
baseEqlCurrent,
baseEqlTarget,
currentEqlTarget,
baseEqualsCurrent,
baseEqualsTarget,
currentEqualsTarget,
hasBaseVersion: baseVersion !== MissingVersion,
});
};
Expand Down Expand Up @@ -105,16 +104,16 @@ export const determineDiffOutcomeForDataSource = (
};

interface DetermineDiffOutcomeProps {
baseEqlCurrent: boolean;
baseEqlTarget: boolean;
currentEqlTarget: boolean;
baseEqualsCurrent: boolean;
baseEqualsTarget: boolean;
currentEqualsTarget: boolean;
hasBaseVersion: boolean;
}

const getThreeWayDiffOutcome = ({
baseEqlCurrent,
baseEqlTarget,
currentEqlTarget,
baseEqualsCurrent,
baseEqualsTarget,
currentEqualsTarget,
hasBaseVersion,
}: DetermineDiffOutcomeProps): ThreeWayDiffOutcome => {
if (!hasBaseVersion) {
Expand All @@ -123,22 +122,22 @@ const getThreeWayDiffOutcome = ({
* version comparison is not possible. We assume that the rule is
* customized and the value can be updated if there's an update.
*/
return currentEqlTarget
return currentEqualsTarget
? ThreeWayDiffOutcome.MissingBaseNoUpdate
: ThreeWayDiffOutcome.MissingBaseCanUpdate;
}

if (baseEqlCurrent) {
return currentEqlTarget
if (baseEqualsCurrent) {
return currentEqualsTarget
? ThreeWayDiffOutcome.StockValueNoUpdate
: ThreeWayDiffOutcome.StockValueCanUpdate;
}

if (baseEqlTarget) {
if (baseEqualsTarget) {
return ThreeWayDiffOutcome.CustomizedValueNoUpdate;
}

return currentEqlTarget
return currentEqualsTarget
? ThreeWayDiffOutcome.CustomizedValueSameUpdate
: ThreeWayDiffOutcome.CustomizedValueCanUpdate;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
* 2.0.
*/

import type { ThreeWayDiff, ThreeWayDiffAlgorithm } from '../three_way_diff/three_way_diff';
import type { ThreeWayDiff, ThreeWayDiffAlgorithm } from './three_way_diff';

export type FieldsDiff<TObject> = Required<{
export type ThreeWayFieldsDiff<TObject> = Required<{
[Field in keyof TObject]: ThreeWayDiff<TObject[Field]>;
}>;

export type FieldsDiffAlgorithmsFor<TObject> = Required<{
export type ThreeWayFieldsDiffAlgorithmsFor<TObject> = Required<{
[Field in keyof TObject]: ThreeWayDiffAlgorithm<TObject[Field]>;
}>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type {
DiffableAllFields,
DiffableCommonFields,
DiffableCustomQueryFields,
DiffableEqlFields,
DiffableEsqlFields,
DiffableMachineLearningFields,
DiffableNewTermsFields,
DiffableSavedQueryFields,
DiffableThreatMatchFields,
DiffableThresholdFields,
} from '../diffable_rule/diffable_rule';

import type { ThreeWayFieldsDiff } from './three_way_fields_diff';

export type AllThreeWayFieldsDiff = ThreeWayFieldsDiff<DiffableAllFields>;
export type CommonThreeWayFieldsDiff = ThreeWayFieldsDiff<DiffableCommonFields>;
export type CustomQueryThreeWayFieldsDiff = ThreeWayFieldsDiff<DiffableCustomQueryFields>;
export type SavedQueryThreeWayFieldsDiff = ThreeWayFieldsDiff<DiffableSavedQueryFields>;
export type EqlThreeWayFieldsDiff = ThreeWayFieldsDiff<DiffableEqlFields>;
export type EsqlThreeWayFieldsDiff = ThreeWayFieldsDiff<DiffableEsqlFields>;
export type ThreatMatchThreeWayFieldsDiff = ThreeWayFieldsDiff<DiffableThreatMatchFields>;
export type ThresholdThreeWayFieldsDiff = ThreeWayFieldsDiff<DiffableThresholdFields>;
export type MachineLearningThreeWayFieldsDiff = ThreeWayFieldsDiff<DiffableMachineLearningFields>;
export type NewTermsThreeWayFieldsDiff = ThreeWayFieldsDiff<DiffableNewTermsFields>;

/**
* It's an object which keys are the same as keys of DiffableRule, but values are
* three-way diffs calculated for their values.
*
* @example
* {
* name: ThreeWayDiff<RuleName>;
* tags: ThreeWayDiff<RuleTagArray>;
* // etc
* }
*/
export type ThreeWayRuleFieldsDiff = CommonThreeWayFieldsDiff &
(
| CustomQueryThreeWayFieldsDiff
| SavedQueryThreeWayFieldsDiff
| EqlThreeWayFieldsDiff
| EsqlThreeWayFieldsDiff
| ThreatMatchThreeWayFieldsDiff
| ThresholdThreeWayFieldsDiff
| MachineLearningThreeWayFieldsDiff
| NewTermsThreeWayFieldsDiff
);

interface ThreeWayBaseRuleDiff {
num_fields_with_updates: number;
num_fields_with_conflicts: number;
num_fields_with_non_solvable_conflicts: number;
}
/**
* Full rule diff contains diffs for all the top-level rule fields.
* Even if there's no change at all to a given field, its diff will be included in this object.
* This diff can be useful for internal server-side calculations or debugging.
* Note that this is a pretty large object so returning it from the API might be undesirable.
*/
export interface FullThreeWayRuleDiff extends ThreeWayBaseRuleDiff {
fields: ThreeWayRuleFieldsDiff;
}

/**
* Partial rule diff contains diffs only for those rule fields that have some changes to them.
* This diff can be useful for returning info from REST API endpoints because its size is tolerable.
*/
export interface PartialThreeWayRuleDiff extends ThreeWayBaseRuleDiff {
fields: Partial<ThreeWayRuleFieldsDiff>;
}

export type RuleFieldsDiffWithDataSource =
| CustomQueryThreeWayFieldsDiff
| SavedQueryThreeWayFieldsDiff
| EqlThreeWayFieldsDiff
| ThreatMatchThreeWayFieldsDiff
| ThresholdThreeWayFieldsDiff
| NewTermsThreeWayFieldsDiff;

export type RuleFieldsDiffWithKqlQuery =
| CustomQueryThreeWayFieldsDiff
| SavedQueryThreeWayFieldsDiff
| ThreatMatchThreeWayFieldsDiff
| ThresholdThreeWayFieldsDiff
| NewTermsThreeWayFieldsDiff;

export type RuleFieldsDiffWithEqlQuery = EqlThreeWayFieldsDiff;

export type RuleFieldsDiffWithEsqlQuery = EsqlThreeWayFieldsDiff;

export type RuleFieldsDiffWithThreatQuery = ThreatMatchThreeWayFieldsDiff;

export type RuleFieldsDiffWithThreshold = ThresholdThreeWayFieldsDiff;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

/**
* Used for the structures that contain the two-way diff algorithms
*
* These types will throw an error when a field is missing from the comparator groups,
* alerting us to a field that won't be compared during the two-way diff calculation.
*/
export type TwoWayFieldsDiffAlgorithmsFor<TObject> = Required<{
[Field in keyof TObject]: TwoWayDiffAlgorithm<TObject[Field]>;
}>;

/**
* Type for the two way diff algorithm comparison itself
*
* All of these algorithms take in two field values and return if the values are equal
* to one another.
*/
export type TwoWayDiffAlgorithm<TValue> = (a_value: TValue, b_value: TValue) => boolean;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

/**
* The entire two-way fields diff return object
*
* Contains every field compared by the two-way diff algorithms and their values.
*/
export type TwoWayFieldsDiff<TObject> = Required<{
[Field in keyof TObject]: TwoWayDiff;
}>;

/**
* The result of a two-way field diff comparison
*
* We use this to determine whether the two fields are equal to one another
* and easily filter out fields that are different. It also contains the field
* values compared for reference.
*/
export interface TwoWayDiff {
is_equal: boolean;
value_a: unknown;
value_b: unknown;
}
Loading