|
| 1 | +/** |
| 2 | + * Example of a simple server-side operation that returns Result data model. |
| 3 | + * |
| 4 | + * In a real-world scenario, this could be part of a backend service |
| 5 | + * handling requests and returning structured responses. |
| 6 | + * |
| 7 | + * In this example, we show how to return both successful and error results |
| 8 | + * based on input conditions. |
| 9 | + */ |
| 10 | +import type { Address } from "viem"; |
| 11 | +import { zeroAddress } from "viem"; |
| 12 | + |
| 13 | +import type { AbstractResultOk } from "../result-base"; |
| 14 | +import { type AssertResultCodeExact, type ExpectTrue, ResultCodes } from "../result-code"; |
| 15 | +import { |
| 16 | + buildResultInternalServerError, |
| 17 | + buildResultInvalidRequest, |
| 18 | + type ResultInternalServerError, |
| 19 | + type ResultInvalidRequest, |
| 20 | +} from "../result-common"; |
| 21 | + |
| 22 | +export interface ResultExampleOpOkData { |
| 23 | + name: string; |
| 24 | +} |
| 25 | + |
| 26 | +export interface ResultExampleOpOk extends AbstractResultOk<ResultExampleOpOkData> {} |
| 27 | + |
| 28 | +export const buildResultExampleOpOk = (name: string): ResultExampleOpOk => { |
| 29 | + return { |
| 30 | + resultCode: ResultCodes.Ok, |
| 31 | + data: { |
| 32 | + name, |
| 33 | + }, |
| 34 | + }; |
| 35 | +}; |
| 36 | + |
| 37 | +// NOTE: Here we define a union of all possible results returned by the server for this operation. |
| 38 | +// We specifically call these "Server Results" because later we need to add all the possible client error results to get |
| 39 | +// the full set of all results a client can receive from this operation. |
| 40 | +export type ExampleOpServerResult = |
| 41 | + | ResultExampleOpOk |
| 42 | + | ResultInternalServerError |
| 43 | + | ResultInvalidRequest; |
| 44 | + |
| 45 | +export type ExampleOpServerResultCode = ExampleOpServerResult["resultCode"]; |
| 46 | + |
| 47 | +export const EXAMPLE_OP_RECOGNIZED_SERVER_RESULT_CODES = [ |
| 48 | + ResultCodes.Ok, |
| 49 | + ResultCodes.InternalServerError, |
| 50 | + ResultCodes.InvalidRequest, |
| 51 | +] as const satisfies readonly ExampleOpServerResultCode[]; |
| 52 | + |
| 53 | +// Intentionally unused: compile-time assertion that the recognized result codes |
| 54 | +// exactly match the union of ExampleOpServerResult["resultCode"]. |
| 55 | +type _AssertExampleOpServerResultCodesMatch = ExpectTrue< |
| 56 | + AssertResultCodeExact<ExampleOpServerResultCode, typeof EXAMPLE_OP_RECOGNIZED_SERVER_RESULT_CODES> |
| 57 | +>; |
| 58 | + |
| 59 | +export const exampleOp = (address: Address): ExampleOpServerResult => { |
| 60 | + if (address === zeroAddress) { |
| 61 | + return buildResultInvalidRequest("Address must not be the zero address"); |
| 62 | + } |
| 63 | + if (Math.random() < 0.5) { |
| 64 | + return buildResultExampleOpOk("example.eth"); |
| 65 | + } else { |
| 66 | + return buildResultInternalServerError( |
| 67 | + "Invariant violation: random number is not less than 0.5", |
| 68 | + ); |
| 69 | + } |
| 70 | +}; |
0 commit comments