flagon-io/g1t

public

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t/packages/contracts/src/result.ts

63 lines1,952 bytesCodeBlame
1/**
2 * Expected failures cross service boundaries as values, not exceptions:
3 * Worker RPC does not preserve error classes, and callers should have to
4 * handle them.
5 */
6export type FailureCode =
7 | "not_found"
8 | "forbidden"
9 | "unauthenticated"
10 | "conflict"
11 | "invalid"
12 /** The workspace has to pay before this can happen. */
13 | "payment_required"
14 /** Billing's refusals to start compute (`reserve`); each message says what to do. */
15 /** No plan, and no trial or pool that pays for this work: a card check or the g1t plan is needed. */
16 | "not_paid"
17 /** The workspace's one trial is spent. */
18 | "trial_used"
19 /** The spend limit or g1t's ceiling is reached. */
20 | "limit"
21 /** Compute is paused: a spend spike waiting for an owner, or a hold. */
22 | "paused"
23 /** This month's open-source pool, or the repository's share of it, is spent. */
24 | "oss_pool_empty"
25 /** A sensitive change needs a recent sign-in or the password again. */
26 | "reauth_required";
27
28export type Failure = { code: FailureCode; message: string };
29
30export type Result<T> = { ok: true; value: T } | { ok: false; error: Failure };
31
32export function ok<T>(value: T): Result<T> {
33 return { ok: true, value };
34}
35
36export function fail(code: FailureCode, message: string): Result<never> {
37 return { ok: false, error: { code, message } };
38}
39
40const HTTP_STATUS: Record<FailureCode, number> = {
41 not_found: 404,
42 forbidden: 403,
43 unauthenticated: 401,
44 conflict: 409,
45 invalid: 422,
46 payment_required: 402,
47 not_paid: 402,
48 trial_used: 402,
49 limit: 402,
50 paused: 409,
51 oss_pool_empty: 402,
52 reauth_required: 403,
53};
54
55export function httpStatus(failure: Failure): number {
56 return HTTP_STATUS[failure.code];
57}
58
59/** Returned when an account with an unconfirmed email tries to change something. */
60export const UNVERIFIED = fail(
61 "forbidden",
62 "Confirm your email address first. Check your inbox, or resend the link from the banner on g1t.sh.",
63);