diff --git a/src/api/schemas.ts b/src/api/schemas.ts index 1330bb92..2626d9a4 100644 --- a/src/api/schemas.ts +++ b/src/api/schemas.ts @@ -1,5 +1,4 @@ import { z } from 'zod' -import { GetProjectsParams } from './zodClientAPI' import { Variable, Variation, @@ -36,6 +35,7 @@ import { CreateFeatureDto, UpdateFeatureDto, CreateVariableDto, + GetProjectsParams, } from './zodSchemas' export type Project = z.infer diff --git a/src/api/zodClientAPI.ts b/src/api/zodClientAPI.ts index d4772444..98b33e74 100644 --- a/src/api/zodClientAPI.ts +++ b/src/api/zodClientAPI.ts @@ -46,25 +46,6 @@ import { UserOverride, } from './zodSchemas' -const GetProjectsParams = z.object({ - page: z.number().gte(1).optional().default(1), - perPage: z.number().gte(1).lte(1000).optional().default(100), - sortBy: z - .enum([ - 'createdAt', - 'updatedAt', - 'name', - 'key', - 'createdBy', - 'propertyKey', - ]) - .optional() - .default('createdAt'), - sortOrder: z.enum(['asc', 'desc']).optional().default('desc'), - search: z.string().optional(), - createdBy: z.string().optional(), -}) - const BadRequestErrorResponse = z.object({ statusCode: z.number(), message: z.object({}).partial(), @@ -93,7 +74,6 @@ const PreconditionFailedErrorResponse = z.object({ }) export { - GetProjectsParams, BadRequestErrorResponse, ConflictErrorResponse, NotFoundErrorResponse, diff --git a/src/api/zodSchemas.ts b/src/api/zodSchemas.ts index 546a03e7..2de0a8fe 100644 --- a/src/api/zodSchemas.ts +++ b/src/api/zodSchemas.ts @@ -17,6 +17,24 @@ */ import { z } from 'zod' +export const GetProjectsParams = z.object({ + page: z.number().gte(1).optional().default(1), + perPage: z.number().gte(1).lte(1000).optional().default(100), + sortBy: z + .enum([ + 'createdAt', + 'updatedAt', + 'name', + 'key', + 'createdBy', + 'propertyKey', + ]) + .optional() + .default('createdAt'), + sortOrder: z.enum(['asc', 'desc']).optional().default('desc'), + search: z.string().optional(), + createdBy: z.string().optional(), +}) export const ResultSummaryDto = z.object({ result: z .object({ @@ -71,7 +89,7 @@ const ObfuscationSettingsDTO = z const DynatraceProjectSettingsDTO = z .object({ enabled: z.boolean(), - environmentMap: z.object({}).partial().passthrough(), + environmentMap: z.record(z.unknown()), }) .partial() .passthrough() @@ -86,25 +104,23 @@ export const ProjectSettingsDTO = z dynatrace: DynatraceProjectSettingsDTO, }) .passthrough() -export const CreateProjectDto = z - .object({ - name: z.string().min(1).max(100), - key: z - .string() - .min(1) - .max(100) - .regex(/^[a-z0-9-_.]+$/), - description: z.string().max(1000).optional(), - color: z - .string() - .max(9) - .regex( - /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/, - ) - .optional(), - settings: ProjectSettingsDTO.optional(), - }) - .passthrough() +export const CreateProjectDto = z.object({ + key: z + .string() + .min(1) + .max(100) + .regex(/^[a-z0-9-_.]+$/), + name: z.string().min(1).max(100), + description: z.string().max(1000).optional(), + color: z + .string() + .max(9) + .regex( + /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{4}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/, + ) + .optional(), + settings: ProjectSettingsDTO.optional(), +}) const EdgeDBSettings = z.object({ enabled: z.boolean() }) const ColorSettings = z.object({ primary: z.string(), secondary: z.string() }) const OptInSettings = z.object({ @@ -113,7 +129,7 @@ const OptInSettings = z.object({ description: z.string(), imageURL: z.string(), colors: ColorSettings, - poweredByAlignment: z.object({}).partial().passthrough(), + poweredByAlignment: z.record(z.unknown()), }) const SDKTypeVisibilitySettings = z.object({ enabledInFeatureSettings: z.boolean(), @@ -153,7 +169,7 @@ const StalenessSettings = z const DynatraceProjectSettings = z .object({ enabled: z.boolean(), - environmentMap: z.object({}).partial().passthrough(), + environmentMap: z.record(z.unknown()), }) .passthrough() export const ProjectSettings = z @@ -194,36 +210,14 @@ export const Project = z .optional(), }) .passthrough() -// const BadRequestErrorResponse = z -// .object({ -// statusCode: z.number(), -// message: z.object({}).partial().passthrough(), -// error: z.string(), -// }) -// .passthrough() -// const ConflictErrorResponse = z -// .object({ -// statusCode: z.number(), -// message: z.object({}).partial().passthrough(), -// error: z.string(), -// errorType: z.string(), -// }) -// .passthrough() -// const NotFoundErrorResponse = z -// .object({ -// statusCode: z.number(), -// message: z.object({}).partial().passthrough(), -// error: z.string(), -// }) -// .passthrough() export const UpdateProjectDto = z .object({ - name: z.string().min(1).max(100), key: z .string() .min(1) .max(100) .regex(/^[a-z0-9-_.]+$/), + name: z.string().min(1).max(100), description: z.string().max(1000), color: z .string() @@ -234,13 +228,6 @@ export const UpdateProjectDto = z settings: ProjectSettingsDTO, }) .partial() -// const CannotDeleteLastItemErrorResponse = z -// .object({ -// statusCode: z.number(), -// message: z.object({}).partial().passthrough(), -// error: z.string(), -// }) -// .passthrough() // const UpdateProjectSettingsDto = z // .object({ settings: ProjectSettings }) // .passthrough() @@ -294,19 +281,19 @@ const FeatureStalenessEntity = z reason: z .enum(['released', 'unused', 'unmodifiedShort', 'unmodifiedLong']) .optional(), - metaData: z.object({}).partial().passthrough().optional(), + metaData: z.record(z.unknown()).optional(), }) .passthrough() const EnvironmentSettings = z .object({ appIconURI: z.string().max(2048) }) .partial() export const CreateEnvironmentDto = z.object({ - name: z.string().min(1).max(100), key: z .string() .min(1) .max(100) .regex(/^[a-z0-9-_.]+$/), + name: z.string().min(1).max(100), description: z.string().max(1000).optional(), color: z .string() @@ -355,12 +342,12 @@ export const Environment = z.object({ }) export const UpdateEnvironmentDto = z .object({ - name: z.string().min(1).max(100), key: z .string() .min(1) .max(100) .regex(/^[a-z0-9-_.]+$/), + name: z.string().min(1).max(100), description: z.string().max(1000), color: z .string() @@ -550,7 +537,7 @@ export const UpdateAudienceDto = z tags: z.array(z.string()), }) .partial() -// const AudienceEnvironments = z.object({}).partial().passthrough() +// const AudienceEnvironments = z.record(z.unknown()) // const AudienceFeature = z // .object({ // key: z @@ -575,17 +562,18 @@ const VariableValidationEntity = z.object({ exampleValue: z.any(), }) export const CreateVariableDto = z.object({ - name: z.string().min(1).max(100).optional(), - description: z.string().max(1000).optional(), key: z .string() .min(1) .max(100) .regex(/^[a-z0-9-_.]+$/), - _feature: z.string().optional(), + name: z.string().min(1).max(100).optional(), + description: z.string().max(1000).optional(), type: z.enum(['String', 'Boolean', 'Number', 'JSON']), defaultValue: z.any().optional(), + _feature: z.string().optional(), validationSchema: VariableValidationEntity.optional(), + persistent: z.boolean().optional(), tags: z.array(z.string()).optional(), }) // Remove defaultValue from CreateVariableDto for Features V2 endpoints @@ -630,13 +618,13 @@ export const Variable = z .passthrough() export const UpdateVariableDto = z .object({ - name: z.string().min(1).max(100), - description: z.string().max(1000), key: z .string() .min(1) .max(100) .regex(/^[a-z0-9-_.]+$/), + name: z.string().min(1).max(100), + description: z.string().max(1000), type: z.enum(['String', 'Boolean', 'Number', 'JSON']), validationSchema: VariableValidationEntity, persistent: z.boolean(), @@ -697,7 +685,6 @@ export const UpdateFeatureConfigDto = z status: z.enum(['active', 'inactive']).default('inactive'), targets: z .array(UpdateTargetDto) - .optional() .describe( 'Setting an empty array will remove all targets for this configuration', ), @@ -717,7 +704,7 @@ export const CreateVariationDto = z.object({ z.number(), z.boolean(), z.array(z.unknown()), - z.object({}).partial().passthrough(), + z.record(z.unknown()), ]), ) .optional(), @@ -765,7 +752,7 @@ export const Variation = z.object({ z.number(), z.boolean(), z.array(z.unknown()), - z.object({}).partial().passthrough(), + z.record(z.unknown()), ]), ) .optional(), @@ -804,10 +791,10 @@ const AuditLogEntity = z .object({ date: z.string().datetime({ offset: true }), a0_user: z.string(), - changes: z.array(z.object({}).partial().passthrough()), + changes: z.array(z.record(z.unknown())), }) .passthrough() -// const FeatureStaleness = z.object({}).partial().passthrough() +// const FeatureStaleness = z.record(z.unknown()) const Link = z.object({ url: z.string(), title: z.string() }).passthrough() const FeatureSummary = z .object({ @@ -858,9 +845,7 @@ export const Feature = z sdkVisibility: FeatureSDKVisibility.optional(), configurations: z.array(FeatureConfig.partial()).optional(), latestUpdate: AuditLogEntity.optional(), - changeRequests: z - .array(z.object({}).partial().passthrough()) - .optional(), + changeRequests: z.array(z.record(z.unknown())).optional(), staleness: FeatureStalenessEntity.optional(), summary: FeatureSummary.partial().optional(), }) @@ -880,7 +865,7 @@ const UpdateVariationDto = z z.number(), z.boolean(), z.array(z.unknown()), - z.object({}).partial().passthrough(), + z.record(z.unknown()), ]), ) .optional(), @@ -929,15 +914,15 @@ export const UpdateFeatureStatusDto = z.object({ // .optional(), // name: z.string().min(1).max(100).optional(), // description: z.string().max(1000).optional(), -// variables: z.object({}).partial().passthrough(), -// environments: z.object({}).partial().passthrough(), +// variables: z.record(z.unknown()), +// environments: z.record(z.unknown()), // readonly: z.boolean(), // type: z.enum(['release', 'experiment', 'permission', 'ops']).optional(), // tags: z.array(z.string()).optional(), // controlVariation: z.string().optional(), // settings: FeatureSettingsDto.optional(), // sdkVisibility: FeatureSDKVisibilityDto.optional(), -// staleness: z.object({}).partial().passthrough().optional(), +// staleness: z.record(z.unknown()).optional(), // summary: UpdateFeatureSummaryDto.optional(), // }) // .passthrough() @@ -955,10 +940,10 @@ export const UpdateFeatureStatusDto = z.object({ // controlVariation: z.string(), // settings: FeatureSettingsDto, // sdkVisibility: FeatureSDKVisibilityDto, -// staleness: z.object({}).partial().passthrough(), +// staleness: z.record(z.unknown()), // summary: UpdateFeatureSummaryDto, -// variables: z.object({}).partial().passthrough(), -// environments: z.object({}).partial().passthrough(), +// variables: z.record(z.unknown()), +// environments: z.record(z.unknown()), // }) // .partial() // .passthrough() @@ -979,7 +964,7 @@ export const FeatureVariationDto = z.object({ z.number(), z.boolean(), z.array(z.unknown()), - z.object({}).partial().passthrough(), + z.record(z.unknown()), ]), ) .optional(), @@ -999,13 +984,13 @@ export const UpdateFeatureVariationDto = z z.number(), z.boolean(), z.array(z.unknown()), - z.object({}).partial().passthrough(), + z.record(z.unknown()), ]), ), }) .partial() const FeatureDataPoint = z.object({ - values: z.object({}).partial().passthrough(), + values: z.record(z.unknown()), date: z.string().datetime({ offset: true }), }) const ResultWithFeatureData = z @@ -1048,7 +1033,7 @@ const UpdateUserProfileDto = z .partial() const AllowedValue = z.object({ label: z.string(), - value: z.object({}).partial().passthrough(), + value: z.record(z.unknown()), }) const EnumSchema = z.object({ allowedValues: z.array(AllowedValue), @@ -1259,7 +1244,7 @@ export const UserOverride = z.object({ }) // const AudiencePatchAction = z // .object({ -// values: z.object({}).partial().passthrough(), +// values: z.record(z.unknown()), // filterIndex: z.string(), // }) // .passthrough() @@ -1276,12 +1261,12 @@ export const UserOverride = z.object({ // .object({ // snoozedUntil: z.string(), // disabled: z.boolean(), -// metaData: z.object({}).partial().passthrough(), +// metaData: z.record(z.unknown()), // }) // .partial() // .passthrough() -// const Reviewers = z.object({}).partial().passthrough() -// const ReviewReason = z.object({}).partial().passthrough() +// const Reviewers = z.record(z.unknown()) +// const ReviewReason = z.record(z.unknown()) // const FeatureDetails = z // .object({ // key: z @@ -1325,7 +1310,7 @@ export const UserOverride = z.object({ // .object({ // path: z.string(), // method: z.literal('PATCH'), -// body: z.object({}).partial().passthrough(), +// body: z.record(z.unknown()), // }) // .passthrough() // const FeatureChangeRequest = z @@ -1342,7 +1327,7 @@ export const UserOverride = z.object({ // 'rejected', // 'cancelled', // ]), -// changes: z.array(z.object({}).partial().passthrough()).optional(), +// changes: z.array(z.record(z.unknown())).optional(), // operation: z.enum([ // 'featureUpdate', // 'featureStatusUpdate', @@ -1373,7 +1358,7 @@ export const UserOverride = z.object({ // .object({ // name: z.string().min(1).max(100), // description: z.string().max(1000).optional(), -// outputFormat: z.object({}).partial().passthrough().optional(), +// outputFormat: z.record(z.unknown()).optional(), // _feature: z.string().optional(), // _environments: z.array(z.string()).optional(), // events: z.array(z.string()), @@ -1410,7 +1395,7 @@ export const UserOverride = z.object({ // createdBy: z.string().optional(), // createdAt: z.string().datetime({ offset: true }), // updatedAt: z.string().datetime({ offset: true }), -// outputFormat: z.object({}).partial().passthrough().optional(), +// outputFormat: z.record(z.unknown()).optional(), // _slackIntegration: z.string().optional(), // }) // .passthrough() @@ -1422,7 +1407,7 @@ export const UserOverride = z.object({ // _environments: z.array(z.string()), // events: z.array(z.string()).optional(), // url: z.string().optional(), -// outputFormat: z.object({}).partial().passthrough().optional(), +// outputFormat: z.record(z.unknown()).optional(), // }) // .passthrough() // const CreateDynatraceIntegrationDto = z diff --git a/src/commands/projects/get.ts b/src/commands/projects/get.ts index 7781381a..ed798268 100644 --- a/src/commands/projects/get.ts +++ b/src/commands/projects/get.ts @@ -1,5 +1,5 @@ import { fetchProjects } from '../../api/projects' -import { GetProjectsParams } from '../../api/zodClientAPI' +import { GetProjectsParams } from '../../api/zodSchemas' import type { Project } from '../../api/schemas' import GetCommand from '../getCommand' diff --git a/src/mcp/types.ts b/src/mcp/types.ts index be43f87b..bf41008d 100644 --- a/src/mcp/types.ts +++ b/src/mcp/types.ts @@ -1,6 +1,6 @@ import { z } from 'zod' -import { GetProjectsParams } from '../api/zodClientAPI' import { + GetProjectsParams, CreateProjectDto, UpdateProjectDto, CreateEnvironmentDto, @@ -135,38 +135,40 @@ export const ListVariablesArgsSchema = z.object({ .describe('Filter by variable status'), }) -export const CreateVariableArgsSchema = z.object({ +export const CreateVariableArgsSchema = CreateVariableDto.extend({ key: CreateVariableDto.shape.key.describe('Unique variable key'), - name: CreateVariableDto.shape.name, - description: CreateVariableDto.shape.description.optional(), - type: CreateVariableDto.shape.type, - defaultValue: CreateVariableDto.shape.defaultValue - .optional() - .describe( - 'Default value for the variable, the data type of the defaultValue must match the variable.type', - ), - _feature: CreateVariableDto.shape._feature - .optional() - .describe( - 'Feature key or ID to associate with this variable, only set if variable is associated with a feature', - ), - validationSchema: VariableValidationSchema.optional().describe( + defaultValue: CreateVariableDto.shape.defaultValue.describe( + 'Default value for the variable, the data type of the defaultValue must match the variable.type', + ), + _feature: CreateVariableDto.shape._feature.describe( + 'Feature key or ID to associate with this variable, only set if variable is associated with a feature', + ), + validationSchema: CreateVariableDto.shape.validationSchema.describe( 'Validation schema for variable values', ), + persistent: CreateVariableDto.shape.persistent.describe( + 'indicating if the variable is intended to be long-lived within a feature', + ), + tags: CreateVariableDto.shape.tags.describe('Tags to organize variables'), }) -export const UpdateVariableArgsSchema = z.object({ +export const UpdateVariableArgsSchema = UpdateVariableDto.extend({ key: z .string() .max(100) .regex(/^[a-z0-9-_.]+$/) .describe('key to identify variable'), - name: UpdateVariableDto.shape.name.optional(), - description: UpdateVariableDto.shape.description.optional(), - type: UpdateVariableDto.shape.type.optional(), - validationSchema: VariableValidationSchema.optional().describe( - 'Validation schema for variable values', - ), + validationSchema: UpdateVariableDto.shape.validationSchema + .optional() + .describe('Validation schema for variable values'), + persistent: UpdateVariableDto.shape.persistent + .optional() + .describe( + 'indicating if the variable is intended to be long-lived within a feature', + ), + tags: UpdateVariableDto.shape.tags + .optional() + .describe('Tags to organize variables'), }) export const DeleteVariableArgsSchema = z.object({ @@ -177,13 +179,11 @@ export const DeleteFeatureArgsSchema = z.object({ key: z.string().describe('key to identify feature to delete'), }) -export const ListProjectsArgsSchema = z.object({ +export const ListProjectsArgsSchema = GetProjectsParams.extend({ page: GetProjectsParams.shape.page.describe('Page number for pagination'), perPage: GetProjectsParams.shape.perPage.describe( 'Number of items per page', ), - sortBy: GetProjectsParams.shape.sortBy, - sortOrder: GetProjectsParams.shape.sortOrder, search: GetProjectsParams.shape.search.describe( 'Search term to filter projects by "name" or "key"', ), @@ -192,30 +192,22 @@ export const ListProjectsArgsSchema = z.object({ ), }) -export const CreateProjectArgsSchema = z.object({ - name: CreateProjectDto.shape.name, - key: CreateProjectDto.shape.key.describe( - 'Unique project key (lowercase letters, numbers, dots, dashes, underscores only)', - ), - description: CreateProjectDto.shape.description, +export const CreateProjectArgsSchema = CreateProjectDto.extend({ + key: CreateProjectDto.shape.key.describe('Unique project key'), color: CreateProjectDto.shape.color.describe( 'Project color in hex format (e.g., #FF0000)', ), - settings: CreateProjectDto.shape.settings, }) -export const UpdateProjectArgsSchema = z.object({ +export const UpdateProjectArgsSchema = UpdateProjectDto.extend({ key: z .string() .max(100) .regex(/^[a-z0-9-_.]+$/) .describe('key to identify project to update'), - name: UpdateProjectDto.shape.name, - description: UpdateProjectDto.shape.description, - color: UpdateProjectDto.shape.color.describe( - 'Updated project color in hex format (e.g., #FF0000)', - ), - settings: UpdateProjectDto.shape.settings, + color: UpdateProjectDto.shape.color + .describe('Updated project color in hex format (e.g., #FF0000)') + .optional(), }) export const ListEnvironmentsArgsSchema = z.object({ @@ -254,28 +246,18 @@ export const GetSdkKeysArgsSchema = z.object({ .describe('type of SDK key to retrieve'), }) -export const CreateEnvironmentArgsSchema = z.object({ - name: CreateEnvironmentDto.shape.name, - key: CreateEnvironmentDto.shape.key.describe( - 'Unique environment key (lowercase letters, numbers, dots, dashes, underscores only)', - ), - description: CreateEnvironmentDto.shape.description, +export const CreateEnvironmentArgsSchema = CreateEnvironmentDto.extend({ + key: CreateEnvironmentDto.shape.key.describe('Unique environment key'), color: CreateEnvironmentDto.shape.color.describe( 'Environment color in hex format (e.g., #FF0000)', ), - type: CreateEnvironmentDto.shape.type, - settings: CreateEnvironmentDto.shape.settings, }) -export const UpdateEnvironmentArgsSchema = z.object({ +export const UpdateEnvironmentArgsSchema = UpdateEnvironmentDto.extend({ key: z.string().describe('key to identify environment to update'), - name: UpdateEnvironmentDto.shape.name, - description: UpdateEnvironmentDto.shape.description, - color: UpdateEnvironmentDto.shape.color.describe( - 'color in hex format (e.g., #FF0000)', - ), - type: UpdateEnvironmentDto.shape.type, - settings: UpdateEnvironmentDto.shape.settings, + color: UpdateEnvironmentDto.shape.color + .describe('color in hex format (e.g., #FF0000)') + .optional(), }) export const SetFeatureTargetingArgsSchema = z.object({ @@ -286,12 +268,8 @@ export const SetFeatureTargetingArgsSchema = z.object({ enabled: z.boolean().describe('enable or disable targeting'), }) -export const CreateFeatureArgsSchema = z.object({ - name: CreateFeatureDto.shape.name, - key: CreateFeatureDto.shape.key.describe( - 'Unique feature key (lowercase letters, numbers, dots, dashes, underscores only)', - ), - description: CreateFeatureDto.shape.description, +export const CreateFeatureArgsSchema = CreateFeatureDto.extend({ + key: CreateFeatureDto.shape.key.describe('Unique feature key'), variables: CreateFeatureDto.shape.variables.describe( 'Array of variables to create or reassociate with this feature', ), @@ -310,57 +288,56 @@ export const CreateFeatureArgsSchema = z.object({ sdkVisibility: CreateFeatureDto.shape.sdkVisibility.describe( 'SDK Type Visibility Settings for mobile, client, and server SDKs', ), - type: CreateFeatureDto.shape.type, tags: CreateFeatureDto.shape.tags.describe('Tags to organize features'), }) -export const UpdateFeatureArgsSchema = z.object({ +export const UpdateFeatureArgsSchema = UpdateFeatureDto.extend({ key: z .string() .min(1) .max(100) .regex(/^[a-z0-9-_.]+$/) .describe('key to identify feature to update'), - name: UpdateFeatureDto.shape.name, - description: UpdateFeatureDto.shape.description, - type: UpdateFeatureDto.shape.type, - tags: UpdateFeatureDto.shape.tags.describe( - 'Updated tags to organize features', - ), - configurations: UpdateFeatureDto.shape.configurations.describe( - 'Updated environment-specific targeting configurations (key-value map of environment keys to config)', - ), - variables: UpdateFeatureDto.shape.variables.describe( - 'Updated array of variables for this feature', - ), - variations: UpdateFeatureDto.shape.variations.describe( - 'Updated array of variations for this feature', - ), - settings: UpdateFeatureDto.shape.settings.describe( - 'Updated feature-level settings configuration', - ), - sdkVisibility: UpdateFeatureDto.shape.sdkVisibility.describe( - 'Updated SDK Type Visibility Settings for mobile, client, and server SDKs', - ), - controlVariation: UpdateFeatureDto.shape.controlVariation.describe( - 'Updated control variation key for Metrics', - ), - // summary: UpdateFeatureDto.shape.summary.describe( + configurations: UpdateFeatureDto.shape.configurations + .optional() + .describe( + 'Updated environment-specific targeting configurations (key-value map of environment keys to config)', + ), + variables: UpdateFeatureDto.shape.variables + .optional() + .describe('Updated array of variables for this feature'), + variations: UpdateFeatureDto.shape.variations + .optional() + .describe('Updated array of variations for this feature'), + settings: UpdateFeatureDto.shape.settings + .optional() + .describe('Updated feature-level settings configuration'), + sdkVisibility: UpdateFeatureDto.shape.sdkVisibility + .optional() + .describe( + 'Updated SDK Type Visibility Settings for mobile, client, and server SDKs', + ), + controlVariation: UpdateFeatureDto.shape.controlVariation + .optional() + .describe('Updated control variation key for Metrics'), + tags: UpdateFeatureDto.shape.tags + .optional() + .describe('Updated tags to organize features'), + // summary: UpdateFeatureDto.shape.summary.optional().describe( // 'Updated feature summary', // ), - // staleness: UpdateFeatureDto.shape.staleness.describe( + // staleness: UpdateFeatureDto.shape.staleness.optional().describe( // 'Updated feature staleness configuration', // ), }) -export const UpdateFeatureStatusArgsSchema = z.object({ +export const UpdateFeatureStatusArgsSchema = UpdateFeatureStatusDto.extend({ key: z .string() .min(1) .max(100) .regex(/^[a-z0-9-_.]+$/) .describe('key to identify feature to update'), - status: UpdateFeatureStatusDto.shape.status, staticVariation: UpdateFeatureStatusDto.shape.staticVariation.describe( 'The variation key or ID to serve if the status is set to complete', ), @@ -396,34 +373,20 @@ export const ListVariationsArgsSchema = z.object({ const variablesDescription = 'key-value map of variable keys to their values for this variation. { "variableKey1": "value1", "variableKey2": false }' -export const CreateVariationArgsSchema = z.object({ +export const CreateVariationArgsSchema = CreateVariationDto.extend({ feature_key: z.string().describe('Feature key to create variation for'), - key: CreateVariationDto.shape.key.describe( - 'Unique variation key (lowercase letters, numbers, dots, dashes, underscores only)', - ), - name: CreateVariationDto.shape.name, + key: CreateVariationDto.shape.key.describe('Unique variation key'), variables: CreateVariationDto.shape.variables.describe(variablesDescription), }) -export const UpdateVariationArgsSchema = z.object({ +export const UpdateVariationArgsSchema = UpdateFeatureVariationDto.extend({ + key: UpdateFeatureVariationDto.shape.key.describe('Updated variation key'), feature_key: z .string() .describe('Feature key that the variation belongs to'), variation_key: z.string().describe('key to identify variation to update'), - key: UpdateFeatureVariationDto.shape.key.describe( - 'Updated variation key (lowercase letters, numbers, dots, dashes, underscores only)', - ), - name: UpdateFeatureVariationDto.shape.name, - variables: z - .record( - z.union([ - z.string(), - z.number(), - z.boolean(), - z.record(z.unknown()), - ]), - ) + variables: UpdateFeatureVariationDto.shape.variables .optional() .describe(`Updated ${variablesDescription}`), }) @@ -436,15 +399,14 @@ export const ListFeatureTargetingArgsSchema = z.object({ .describe('Optional environment key to filter targeting by'), }) -export const UpdateFeatureTargetingArgsSchema = z.object({ +export const UpdateFeatureTargetingArgsSchema = UpdateFeatureConfigDto.extend({ feature_key: z.string().describe('Feature key to update targeting for'), environment_key: z .string() .describe('Environment key to update targeting in'), - status: UpdateFeatureConfigDto.shape.status, - targets: UpdateFeatureConfigDto.shape.targets.describe( - 'Updated array of targeting rules/targets for the feature', - ), + targets: UpdateFeatureConfigDto.shape.targets + .optional() + .describe('Updated array of targeting rules/targets for the feature'), }) export const GetFeatureAuditLogHistoryArgsSchema = z.object({ @@ -573,26 +535,21 @@ export const ListCustomPropertiesArgsSchema = z.object({ createdBy: z.string().optional().describe('Filter by creator user ID'), }) -export const UpsertCustomPropertyArgsSchema = z.object({ - name: CreateCustomPropertyDto.shape.name, +export const UpsertCustomPropertyArgsSchema = CreateCustomPropertyDto.extend({ key: CreateCustomPropertyDto.shape.key.describe( - 'Unique custom property key (lowercase letters, numbers, dots, dashes, underscores only)', + 'Unique custom property key', ), - type: CreateCustomPropertyDto.shape.type, propertyKey: CreateCustomPropertyDto.shape.propertyKey.describe( 'Property key to associate with the custom property', ), }) -export const UpdateCustomPropertyArgsSchema = z.object({ +export const UpdateCustomPropertyArgsSchema = UpdateCustomPropertyDto.extend({ key: z .string() .max(100) .regex(/^[a-z0-9-_.]+$/) .describe('key to identify property to update'), - name: UpdateCustomPropertyDto.shape.name, - propertyKey: UpdateCustomPropertyDto.shape.propertyKey, - type: UpdateCustomPropertyDto.shape.type, }) export const DeleteCustomPropertyArgsSchema = z.object({