values.ts 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import { z } from "zod";
  2. // ServiceString is a string value in a service that can be read-only or editable
  3. export const serviceStringValidator = z.object({
  4. readOnly: z.boolean().default(false),
  5. value: z.string(),
  6. });
  7. export type ServiceString = z.infer<typeof serviceStringValidator>;
  8. // ServiceNumber is a number value in a service that can be read-only or editable
  9. export const serviceNumberValidator = z.object({
  10. readOnly: z.boolean().default(false),
  11. value: z.coerce.number(),
  12. });
  13. export type ServiceNumber = z.infer<typeof serviceNumberValidator>;
  14. // ServiceBoolean is a boolean value in a service that can be read-only or editable
  15. export const serviceBooleanValidator = z.object({
  16. readOnly: z.boolean().default(false),
  17. value: z.boolean(),
  18. });
  19. export type ServiceBoolean = z.infer<typeof serviceBooleanValidator>;
  20. // ServiceArray is an array of ServiceStrings
  21. const serviceArrayValidator = z.array(
  22. z.object({
  23. key: z.string(),
  24. value: serviceStringValidator,
  25. })
  26. );
  27. export type ServiceArray = z.infer<typeof serviceArrayValidator>;
  28. const getNumericValue = (
  29. defaultValue: number,
  30. overrideValue?: number,
  31. validAsZero = false
  32. ) => {
  33. if (!overrideValue) {
  34. return defaultValue;
  35. }
  36. if (!validAsZero && overrideValue === 0) {
  37. return defaultValue;
  38. }
  39. return overrideValue;
  40. };
  41. // ServiceField is a helper to create a ServiceString, ServiceNumber, or ServiceBoolean
  42. export const ServiceField = {
  43. string: (defaultValue: string, overrideValue?: string): ServiceString => {
  44. return {
  45. readOnly: !!overrideValue,
  46. value: overrideValue || defaultValue,
  47. };
  48. },
  49. number: (
  50. defaultValue: number,
  51. overrideValue?: number,
  52. validAsZero = false
  53. ): ServiceNumber => {
  54. return {
  55. readOnly: !!overrideValue || (validAsZero && overrideValue === 0),
  56. value: getNumericValue(defaultValue, overrideValue, validAsZero),
  57. };
  58. },
  59. boolean: (
  60. defaultValue?: boolean,
  61. overrideValue?: boolean
  62. ): ServiceBoolean => {
  63. return {
  64. readOnly: typeof overrideValue === "boolean",
  65. value: overrideValue || defaultValue || false,
  66. };
  67. },
  68. };
  69. // Autoscaling
  70. export const autoscalingValidator = z.object({
  71. enabled: serviceBooleanValidator,
  72. minInstances: serviceNumberValidator.optional(),
  73. maxInstances: serviceNumberValidator.optional(),
  74. cpuThresholdPercent: serviceNumberValidator.optional(),
  75. memoryThresholdPercent: serviceNumberValidator.optional(),
  76. });
  77. export type ClientAutoscaling = z.infer<typeof autoscalingValidator>;
  78. export type SerializedAutoscaling = {
  79. enabled: boolean;
  80. minInstances?: number;
  81. maxInstances?: number;
  82. cpuThresholdPercent?: number;
  83. memoryThresholdPercent?: number;
  84. };
  85. export function serializeAutoscaling({
  86. autoscaling,
  87. }: {
  88. autoscaling?: ClientAutoscaling;
  89. }): SerializedAutoscaling | undefined {
  90. return (
  91. autoscaling && {
  92. enabled: autoscaling.enabled.value,
  93. minInstances: autoscaling.minInstances?.value,
  94. maxInstances: autoscaling.maxInstances?.value,
  95. cpuThresholdPercent: autoscaling.cpuThresholdPercent?.value,
  96. memoryThresholdPercent: autoscaling.memoryThresholdPercent?.value,
  97. }
  98. );
  99. }
  100. export function deserializeAutoscaling({
  101. autoscaling,
  102. override,
  103. setDefaults,
  104. }: {
  105. autoscaling?: SerializedAutoscaling;
  106. override?: SerializedAutoscaling;
  107. setDefaults: boolean;
  108. }): ClientAutoscaling | undefined {
  109. return autoscaling
  110. ? {
  111. enabled: ServiceField.boolean(autoscaling.enabled, override?.enabled),
  112. minInstances: autoscaling.minInstances
  113. ? ServiceField.number(
  114. autoscaling.minInstances,
  115. override?.minInstances
  116. )
  117. : ServiceField.number(1, undefined),
  118. maxInstances: autoscaling.maxInstances
  119. ? ServiceField.number(
  120. autoscaling.maxInstances,
  121. override?.maxInstances
  122. )
  123. : ServiceField.number(10, undefined),
  124. cpuThresholdPercent: autoscaling.cpuThresholdPercent
  125. ? ServiceField.number(
  126. autoscaling.cpuThresholdPercent,
  127. override?.cpuThresholdPercent
  128. )
  129. : ServiceField.number(50, undefined),
  130. memoryThresholdPercent: autoscaling.memoryThresholdPercent
  131. ? ServiceField.number(
  132. autoscaling.memoryThresholdPercent,
  133. override?.memoryThresholdPercent
  134. )
  135. : ServiceField.number(50, undefined),
  136. }
  137. : setDefaults
  138. ? {
  139. enabled: ServiceField.boolean(false, undefined),
  140. minInstances: ServiceField.number(1, undefined),
  141. maxInstances: ServiceField.number(10, undefined),
  142. cpuThresholdPercent: ServiceField.number(50, undefined),
  143. memoryThresholdPercent: ServiceField.number(50, undefined),
  144. }
  145. : undefined;
  146. }
  147. // Health Check
  148. export const healthcheckValidator = z.object({
  149. enabled: serviceBooleanValidator,
  150. httpPath: serviceStringValidator.optional(),
  151. });
  152. export type ClientHealthCheck = z.infer<typeof healthcheckValidator>;
  153. export type SerializedHealthcheck = {
  154. enabled: boolean;
  155. httpPath?: string;
  156. };
  157. export function serializeHealth({
  158. health,
  159. }: {
  160. health?: ClientHealthCheck;
  161. }): SerializedHealthcheck | undefined {
  162. return (
  163. health && {
  164. enabled: health.enabled.value,
  165. httpPath: health.httpPath?.value,
  166. }
  167. );
  168. }
  169. export function deserializeHealthCheck({
  170. health,
  171. override,
  172. setDefaults,
  173. }: {
  174. health?: SerializedHealthcheck;
  175. override?: SerializedHealthcheck;
  176. setDefaults: boolean;
  177. }): ClientHealthCheck | undefined {
  178. return health
  179. ? {
  180. enabled: ServiceField.boolean(health.enabled, override?.enabled),
  181. httpPath: health.httpPath
  182. ? ServiceField.string(health.httpPath, override?.httpPath)
  183. : ServiceField.string("", undefined),
  184. }
  185. : setDefaults
  186. ? {
  187. enabled: ServiceField.boolean(false, undefined),
  188. httpPath: ServiceField.string("", undefined),
  189. }
  190. : undefined;
  191. }
  192. // Domains
  193. export const domainsValidator = z.array(
  194. z.object({
  195. name: serviceStringValidator,
  196. })
  197. );
  198. export type ClientDomains = z.infer<typeof domainsValidator>;
  199. // Ingress Annotations
  200. export const ingressAnnotationsValidator = z.array(
  201. z.object({
  202. key: z.string(),
  203. value: z.string(),
  204. readOnly: z.boolean(),
  205. })
  206. );
  207. export type ClientIngressAnnotations = z.infer<
  208. typeof ingressAnnotationsValidator
  209. >;