inbound-form.ts 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { z } from 'zod';
  2. import { PortSchema, SniffingSchema } from '@/schemas/primitives';
  3. import { InboundSettingsSchema } from '@/schemas/protocols/inbound';
  4. import { SecuritySettingsSchema } from '@/schemas/protocols/security';
  5. import { NetworkSettingsSchema, StreamExtrasSchema } from '@/schemas/protocols/stream';
  6. // InboundFormValues = the values shape Form.useForm<T>() carries in
  7. // InboundFormModal. Mirrors the wire shape (so submission can hand
  8. // values straight to Schema.parse + POST) plus the DB-side fields that
  9. // the panel's /panel/api/inbounds/add endpoint expects alongside.
  10. //
  11. // Differences from schemas/api/inbound.ts InboundSchema:
  12. // - settings/streamSettings/sniffing are nested OBJECTS here, not the
  13. // JSON strings the endpoint accepts. The form holds typed data; the
  14. // submit handler stringifies right before POSTing.
  15. // - Adds DB fields not in InboundSchema: up, down, total, trafficReset,
  16. // lastTrafficResetTime, nodeId. These flow through the DBInbound row,
  17. // not the xray-config slice.
  18. export const InboundStreamFormSchema = NetworkSettingsSchema
  19. .and(SecuritySettingsSchema)
  20. .and(StreamExtrasSchema);
  21. export type InboundStreamFormValues = z.infer<typeof InboundStreamFormSchema>;
  22. export const TrafficResetSchema = z.enum(['never', 'hourly', 'daily', 'weekly', 'monthly']);
  23. export type TrafficReset = z.infer<typeof TrafficResetSchema>;
  24. // Db-side fields layered on top of the xray slice. These mirror the
  25. // DBInbound model — they live in the SQL row, not in xray's config.
  26. export const InboundDbFieldsSchema = z.object({
  27. up: z.number().int().min(0).default(0),
  28. down: z.number().int().min(0).default(0),
  29. total: z.number().int().min(0).default(0),
  30. trafficReset: TrafficResetSchema.default('never'),
  31. lastTrafficResetTime: z.number().int().default(0),
  32. nodeId: z.number().int().nullable().optional(),
  33. });
  34. export type InboundDbFields = z.infer<typeof InboundDbFieldsSchema>;
  35. // Base fields that apply to every inbound regardless of protocol or
  36. // transport. The protocol-specific `settings` and the transport-specific
  37. // `streamSettings` are layered on via intersection below.
  38. export const InboundFormBaseSchema = z.object({
  39. remark: z.string().default(''),
  40. enable: z.boolean().default(true),
  41. port: PortSchema,
  42. listen: z.string().default(''),
  43. tag: z.string().default(''),
  44. expiryTime: z.number().int().default(0),
  45. clientStats: z.string().optional(),
  46. sniffing: SniffingSchema.default({
  47. enabled: false,
  48. destOverride: ['http', 'tls', 'quic', 'fakedns'],
  49. metadataOnly: false,
  50. routeOnly: false,
  51. ipsExcluded: [],
  52. domainsExcluded: [],
  53. }),
  54. streamSettings: InboundStreamFormSchema.optional(),
  55. });
  56. export type InboundFormBase = z.infer<typeof InboundFormBaseSchema>;
  57. // Full form values = base + db fields + protocol-discriminated settings.
  58. // Consumers narrow on `.protocol` to access the matching settings branch.
  59. export const InboundFormSchema = InboundFormBaseSchema
  60. .and(InboundDbFieldsSchema)
  61. .and(InboundSettingsSchema);
  62. export type InboundFormValues = z.infer<typeof InboundFormSchema>;
  63. // Fallback rows ride alongside the inbound submission for VLESS/Trojan
  64. // hosts. They're saved via a separate endpoint after the main inbound
  65. // POST returns, so the schema lives here but is not part of the wire
  66. // inbound payload.
  67. export const FallbackRowSchema = z.object({
  68. rowKey: z.string(),
  69. childId: z.number().int().nullable(),
  70. name: z.string().default(''),
  71. alpn: z.string().default(''),
  72. path: z.string().default(''),
  73. xver: z.number().int().min(0).max(2).default(0),
  74. });
  75. export type FallbackRow = z.infer<typeof FallbackRowSchema>;