Skip to content

Commit

Permalink
Refactor models (elastic#206930)
Browse files Browse the repository at this point in the history
Refactors models to make it more clear what our data model is internally
and what our API responses are. Also some small changes to make it more
elasticsearch-y:

- isSchema variants now are based on specific type narrowing instead of
from any > type, as the latter only gives runtime safety, but does not
add much in terms of type safety
- validation is now entirely encapsulated in the type, removed
additional checks such as `isCompleteCondition`
- the stored document puts all stream properties top level (currently
only `ingest`, instead of `stream.ingest`)
- `condition` is renamed to `if`, and required everywhere
- `always` and `never` conditions were added
- `grok` and `dissect` processors are now similar to ES, where the
condition is a part of the processor config
- `GET /api/streams/{id}` returns `{ stream: ..., dashboards: ..., ...
}` instead of `{ ingest: ...., dashboards: ..., ... }`
- `PUT /api/streams/{id}` now requires `dashboards`, and `stream` is a
top-level property
- `PUT /api/streams/{id}/_ingest` was added to allow consumers to only
update the stream, and not its assets
- there are some legacy definitions (in `legacy.ts`) to minimize the
amount of changes in the UI, this still needs to happen at some point
but not in this PR

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
dgieselaar and kibanamachine authored Jan 22, 2025
1 parent f4ff699 commit 8d4a70c
Show file tree
Hide file tree
Showing 90 changed files with 1,964 additions and 1,436 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ export function isNonEmptyString(input: string, ctx: z.RefinementCtx): void {
});
}
}

export const NonEmptyString = z.string().min(1).superRefine(isNonEmptyString);
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@
* 2.0.
*/

export * from './src/apis';
export * from './src/models';
export * from './src/helpers';

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@
* 2.0.
*/

export * from './processing';
export * from './type_guards';
export * from './hierarchy';

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,117 +5,41 @@
* 2.0.
*/

import { ZodSchema, custom, output } from '@kbn/zod';
import {
AndCondition,
conditionSchema,
dissectProcessingDefinitionSchema,
DissectProcessingDefinition,
FilterCondition,
filterConditionSchema,
GrokProcessingDefinition,
grokProcessingDefinitionSchema,
IngestReadStreamDefinition,
ingestReadStreamDefinitonSchema,
IngestStreamDefinition,
ingestStreamDefinitonSchema,
OrCondition,
ReadStreamDefinition,
readStreamDefinitonSchema,
StreamDefinition,
streamDefinitionSchema,
WiredReadStreamDefinition,
wiredReadStreamDefinitonSchema,
WiredStreamDefinition,
wiredStreamDefinitonSchema,
} from '../models';
import {
IngestStreamConfigDefinition,
ingestStreamConfigDefinitonSchema,
StreamConfigDefinition,
streamConfigDefinitionSchema,
WiredStreamConfigDefinition,
wiredStreamConfigDefinitonSchema,
} from '../models/stream_config';

export function isSchema<T>(zodSchema: ZodSchema, subject: T) {
try {
zodSchema.parse(subject);
return true;
} catch (e) {
return false;
}
import { ZodSchema, z } from '@kbn/zod';

export function createIsNarrowSchema<TBaseSchema extends z.Schema, TNarrowSchema extends z.Schema>(
base: TBaseSchema,
narrow: TNarrowSchema
) {
return <TValue extends z.input<TBaseSchema>>(
value: TValue
): value is Extract<TValue, z.input<TNarrowSchema>> => {
return isSchema(narrow, value);
};
}

export function createAsSchemaOrThrow<TBaseSchema extends z.Schema, TNarrowSchema extends z.Schema>(
base: TBaseSchema,
narrow: TNarrowSchema
) {
return <TValue extends z.input<TBaseSchema>>(
value: TValue
): Extract<TValue, z.input<TNarrowSchema>> => {
narrow.parse(value);
return value;
};
}

export function isSchema<TSchema extends z.Schema>(
schema: TSchema,
value: unknown
): value is z.input<TSchema> {
return schema.safeParse(value).success;
}

export function assertsSchema<TSchema extends ZodSchema>(
schema: TSchema,
subject: any
): asserts subject is output<TSchema> {
): asserts subject is z.input<TSchema> {
schema.parse(subject);
}

export function isReadStream(subject: any): subject is ReadStreamDefinition {
return isSchema(readStreamDefinitonSchema, subject);
}

export function isWiredReadStream(subject: any): subject is WiredReadStreamDefinition {
return isSchema(wiredReadStreamDefinitonSchema, subject);
}

export function isIngestReadStream(subject: any): subject is IngestReadStreamDefinition {
return isSchema(ingestReadStreamDefinitonSchema, subject);
}

export function isStream(subject: any): subject is StreamDefinition {
return isSchema(streamDefinitionSchema, subject);
}

export function isIngestStream(subject: StreamDefinition): subject is IngestStreamDefinition {
return isSchema(ingestStreamDefinitonSchema, subject);
}

export function isWiredStream(subject: StreamDefinition): subject is WiredStreamDefinition {
return isSchema(wiredStreamDefinitonSchema, subject);
}

const rootStreamSchema = custom<'RootStreamSchema'>((val) => {
return val?.name?.split('.').length === 1;
});

export function isRootStream(subject: any): subject is WiredStreamDefinition {
return (
(isWiredStream(subject) || isWiredReadStream(subject)) && isSchema(rootStreamSchema, subject)
);
}

export function isWiredStreamConfig(subject: any): subject is WiredStreamConfigDefinition {
return isSchema(wiredStreamConfigDefinitonSchema, subject);
}

export function isIngestStreamConfig(subject: any): subject is IngestStreamConfigDefinition {
return isSchema(ingestStreamConfigDefinitonSchema, subject);
}

export function isStreamConfig(subject: any): subject is StreamConfigDefinition {
return isSchema(streamConfigDefinitionSchema, subject);
}

export function isGrokProcessor(subject: any): subject is GrokProcessingDefinition {
return isSchema(grokProcessingDefinitionSchema, subject);
}

export function isDissectProcessor(subject: any): subject is DissectProcessingDefinition {
return isSchema(dissectProcessingDefinitionSchema, subject);
}

export function isFilterCondition(subject: any): subject is FilterCondition {
return isSchema(filterConditionSchema, subject);
}

export function isAndCondition(subject: any): subject is AndCondition {
return isSchema(conditionSchema, subject) && subject.and != null;
}

export function isOrCondition(subject: any): subject is OrCondition {
return isSchema(conditionSchema, subject) && subject.or != null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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 { z } from '@kbn/zod';
import {
ingestStreamUpsertRequestSchema,
type IngestStreamGetResponse,
type IngestStreamUpsertRequest,
} from './ingest';

export const streamUpsertRequestSchema: z.Schema<StreamUpsertRequest> =
ingestStreamUpsertRequestSchema;

export type StreamGetResponse = IngestStreamGetResponse;
export type StreamUpsertRequest = IngestStreamUpsertRequest;
Loading

0 comments on commit 8d4a70c

Please sign in to comment.