mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-05-30 00:49:34 +00:00
Step 3d's last scaffolding piece before link generators. Three new
stream-extras schemas land alongside the network/security DUs:
- finalmask: TcpMask[] + UdpMask[] + QuicParams. Mask `settings` stays
record<string, unknown> for now — there are 13 UDP mask types and 3
TCP mask types with distinct per-type setting shapes, and modeling
them all as DUs would dwarf the rest of stream/ without buying
anything the shadow harness doesn't already catch. Tightened in
Step 6.
- sockopt: 17 socket-tuning knobs (TCP keepalive, TFO, mark, tproxy,
mptcp, dialer proxy, IPv6-only, congestion). `interfaceName` field
matches the panel class naming; serializers rename to `interface` on
the wire.
- external-proxy: rows ship per inbound describing edge fronts (CDN
mirrors). Used by link generators to fan out share URLs.
schemas/api/inbound.ts composes the top-level wire shape with
intersection-of-DUs:
StreamSettingsSchema = NetworkSettingsSchema
.and(SecuritySettingsSchema)
.and(StreamExtrasSchema)
InboundSchema = InboundCoreSchema.and(InboundSettingsSchema)
A fixture (vless-ws-tls.json) exercises the full shape — protocol DU,
network DU, security DU, and TLS cert file branch in one round trip.
The snapshot pins the canonical parsed form so the upcoming link
extractor consumes typed input with no class hierarchy underneath.
Suite: 65 tests across 7 files; typecheck + lint clean. Zod 4
intersection-of-DUs works.
32 lines
1.1 KiB
TypeScript
32 lines
1.1 KiB
TypeScript
/// <reference types="vite/client" />
|
|
import { describe, expect, it } from 'vitest';
|
|
|
|
import { InboundSchema } from '@/schemas/api/inbound';
|
|
|
|
// Full Inbound parse tests — exercises the intersection of network DU,
|
|
// security DU, settings DU, and orthogonal extras in a single
|
|
// round-trip. These fixtures are the input the link generators in
|
|
// lib/xray/inbound-link.ts will consume once extracted.
|
|
|
|
const fixtures = import.meta.glob<unknown>(
|
|
'./golden/fixtures/inbound-full/*.json',
|
|
{ eager: true, import: 'default' },
|
|
);
|
|
|
|
function fixtureName(path: string): string {
|
|
const file = path.split('/').pop() ?? path;
|
|
return file.replace(/\.json$/, '');
|
|
}
|
|
|
|
describe('InboundSchema (full) fixtures', () => {
|
|
const entries = Object.entries(fixtures).sort(([a], [b]) => a.localeCompare(b));
|
|
expect(entries.length, 'expected at least one fixture under golden/fixtures/inbound-full').toBeGreaterThan(0);
|
|
|
|
for (const [path, raw] of entries) {
|
|
it(`parses ${fixtureName(path)} byte-stably`, () => {
|
|
const parsed = InboundSchema.parse(raw);
|
|
expect(parsed).toMatchSnapshot();
|
|
});
|
|
}
|
|
});
|