@adhd/apigen-errors 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { ERROR_CODES, type ApiErrorCode, HTTP_STATUS, GRPC_CODE, CLI_EXIT_CODE, MCP_ERROR_KIND, statusMaps, ApiError, type StreamingPhase, type BeforeFirstChunkError, type AfterFirstChunkError, type StreamingErrorCarrier, toStreamingError, isBeforeFirstChunk, isAfterFirstChunk, } from './lib/errors';
package/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=["invalid_argument","unauthenticated","permission_denied","not_found","internal"],r={invalid_argument:400,unauthenticated:401,permission_denied:403,not_found:404,internal:500},i={invalid_argument:"INVALID_ARGUMENT",unauthenticated:"UNAUTHENTICATED",permission_denied:"PERMISSION_DENIED",not_found:"NOT_FOUND",internal:"INTERNAL"},s={invalid_argument:2,unauthenticated:3,permission_denied:3,not_found:4,internal:1},o={invalid_argument:"error",unauthenticated:"error",permission_denied:"error",not_found:"error",internal:"error"},d={http:r,grpc:i,cli:s,mcp:o};class _ extends Error{constructor(e,n,a){super(n),this.name="ApiError",this.code=e,this.details=a,Object.setPrototypeOf(this,new.target.prototype)}toJSON(){const e={code:this.code,message:this.message};return this.details!==void 0&&(e.details=this.details),e}}function c(t,e,n=0){return t==="before-first-chunk"?{phase:t,error:e}:{phase:t,error:e,chunksDelivered:n}}function E(t){return t.phase==="before-first-chunk"}function f(t){return t.phase==="after-first-chunk"}exports.ApiError=_;exports.CLI_EXIT_CODE=s;exports.ERROR_CODES=u;exports.GRPC_CODE=i;exports.HTTP_STATUS=r;exports.MCP_ERROR_KIND=o;exports.isAfterFirstChunk=f;exports.isBeforeFirstChunk=E;exports.statusMaps=d;exports.toStreamingError=c;
package/index.mjs ADDED
@@ -0,0 +1,70 @@
1
+ const u = [
2
+ "invalid_argument",
3
+ "unauthenticated",
4
+ "permission_denied",
5
+ "not_found",
6
+ "internal"
7
+ ], i = {
8
+ invalid_argument: 400,
9
+ unauthenticated: 401,
10
+ permission_denied: 403,
11
+ not_found: 404,
12
+ internal: 500
13
+ }, o = {
14
+ invalid_argument: "INVALID_ARGUMENT",
15
+ unauthenticated: "UNAUTHENTICATED",
16
+ permission_denied: "PERMISSION_DENIED",
17
+ not_found: "NOT_FOUND",
18
+ internal: "INTERNAL"
19
+ }, s = {
20
+ invalid_argument: 2,
21
+ unauthenticated: 3,
22
+ permission_denied: 3,
23
+ not_found: 4,
24
+ internal: 1
25
+ }, a = {
26
+ invalid_argument: "error",
27
+ unauthenticated: "error",
28
+ permission_denied: "error",
29
+ not_found: "error",
30
+ internal: "error"
31
+ }, d = {
32
+ http: i,
33
+ grpc: o,
34
+ cli: s,
35
+ mcp: a
36
+ };
37
+ class c extends Error {
38
+ constructor(n, e, r) {
39
+ super(e), this.name = "ApiError", this.code = n, this.details = r, Object.setPrototypeOf(this, new.target.prototype);
40
+ }
41
+ /** Serialise to a plain object suitable for JSON transport. */
42
+ toJSON() {
43
+ const n = {
44
+ code: this.code,
45
+ message: this.message
46
+ };
47
+ return this.details !== void 0 && (n.details = this.details), n;
48
+ }
49
+ }
50
+ function _(t, n, e = 0) {
51
+ return t === "before-first-chunk" ? { phase: t, error: n } : { phase: t, error: n, chunksDelivered: e };
52
+ }
53
+ function f(t) {
54
+ return t.phase === "before-first-chunk";
55
+ }
56
+ function h(t) {
57
+ return t.phase === "after-first-chunk";
58
+ }
59
+ export {
60
+ c as ApiError,
61
+ s as CLI_EXIT_CODE,
62
+ u as ERROR_CODES,
63
+ o as GRPC_CODE,
64
+ i as HTTP_STATUS,
65
+ a as MCP_ERROR_KIND,
66
+ h as isAfterFirstChunk,
67
+ f as isBeforeFirstChunk,
68
+ d as statusMaps,
69
+ _ as toStreamingError
70
+ };
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @adhd/apigen-errors
3
+ *
4
+ * Canonical error taxonomy for apigen — §9.1 of the apigen SPEC.
5
+ *
6
+ * Exports:
7
+ * - `ApiErrorCode` — the gRPC-style canonical code set (string union + const object)
8
+ * - `ApiError` — the thrown error class carrying code + message + details
9
+ * - `HTTP_STATUS` — code → HTTP status code map
10
+ * - `GRPC_CODE` — code → gRPC status code name map
11
+ * - `CLI_EXIT_CODE` — code → CLI process exit code map
12
+ * - `MCP_ERROR_KIND` — code → MCP error shape indicator ('error')
13
+ * - `statusMaps` — convenience bundle of all four maps
14
+ * - `StreamingPhase` — 'before-first-chunk' | 'after-first-chunk' discriminant
15
+ * - `StreamingErrorCarrier` — discriminated union: how an in-flight stream delivers a terminal error
16
+ * - `toStreamingError` — factory that wraps an ApiError into the correct carrier for the phase
17
+ */
18
+ /** The five gRPC-style canonical error codes recognised by apigen. */
19
+ export declare const ERROR_CODES: readonly ["invalid_argument", "unauthenticated", "permission_denied", "not_found", "internal"];
20
+ /** String-union type for the canonical error codes. */
21
+ export type ApiErrorCode = (typeof ERROR_CODES)[number];
22
+ /** Maps each canonical code to its HTTP status code. */
23
+ export declare const HTTP_STATUS: Record<ApiErrorCode, number>;
24
+ /** Maps each canonical code to its gRPC status name. */
25
+ export declare const GRPC_CODE: Record<ApiErrorCode, string>;
26
+ /** Maps each canonical code to its CLI process exit code. */
27
+ export declare const CLI_EXIT_CODE: Record<ApiErrorCode, number>;
28
+ /**
29
+ * MCP surfaces all apigen errors as the MCP `error` result kind.
30
+ * Maps each canonical code to the MCP error shape indicator.
31
+ */
32
+ export declare const MCP_ERROR_KIND: Record<ApiErrorCode, 'error'>;
33
+ /** Convenience bundle: all four transport maps keyed by transport name. */
34
+ export declare const statusMaps: {
35
+ readonly http: Record<"invalid_argument" | "unauthenticated" | "permission_denied" | "not_found" | "internal", number>;
36
+ readonly grpc: Record<"invalid_argument" | "unauthenticated" | "permission_denied" | "not_found" | "internal", string>;
37
+ readonly cli: Record<"invalid_argument" | "unauthenticated" | "permission_denied" | "not_found" | "internal", number>;
38
+ readonly mcp: Record<"invalid_argument" | "unauthenticated" | "permission_denied" | "not_found" | "internal", "error">;
39
+ };
40
+ /**
41
+ * The canonical apigen error. Every transport adapter catches this and maps
42
+ * `code` to the native status using the tables above.
43
+ */
44
+ export declare class ApiError extends Error {
45
+ /** gRPC-style canonical error code. */
46
+ readonly code: ApiErrorCode;
47
+ /** Optional structured details (passed through to MCP / HTTP body). */
48
+ readonly details?: unknown;
49
+ constructor(code: ApiErrorCode, message: string, details?: unknown);
50
+ /** Serialise to a plain object suitable for JSON transport. */
51
+ toJSON(): {
52
+ code: ApiErrorCode;
53
+ message: string;
54
+ details?: unknown;
55
+ };
56
+ }
57
+ /**
58
+ * Discriminant that records whether the first chunk was already flushed.
59
+ * Determines the carrier shape used to deliver a terminal stream error.
60
+ */
61
+ export type StreamingPhase = 'before-first-chunk' | 'after-first-chunk';
62
+ /**
63
+ * Carrier for a terminal streaming error **before** the first chunk was sent.
64
+ * Adapters handle this identically to a normal (non-streaming) §9 error.
65
+ */
66
+ export interface BeforeFirstChunkError {
67
+ readonly phase: 'before-first-chunk';
68
+ /** The underlying canonical error. */
69
+ readonly error: ApiError;
70
+ }
71
+ /**
72
+ * Carrier for a terminal streaming error **after** the first chunk was flushed.
73
+ * The status line is already gone; error must be delivered in-band per transport:
74
+ *
75
+ * | Transport | Mechanism |
76
+ * |------------------|------------------------------------------------------|
77
+ * | HTTP SSE/chunked | terminal `event: error` frame carrying the ApiError |
78
+ * | gRPC | trailing status (native gRPC trailers) |
79
+ * | MCP | progressive error notification |
80
+ * | CLI | flush partial stdout, write ApiError to stderr, exit |
81
+ */
82
+ export interface AfterFirstChunkError {
83
+ readonly phase: 'after-first-chunk';
84
+ /** The underlying canonical error, to be delivered in-band. */
85
+ readonly error: ApiError;
86
+ /**
87
+ * The number of chunks successfully delivered before the error occurred.
88
+ * Informational — lets CLI adapters decide whether stdout has content.
89
+ */
90
+ readonly chunksDelivered: number;
91
+ }
92
+ /** Discriminated union of the two streaming error carrier shapes. */
93
+ export type StreamingErrorCarrier = BeforeFirstChunkError | AfterFirstChunkError;
94
+ /**
95
+ * Factory: wrap an `ApiError` in the appropriate streaming carrier.
96
+ *
97
+ * @param phase - whether the first chunk was already flushed
98
+ * @param error - the terminal error
99
+ * @param chunksDelivered - (after-first-chunk only) chunks sent before failure
100
+ */
101
+ export declare function toStreamingError(phase: 'before-first-chunk', error: ApiError): BeforeFirstChunkError;
102
+ export declare function toStreamingError(phase: 'after-first-chunk', error: ApiError, chunksDelivered: number): AfterFirstChunkError;
103
+ /**
104
+ * Type guard: narrows a `StreamingErrorCarrier` to `BeforeFirstChunkError`.
105
+ */
106
+ export declare function isBeforeFirstChunk(c: StreamingErrorCarrier): c is BeforeFirstChunkError;
107
+ /**
108
+ * Type guard: narrows a `StreamingErrorCarrier` to `AfterFirstChunkError`.
109
+ */
110
+ export declare function isAfterFirstChunk(c: StreamingErrorCarrier): c is AfterFirstChunkError;
package/package.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "@adhd/apigen-errors",
3
+ "version": "0.1.0",
4
+ "main": "./index.js",
5
+ "module": "./index.mjs",
6
+ "typings": "./index.d.ts",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ }
10
+ }