Spaces:
Runtime error
Runtime error
File size: 3,880 Bytes
46252cd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | /**
* Type-level contract test for the engine-resource endpoints β `tsc` is the gate, which `npm test`
* runs ahead of vitest (`.test-d.ts` sits outside vitest's `test/**\/*.test.ts` include, so there is
* no suite to run here; the build tsconfigs exclude `test/`, so nothing else would check it).
*
* The status/label/channel routes hand the engine-neutral shapes from
* `src/engine/interfaces/whatsapp-engine.interface.ts` straight to the client β no DTO, no remap β
* so the record types below must mirror those shapes as JSON. Nothing else enforces that: the
* controllers declare no `@ApiResponse` type, so `openapi.json` carries no schema for these routes
* and `openapi:check` has nothing to diff, and the resource tests mock the transport and assert
* URLs only (#754).
*
* The `Wire*` types are the server interfaces as they arrive over JSON β `Date` fields serialize to
* ISO strings, everything else is verbatim. Keep them in sync with the engine interface by hand;
* `sdk-ci.yml` re-runs this job when that file changes.
* @packageDocumentation
*/
import type { CatalogInfo, ChannelMessageRecord, ChannelRecord, LabelRecord, StatusRecord } from '../src/types.js';
/** `Label` β `hexColor` is the only colour field the wire shape carries. */
interface WireLabel {
id: string;
name: string;
hexColor: string;
}
/**
* `Status` β `timestamp`/`expiresAt` are `Date` on the server and ISO strings once serialized.
* `mediaUrl`/`backgroundColor`/`font` are declared by the engine interface but no adapter populates
* them yet (wwjs `collectStatuses()` sets neither; Baileys throws `unsupported`), so they are
* optional here for forward-compatibility rather than because a response carries them today.
*/
interface WireStatus {
id: string;
contact: { id: string; name?: string; pushName?: string };
type: 'text' | 'image' | 'video';
caption?: string;
mediaUrl?: string;
backgroundColor?: string;
font?: number;
timestamp: string;
expiresAt: string;
}
/** `Channel` β `picture`/`createdAt` come from the Baileys `toChannel()` path; wwjs omits both. */
interface WireChannel {
id: string;
name: string;
description?: string;
inviteCode?: string;
subscriberCount?: number;
picture?: string;
verified?: boolean;
createdAt?: number;
}
/** `ChannelMessage` β the live engine payload, NOT the persisted `MessageRecord`. */
interface WireChannelMessage {
id: string;
body: string;
timestamp: number;
hasMedia: boolean;
mediaUrl?: string;
}
/** `Catalog` β the control: this pair already agreed before #754 and must stay agreeing. */
interface WireCatalog {
id: string;
name: string;
description?: string;
productCount: number;
url: string;
}
/**
* Resolves to `true` only when `Rec` is an honest view of `Wire`: it can hold every real response
* (so no field access that the server answers is a compile error), and it declares no field the
* server never sends (so no access silently evaluates to `undefined`). A mismatch resolves to a
* message tuple, which fails to accept `true` at the assertion site.
*/
type Mirrors<Wire, Rec> = Wire extends Rec
? [Exclude<keyof Wire, keyof Rec>] extends [never]
? [Exclude<keyof Rec, keyof Wire>] extends [never]
? true
: ['sdk declares fields the server never sends:', Exclude<keyof Rec, keyof Wire>]
: ['sdk omits fields the server sends:', Exclude<keyof Wire, keyof Rec>]
: ['sdk type cannot hold a real response:', Wire];
const label: Mirrors<WireLabel, LabelRecord> = true;
const status: Mirrors<WireStatus, StatusRecord> = true;
const channel: Mirrors<WireChannel, ChannelRecord> = true;
const channelMessage: Mirrors<WireChannelMessage, ChannelMessageRecord> = true;
const catalog: Mirrors<WireCatalog, CatalogInfo> = true;
export const contract = [label, status, channel, channelMessage, catalog];
|