diff --git a/apps/webservice/src/app/[workspaceSlug]/_components/filter/VersionConditionRender.tsx b/apps/webservice/src/app/[workspaceSlug]/_components/filter/ColumnConditionRender.tsx similarity index 65% rename from apps/webservice/src/app/[workspaceSlug]/_components/filter/VersionConditionRender.tsx rename to apps/webservice/src/app/[workspaceSlug]/_components/filter/ColumnConditionRender.tsx index a4a109f6f..910c14552 100644 --- a/apps/webservice/src/app/[workspaceSlug]/_components/filter/VersionConditionRender.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/_components/filter/ColumnConditionRender.tsx @@ -1,4 +1,4 @@ -import type { VersionOperatorType } from "@ctrlplane/validators/conditions"; +import type { ColumnOperatorType } from "@ctrlplane/validators/conditions"; import { cn } from "@ctrlplane/ui"; import { Input } from "@ctrlplane/ui/input"; @@ -9,24 +9,24 @@ import { SelectTrigger, SelectValue, } from "@ctrlplane/ui/select"; -import { VersionOperator } from "@ctrlplane/validators/conditions"; +import { ColumnOperator } from "@ctrlplane/validators/conditions"; -type VersionConditionRenderProps = { - operator: VersionOperatorType; +type ColumnConditionRenderProps = { + operator: ColumnOperatorType; value: string; - setOperator: (operator: VersionOperatorType) => void; + setOperator: (operator: ColumnOperatorType) => void; setValue: (value: string) => void; + title: string; className?: string; - title?: string; }; -export const VersionConditionRender: React.FC = ({ +export const ColumnConditionRender: React.FC = ({ operator, value, setOperator, setValue, className, - title = "Version", + title, }) => (
@@ -39,18 +39,18 @@ export const VersionConditionRender: React.FC = ({ - Equals - Like - Regex + Equals + Like + Regex
addCondition({ type: FilterType.Version, - operator: VersionOperator.Equals, + operator: ColumnOperator.Equals, value: "", }) } diff --git a/apps/webservice/src/app/[workspaceSlug]/_components/job-condition/JobConditionBadge.tsx b/apps/webservice/src/app/[workspaceSlug]/_components/job-condition/JobConditionBadge.tsx index e996aaa61..1717e0f40 100644 --- a/apps/webservice/src/app/[workspaceSlug]/_components/job-condition/JobConditionBadge.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/_components/job-condition/JobConditionBadge.tsx @@ -239,7 +239,7 @@ const StringifiedVersionCondition: React.FC<{ {operatorVerbs[condition.operator]} - {condition.value} + {condition.value.replace(/%/g, "")} ); diff --git a/apps/webservice/src/app/[workspaceSlug]/_components/job-condition/VersionConditionRender.tsx b/apps/webservice/src/app/[workspaceSlug]/_components/job-condition/VersionConditionRender.tsx index 4a6a5595a..959b9c837 100644 --- a/apps/webservice/src/app/[workspaceSlug]/_components/job-condition/VersionConditionRender.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/_components/job-condition/VersionConditionRender.tsx @@ -1,20 +1,20 @@ import type { + ColumnOperatorType, VersionCondition, - VersionOperatorType, } from "@ctrlplane/validators/conditions"; import type { JobConditionRenderProps } from "./job-condition-props"; -import { VersionConditionRender } from "../filter/VersionConditionRender"; +import { ColumnConditionRender } from "../filter/ColumnConditionRender"; export const JobReleaseVersionConditionRender: React.FC< JobConditionRenderProps > = ({ condition, onChange, className }) => { - const setOperator = (operator: VersionOperatorType) => + const setOperator = (operator: ColumnOperatorType) => onChange({ ...condition, operator }); const setValue = (value: string) => onChange({ ...condition, value }); return ( - addCondition({ type: ReleaseFilterType.Version, - operator: ReleaseOperator.Equals, + operator: ColumnOperator.Equals, value: "", }) } diff --git a/apps/webservice/src/app/[workspaceSlug]/_components/release-condition/ReleaseConditionBadge.tsx b/apps/webservice/src/app/[workspaceSlug]/_components/release-condition/ReleaseConditionBadge.tsx index 6d2d8667f..61bb8c460 100644 --- a/apps/webservice/src/app/[workspaceSlug]/_components/release-condition/ReleaseConditionBadge.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/_components/release-condition/ReleaseConditionBadge.tsx @@ -175,7 +175,7 @@ const StringifiedVersionCondition: React.FC<{ {operatorVerbs[condition.operator]} - {condition.value} + {condition.value.replace(/%/g, "")} ); diff --git a/apps/webservice/src/app/[workspaceSlug]/_components/release-condition/ReleaseVersionConditionRender.tsx b/apps/webservice/src/app/[workspaceSlug]/_components/release-condition/ReleaseVersionConditionRender.tsx index 3bf0285b2..a454ed1b2 100644 --- a/apps/webservice/src/app/[workspaceSlug]/_components/release-condition/ReleaseVersionConditionRender.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/_components/release-condition/ReleaseVersionConditionRender.tsx @@ -1,26 +1,27 @@ import type { + ColumnOperatorType, VersionCondition, - VersionOperatorType, } from "@ctrlplane/validators/conditions"; import React from "react"; import type { ReleaseConditionRenderProps } from "./release-condition-props"; -import { VersionConditionRender } from "../filter/VersionConditionRender"; +import { ColumnConditionRender } from "../filter/ColumnConditionRender"; export const ReleaseVersionConditionRender: React.FC< ReleaseConditionRenderProps > = ({ condition, onChange, className }) => { - const setOperator = (operator: VersionOperatorType) => + const setOperator = (operator: ColumnOperatorType) => onChange({ ...condition, operator }); const setValue = (value: string) => onChange({ ...condition, value }); return ( - ); }; diff --git a/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/ComparisonConditionRender.tsx b/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/ComparisonConditionRender.tsx index 5d276f3e0..a0b723aaf 100644 --- a/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/ComparisonConditionRender.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/ComparisonConditionRender.tsx @@ -30,6 +30,7 @@ import { SelectTrigger, SelectValue, } from "@ctrlplane/ui/select"; +import { ColumnOperator } from "@ctrlplane/validators/conditions"; import { doesConvertingToComparisonRespectMaxDepth, isComparisonCondition, @@ -174,7 +175,6 @@ export const ComparisonConditionRender: React.FC< key={index} condition={subCond} onChange={(c) => updateCondition(index, c)} - onRemove={() => removeCondition(index)} depth={depth + 1} className={cn(depth === 0 ? "col-span-11" : "col-span-10")} /> @@ -292,6 +292,17 @@ export const ComparisonConditionRender: React.FC< > Name + + addCondition({ + type: TargetFilterType.Identifier, + operator: ColumnOperator.Like, + value: "", + }) + } + > + Identifier + addCondition({ diff --git a/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/IdentifierConditionRender.tsx b/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/IdentifierConditionRender.tsx new file mode 100644 index 000000000..ad2f31bb8 --- /dev/null +++ b/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/IdentifierConditionRender.tsx @@ -0,0 +1,24 @@ +import type { ColumnOperatorType } from "@ctrlplane/validators/conditions"; +import type { IdentifierCondition } from "@ctrlplane/validators/targets"; + +import type { TargetConditionRenderProps } from "./target-condition-props"; +import { ColumnConditionRender } from "../filter/ColumnConditionRender"; + +export const IdentifierConditionRender: React.FC< + TargetConditionRenderProps +> = ({ condition, onChange, className }) => { + const setOperator = (operator: ColumnOperatorType) => + onChange({ ...condition, operator }); + const setValue = (value: string) => onChange({ ...condition, value }); + + return ( + + ); +}; diff --git a/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/TargetConditionBadge.tsx b/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/TargetConditionBadge.tsx index 108c5dc4e..f6a818177 100644 --- a/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/TargetConditionBadge.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/TargetConditionBadge.tsx @@ -1,6 +1,7 @@ import type { MetadataCondition } from "@ctrlplane/validators/conditions"; import type { ComparisonCondition, + IdentifierCondition, KindCondition, NameCondition, ProviderCondition, @@ -18,6 +19,7 @@ import { } from "@ctrlplane/ui/hover-card"; import { isComparisonCondition, + isIdentifierCondition, isKindCondition, isMetadataCondition, isNameCondition, @@ -174,6 +176,18 @@ const StringifiedNameCondition: React.FC<{ ); +const StringifiedIdentifierCondition: React.FC<{ + condition: IdentifierCondition; +}> = ({ condition }) => ( + + Identifier + + {operatorVerbs[condition.operator]} + + {condition.value.replace(/%/g, "")} + +); + const StringifiedProviderCondition: React.FC<{ condition: ProviderCondition; }> = ({ condition }) => { @@ -219,6 +233,9 @@ const StringifiedTargetCondition: React.FC<{ if (isNameCondition(condition)) return ; + if (isIdentifierCondition(condition)) + return ; + if (isProviderCondition(condition)) return ; }; diff --git a/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/TargetConditionRender.tsx b/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/TargetConditionRender.tsx index 61c6017e1..de6052723 100644 --- a/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/TargetConditionRender.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/TargetConditionRender.tsx @@ -3,6 +3,7 @@ import React from "react"; import { isComparisonCondition, + isIdentifierCondition, isKindCondition, isMetadataCondition, isNameCondition, @@ -11,6 +12,7 @@ import { import type { TargetConditionRenderProps } from "./target-condition-props"; import { ComparisonConditionRender } from "./ComparisonConditionRender"; +import { IdentifierConditionRender } from "./IdentifierConditionRender"; import { KindConditionRender } from "./KindConditionRender"; import { NameConditionRender } from "./NameConditionRender"; import { ProviderConditionRender } from "./ProviderConditionRender"; @@ -22,14 +24,13 @@ import { TargetMetadataConditionRender } from "./TargetMetadataConditionRender"; */ export const TargetConditionRender: React.FC< TargetConditionRenderProps -> = ({ condition, onChange, onRemove, depth = 0, className }) => { +> = ({ condition, onChange, depth = 0, className }) => { if (isComparisonCondition(condition)) return ( ); @@ -39,8 +40,6 @@ export const TargetConditionRender: React.FC< ); @@ -50,8 +49,6 @@ export const TargetConditionRender: React.FC< ); @@ -61,8 +58,6 @@ export const TargetConditionRender: React.FC< ); @@ -72,8 +67,15 @@ export const TargetConditionRender: React.FC< + ); + + if (isIdentifierCondition(condition)) + return ( + ); diff --git a/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/target-condition-props.ts b/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/target-condition-props.ts index b3f2b000b..a60a2170e 100644 --- a/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/target-condition-props.ts +++ b/apps/webservice/src/app/[workspaceSlug]/_components/target-condition/target-condition-props.ts @@ -3,7 +3,6 @@ import type { TargetCondition } from "@ctrlplane/validators/targets"; export type TargetConditionRenderProps = { condition: T; onChange: (condition: T) => void; - onRemove?: () => void; depth?: number; className?: string; }; diff --git a/apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/releases/[versionId]/FlowPolicyNode.tsx b/apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/releases/[versionId]/FlowPolicyNode.tsx index 4ae71db9d..a4fad664d 100644 --- a/apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/releases/[versionId]/FlowPolicyNode.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/releases/[versionId]/FlowPolicyNode.tsx @@ -26,6 +26,7 @@ import { AlertDialogTitle, AlertDialogTrigger, } from "@ctrlplane/ui/alert-dialog"; +import { ColumnOperator } from "@ctrlplane/validators/conditions"; import { JobStatus } from "@ctrlplane/validators/jobs"; import { ReleaseFilterType, @@ -131,7 +132,7 @@ const useEvaluateReleaseFilterCheck = ( ? [ { type: ReleaseFilterType.Version, - operator: ReleaseOperator.Equals, + operator: ColumnOperator.Equals, value: release.version, }, check, diff --git a/packages/db/src/schema/job.ts b/packages/db/src/schema/job.ts index 2dee45d79..c66eb5134 100644 --- a/packages/db/src/schema/job.ts +++ b/packages/db/src/schema/job.ts @@ -32,10 +32,11 @@ import { import { createInsertSchema } from "drizzle-zod"; import { + ColumnOperator, ComparisonOperator, DateOperator, FilterType, - VersionOperator, + MetadataOperator, } from "@ctrlplane/validators/conditions"; import { JobFilterType } from "@ctrlplane/validators/jobs"; @@ -138,7 +139,7 @@ export const createJobVariable = createInsertSchema(jobVariable).omit({ export const updateJobVariable = createJobVariable.partial(); const buildMetadataCondition = (tx: Tx, cond: MetadataCondition): SQL => { - if (cond.operator === "null") + if (cond.operator === MetadataOperator.Null) return notExists( tx .select() @@ -148,7 +149,7 @@ const buildMetadataCondition = (tx: Tx, cond: MetadataCondition): SQL => { ), ); - if (cond.operator === "regex") + if (cond.operator === MetadataOperator.Regex) return exists( tx .select() @@ -162,7 +163,7 @@ const buildMetadataCondition = (tx: Tx, cond: MetadataCondition): SQL => { ), ); - if (cond.operator === "like") + if (cond.operator === MetadataOperator.Like) return exists( tx .select() @@ -200,9 +201,9 @@ const buildCreatedAtCondition = (cond: CreatedAtCondition): SQL => { }; const buildVersionCondition = (cond: VersionCondition): SQL => { - if (cond.operator === VersionOperator.Like) + if (cond.operator === ColumnOperator.Like) return like(release.version, cond.value); - if (cond.operator === VersionOperator.Regex) + if (cond.operator === ColumnOperator.Regex) return sql`${release.version} ~ ${cond.value}`; return eq(release.version, cond.value); }; diff --git a/packages/db/src/schema/release.ts b/packages/db/src/schema/release.ts index 8e8e2ea7e..7a77df809 100644 --- a/packages/db/src/schema/release.ts +++ b/packages/db/src/schema/release.ts @@ -32,8 +32,9 @@ import { createInsertSchema } from "drizzle-zod"; import { z } from "zod"; import { + ColumnOperator, DateOperator, - VersionOperator, + MetadataOperator, } from "@ctrlplane/validators/conditions"; import { releaseCondition, @@ -164,7 +165,7 @@ export type ReleaseJobTriggerInsert = InferInsertModel< >; const buildMetadataCondition = (tx: Tx, cond: MetadataCondition): SQL => { - if (cond.operator === "null") + if (cond.operator === MetadataOperator.Null) return notExists( tx .select() @@ -177,7 +178,7 @@ const buildMetadataCondition = (tx: Tx, cond: MetadataCondition): SQL => { ), ); - if (cond.operator === "regex") + if (cond.operator === MetadataOperator.Regex) return exists( tx .select() @@ -191,7 +192,7 @@ const buildMetadataCondition = (tx: Tx, cond: MetadataCondition): SQL => { ), ); - if (cond.operator === "like") + if (cond.operator === MetadataOperator.Like) return exists( tx .select() @@ -229,9 +230,9 @@ const buildCreatedAtCondition = (cond: CreatedAtCondition): SQL => { }; const buildVersionCondition = (cond: VersionCondition): SQL => { - if (cond.operator === VersionOperator.Equals) + if (cond.operator === ColumnOperator.Equals) return eq(release.version, cond.value); - if (cond.operator === VersionOperator.Like) + if (cond.operator === ColumnOperator.Like) return like(release.version, cond.value); return sql`${release.version} ~ ${cond.value}`; }; diff --git a/packages/db/src/schema/target.ts b/packages/db/src/schema/target.ts index b3d4dbf1e..fa415bd4c 100644 --- a/packages/db/src/schema/target.ts +++ b/packages/db/src/schema/target.ts @@ -1,5 +1,8 @@ import type { MetadataCondition } from "@ctrlplane/validators/conditions"; -import type { TargetCondition } from "@ctrlplane/validators/targets"; +import type { + IdentifierCondition, + TargetCondition, +} from "@ctrlplane/validators/targets"; import type { InferInsertModel, InferSelectModel, SQL } from "drizzle-orm"; import { exists, like, not, notExists, or, relations, sql } from "drizzle-orm"; import { @@ -17,7 +20,15 @@ import { and, eq } from "drizzle-orm/sql"; import { createInsertSchema } from "drizzle-zod"; import { z } from "zod"; -import { targetCondition } from "@ctrlplane/validators/targets"; +import { + ColumnOperator, + ComparisonOperator, + MetadataOperator, +} from "@ctrlplane/validators/conditions"; +import { + targetCondition, + TargetFilterType, +} from "@ctrlplane/validators/targets"; import type { Tx } from "../common.js"; import { targetProvider } from "./target-provider.js"; @@ -125,7 +136,7 @@ export const targetMetadataRelations = relations(targetMetadata, ({ one }) => ({ })); const buildMetadataCondition = (tx: Tx, cond: MetadataCondition): SQL => { - if (cond.operator === "null") + if (cond.operator === MetadataOperator.Null) return notExists( tx .select() @@ -138,7 +149,7 @@ const buildMetadataCondition = (tx: Tx, cond: MetadataCondition): SQL => { ), ); - if (cond.operator === "regex") + if (cond.operator === MetadataOperator.Regex) return exists( tx .select() @@ -152,7 +163,7 @@ const buildMetadataCondition = (tx: Tx, cond: MetadataCondition): SQL => { ), ); - if (cond.operator === "like") + if (cond.operator === MetadataOperator.Like) return exists( tx .select() @@ -183,16 +194,29 @@ const buildMetadataCondition = (tx: Tx, cond: MetadataCondition): SQL => { throw Error("invalid metadata conditions"); }; +const buildIdentifierCondition = (tx: Tx, cond: IdentifierCondition): SQL => { + if (cond.operator === ColumnOperator.Like) + return like(target.identifier, cond.value); + if (cond.operator === ColumnOperator.Equals) + return eq(target.identifier, cond.value); + return sql`${target.identifier} ~ ${cond.value}`; +}; + const buildCondition = (tx: Tx, cond: TargetCondition): SQL => { - if (cond.type === "metadata") return buildMetadataCondition(tx, cond); - if (cond.type === "kind") return eq(target.kind, cond.value); - if (cond.type === "name") return like(target.name, cond.value); - if (cond.type === "provider") return eq(target.providerId, cond.value); + if (cond.type === TargetFilterType.Metadata) + return buildMetadataCondition(tx, cond); + if (cond.type === TargetFilterType.Kind) return eq(target.kind, cond.value); + if (cond.type === TargetFilterType.Name) return like(target.name, cond.value); + if (cond.type === TargetFilterType.Provider) + return eq(target.providerId, cond.value); + if (cond.type === TargetFilterType.Identifier) + return buildIdentifierCondition(tx, cond); if (cond.conditions.length === 0) return sql`FALSE`; const subCon = cond.conditions.map((c) => buildCondition(tx, c)); - const con = cond.operator === "and" ? and(...subCon)! : or(...subCon)!; + const con = + cond.operator === ComparisonOperator.And ? and(...subCon)! : or(...subCon)!; return cond.not ? not(con) : con; }; diff --git a/packages/validators/src/conditions/index.ts b/packages/validators/src/conditions/index.ts index 54d00f183..d82c5cd00 100644 --- a/packages/validators/src/conditions/index.ts +++ b/packages/validators/src/conditions/index.ts @@ -1,14 +1,21 @@ +import { z } from "zod"; + export * from "./metadata-condition.js"; export * from "./date-condition.js"; -export * from "./version-condition.js"; export enum ColumnOperator { Equals = "equals", Like = "like", Regex = "regex", - Null = "null", } +export const columnOperator = z + .literal(ColumnOperator.Equals) + .or(z.literal(ColumnOperator.Like)) + .or(z.literal(ColumnOperator.Regex)); + +export type ColumnOperatorType = z.infer; + export enum ComparisonOperator { And = "and", Or = "or", @@ -22,3 +29,14 @@ export enum FilterType { } export const MAX_DEPTH_ALLOWED = 2; // 0 indexed + +// importing issue - if this is in another file, since it references +// columnOperator it throws an error saying that columnOperator is not initialized yet +// so we need to keep it here +export const versionCondition = z.object({ + type: z.literal("version"), + operator: columnOperator, + value: z.string().min(1), +}); + +export type VersionCondition = z.infer; diff --git a/packages/validators/src/conditions/version-condition.ts b/packages/validators/src/conditions/version-condition.ts index d012a9fe9..e69de29bb 100644 --- a/packages/validators/src/conditions/version-condition.ts +++ b/packages/validators/src/conditions/version-condition.ts @@ -1,17 +0,0 @@ -import { z } from "zod"; - -export const versionCondition = z.object({ - type: z.literal("version"), - operator: z.literal("like").or(z.literal("regex")).or(z.literal("equals")), - value: z.string().min(1), -}); - -export type VersionCondition = z.infer; - -export enum VersionOperator { - Like = "like", - Regex = "regex", - Equals = "equals", -} - -export type VersionOperatorType = z.infer["operator"]; diff --git a/packages/validators/src/jobs/conditions/comparison-condition.ts b/packages/validators/src/jobs/conditions/comparison-condition.ts index 229a3a739..4da8e4ce7 100644 --- a/packages/validators/src/jobs/conditions/comparison-condition.ts +++ b/packages/validators/src/jobs/conditions/comparison-condition.ts @@ -3,8 +3,8 @@ import { z } from "zod"; import type { CreatedAtCondition, MetadataCondition, + VersionCondition, } from "../../conditions/index.js"; -import type { VersionCondition } from "../../conditions/version-condition.js"; import type { DeploymentCondition } from "./deployment-condition.js"; import type { EnvironmentCondition } from "./environment-condition.js"; import type { JobTargetCondition } from "./job-target-condition.js"; @@ -12,8 +12,8 @@ import type { StatusCondition } from "./status-condition.js"; import { createdAtCondition, metadataCondition, + versionCondition, } from "../../conditions/index.js"; -import { versionCondition } from "../../conditions/version-condition.js"; import { deploymentCondition } from "./deployment-condition.js"; import { environmentCondition } from "./environment-condition.js"; import { jobTargetCondition } from "./job-target-condition.js"; diff --git a/packages/validators/src/jobs/conditions/job-condition.ts b/packages/validators/src/jobs/conditions/job-condition.ts index d5cb9bdd3..0f66f6d9e 100644 --- a/packages/validators/src/jobs/conditions/job-condition.ts +++ b/packages/validators/src/jobs/conditions/job-condition.ts @@ -3,8 +3,8 @@ import { z } from "zod"; import type { CreatedAtCondition, MetadataCondition, + VersionCondition, } from "../../conditions/index.js"; -import type { VersionCondition } from "../../conditions/version-condition.js"; import type { ComparisonCondition } from "./comparison-condition.js"; import type { DeploymentCondition } from "./deployment-condition.js"; import type { EnvironmentCondition } from "./environment-condition.js"; @@ -17,8 +17,8 @@ import { MAX_DEPTH_ALLOWED, metadataCondition, MetadataOperator, + versionCondition, } from "../../conditions/index.js"; -import { versionCondition } from "../../conditions/version-condition.js"; import { comparisonCondition } from "./comparison-condition.js"; import { deploymentCondition } from "./deployment-condition.js"; import { environmentCondition } from "./environment-condition.js"; diff --git a/packages/validators/src/releases/conditions/comparison-condition.ts b/packages/validators/src/releases/conditions/comparison-condition.ts index f018286c0..8d96eda58 100644 --- a/packages/validators/src/releases/conditions/comparison-condition.ts +++ b/packages/validators/src/releases/conditions/comparison-condition.ts @@ -1,11 +1,12 @@ import { z } from "zod"; import type { CreatedAtCondition } from "../../conditions/date-condition.js"; -import type { MetadataCondition } from "../../conditions/index.js"; -import type { VersionCondition } from "../../conditions/version-condition.js"; +import type { + MetadataCondition, + VersionCondition, +} from "../../conditions/index.js"; import { createdAtCondition } from "../../conditions/date-condition.js"; -import { metadataCondition } from "../../conditions/index.js"; -import { versionCondition } from "../../conditions/version-condition.js"; +import { metadataCondition, versionCondition } from "../../conditions/index.js"; export const comparisonCondition: z.ZodType = z.lazy(() => z.object({ diff --git a/packages/validators/src/releases/conditions/release-condition.ts b/packages/validators/src/releases/conditions/release-condition.ts index 01f04851b..3231818b0 100644 --- a/packages/validators/src/releases/conditions/release-condition.ts +++ b/packages/validators/src/releases/conditions/release-condition.ts @@ -1,12 +1,13 @@ import { z } from "zod"; import type { CreatedAtCondition } from "../../conditions/date-condition.js"; -import type { MetadataCondition } from "../../conditions/index.js"; -import type { VersionCondition } from "../../conditions/version-condition.js"; +import type { + MetadataCondition, + VersionCondition, +} from "../../conditions/index.js"; import type { ComparisonCondition } from "./comparison-condition.js"; import { createdAtCondition } from "../../conditions/date-condition.js"; -import { metadataCondition } from "../../conditions/index.js"; -import { versionCondition } from "../../conditions/version-condition.js"; +import { metadataCondition, versionCondition } from "../../conditions/index.js"; import { comparisonCondition } from "./comparison-condition.js"; export type ReleaseCondition = diff --git a/packages/validators/src/targets/conditions/comparison-condition.ts b/packages/validators/src/targets/conditions/comparison-condition.ts index 0b91632d2..a5e85a195 100644 --- a/packages/validators/src/targets/conditions/comparison-condition.ts +++ b/packages/validators/src/targets/conditions/comparison-condition.ts @@ -1,10 +1,12 @@ import { z } from "zod"; import type { MetadataCondition } from "../../conditions/index.js"; +import type { IdentifierCondition } from "./identifier-condition.js"; import type { KindCondition } from "./kind-condition.js"; import type { NameCondition } from "./name-condition.js"; import type { ProviderCondition } from "./provider-condition.js"; import { metadataCondition } from "../../conditions/index.js"; +import { identifierCondition } from "./identifier-condition.js"; import { kindCondition } from "./kind-condition.js"; import { nameCondition } from "./name-condition.js"; import { providerCondition } from "./provider-condition.js"; @@ -21,6 +23,7 @@ export const comparisonCondition: z.ZodType = z.lazy(() => kindCondition, nameCondition, providerCondition, + identifierCondition, ]), ), }), @@ -36,5 +39,6 @@ export type ComparisonCondition = { | KindCondition | NameCondition | ProviderCondition + | IdentifierCondition >; }; diff --git a/packages/validators/src/targets/conditions/identifier-condition.ts b/packages/validators/src/targets/conditions/identifier-condition.ts new file mode 100644 index 000000000..7a0a92294 --- /dev/null +++ b/packages/validators/src/targets/conditions/identifier-condition.ts @@ -0,0 +1,13 @@ +import { z } from "zod"; + +import { columnOperator } from "../../conditions/index.js"; + +export const identifierCondition = z.object({ + type: z.literal("identifier"), + operator: columnOperator, + value: z.string().min(1), +}); + +export type IdentifierCondition = z.infer; + +export type IdentifierOperator = IdentifierCondition["operator"]; diff --git a/packages/validators/src/targets/conditions/index.ts b/packages/validators/src/targets/conditions/index.ts index af520a471..17cdbb5d8 100644 --- a/packages/validators/src/targets/conditions/index.ts +++ b/packages/validators/src/targets/conditions/index.ts @@ -3,3 +3,4 @@ export * from "./kind-condition.js"; export * from "./comparison-condition.js"; export * from "./target-condition.js"; export * from "./provider-condition.js"; +export * from "./identifier-condition.js"; diff --git a/packages/validators/src/targets/conditions/target-condition.ts b/packages/validators/src/targets/conditions/target-condition.ts index d2ebad1bf..15b408082 100644 --- a/packages/validators/src/targets/conditions/target-condition.ts +++ b/packages/validators/src/targets/conditions/target-condition.ts @@ -2,11 +2,13 @@ import { z } from "zod"; import type { MetadataCondition } from "../../conditions/index.js"; import type { ComparisonCondition } from "./comparison-condition.js"; +import type { IdentifierCondition } from "./identifier-condition.js"; import type { KindCondition } from "./kind-condition.js"; import type { NameCondition } from "./name-condition.js"; import type { ProviderCondition } from "./provider-condition.js"; import { metadataCondition } from "../../conditions/index.js"; import { comparisonCondition } from "./comparison-condition.js"; +import { identifierCondition } from "./identifier-condition.js"; import { kindCondition } from "./kind-condition.js"; import { nameCondition } from "./name-condition.js"; import { providerCondition } from "./provider-condition.js"; @@ -16,7 +18,8 @@ export type TargetCondition = | MetadataCondition | KindCondition | NameCondition - | ProviderCondition; + | ProviderCondition + | IdentifierCondition; export const targetCondition = z.union([ comparisonCondition, @@ -24,6 +27,7 @@ export const targetCondition = z.union([ kindCondition, nameCondition, providerCondition, + identifierCondition, ]); export enum TargetOperator { @@ -39,6 +43,7 @@ export enum TargetFilterType { Metadata = "metadata", Kind = "kind", Name = "name", + Identifier = "identifier", Provider = "provider", Comparison = "comparison", } @@ -94,16 +99,18 @@ export const isProviderCondition = ( ): condition is ProviderCondition => condition.type === TargetFilterType.Provider; +export const isIdentifierCondition = ( + condition: TargetCondition, +): condition is IdentifierCondition => + condition.type === TargetFilterType.Identifier; + export const isValidTargetCondition = (condition: TargetCondition): boolean => { if (isComparisonCondition(condition)) return condition.conditions.every((c) => isValidTargetCondition(c)); - if (isKindCondition(condition)) return condition.value.length > 0; - if (isNameCondition(condition)) return condition.value.length > 0; - if (isProviderCondition(condition)) return condition.value.length > 0; if (isMetadataCondition(condition)) { if (condition.operator === TargetOperator.Null) return condition.value == null && condition.key.length > 0; return condition.value.length > 0 && condition.key.length > 0; } - return false; + return condition.value.length > 0; };