benji-sdk 0.1.0 → 0.1.2

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.
Files changed (61) hide show
  1. package/README.md +41 -141
  2. package/dist/client/client/client.gen.d.ts +1 -1
  3. package/dist/client/client/client.gen.d.ts.map +1 -1
  4. package/dist/client/client/client.gen.js +46 -46
  5. package/dist/client/client/index.d.ts +8 -8
  6. package/dist/client/client/index.d.ts.map +1 -1
  7. package/dist/client/client/index.js +5 -5
  8. package/dist/client/client/types.gen.d.ts +18 -18
  9. package/dist/client/client/types.gen.d.ts.map +1 -1
  10. package/dist/client/client/utils.gen.d.ts +3 -3
  11. package/dist/client/client/utils.gen.d.ts.map +1 -1
  12. package/dist/client/client/utils.gen.js +34 -34
  13. package/dist/client/client.gen.d.ts +3 -3
  14. package/dist/client/client.gen.d.ts.map +1 -1
  15. package/dist/client/client.gen.js +2 -2
  16. package/dist/client/core/auth.gen.d.ts +3 -3
  17. package/dist/client/core/auth.gen.js +3 -3
  18. package/dist/client/core/bodySerializer.gen.d.ts +1 -1
  19. package/dist/client/core/bodySerializer.gen.d.ts.map +1 -1
  20. package/dist/client/core/bodySerializer.gen.js +3 -3
  21. package/dist/client/core/params.gen.d.ts +3 -3
  22. package/dist/client/core/params.gen.js +9 -9
  23. package/dist/client/core/pathSerializer.gen.d.ts +3 -3
  24. package/dist/client/core/pathSerializer.gen.d.ts.map +1 -1
  25. package/dist/client/core/pathSerializer.gen.js +36 -36
  26. package/dist/client/core/queryKeySerializer.gen.js +11 -11
  27. package/dist/client/core/serverSentEvents.gen.d.ts +3 -3
  28. package/dist/client/core/serverSentEvents.gen.d.ts.map +1 -1
  29. package/dist/client/core/serverSentEvents.gen.js +19 -19
  30. package/dist/client/core/types.gen.d.ts +4 -4
  31. package/dist/client/core/types.gen.d.ts.map +1 -1
  32. package/dist/client/core/utils.gen.d.ts +1 -1
  33. package/dist/client/core/utils.gen.d.ts.map +1 -1
  34. package/dist/client/core/utils.gen.js +17 -17
  35. package/dist/client/index.d.ts +2 -2
  36. package/dist/client/index.d.ts.map +1 -1
  37. package/dist/client/index.js +1 -1
  38. package/dist/client/sdk.gen.d.ts +1067 -157
  39. package/dist/client/sdk.gen.d.ts.map +1 -1
  40. package/dist/client/sdk.gen.js +2907 -769
  41. package/dist/client/types.gen.d.ts +10703 -4298
  42. package/dist/client/types.gen.d.ts.map +1 -1
  43. package/dist/env.d.ts +10 -0
  44. package/dist/env.d.ts.map +1 -0
  45. package/dist/env.js +18 -0
  46. package/dist/errors.d.ts +22 -0
  47. package/dist/errors.d.ts.map +1 -0
  48. package/dist/errors.js +21 -0
  49. package/dist/index.d.ts +8 -3
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +8 -3
  52. package/dist/method-metadata.gen.d.ts +2 -0
  53. package/dist/method-metadata.gen.d.ts.map +1 -0
  54. package/dist/method-metadata.gen.js +2 -0
  55. package/dist/methods.d.ts +27 -0
  56. package/dist/methods.d.ts.map +1 -0
  57. package/dist/methods.js +147 -0
  58. package/dist/wrapper.d.ts +20 -0
  59. package/dist/wrapper.d.ts.map +1 -0
  60. package/dist/wrapper.js +49 -0
  61. package/package.json +10 -6
package/dist/env.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Initialize the Benji SDK from environment variables.
3
+ *
4
+ * Reads `BENJI_API_KEY` (required) and `BENJI_BASE_URL` (optional) from
5
+ * the environment and calls `configure()`.
6
+ *
7
+ * @throws {BenjiConfigError} if BENJI_API_KEY is not set
8
+ */
9
+ export declare function initializeFromEnv(): void;
10
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CASxC"}
package/dist/env.js ADDED
@@ -0,0 +1,18 @@
1
+ import { configure } from "./index.js";
2
+ import { BenjiConfigError } from "./errors.js";
3
+ /**
4
+ * Initialize the Benji SDK from environment variables.
5
+ *
6
+ * Reads `BENJI_API_KEY` (required) and `BENJI_BASE_URL` (optional) from
7
+ * the environment and calls `configure()`.
8
+ *
9
+ * @throws {BenjiConfigError} if BENJI_API_KEY is not set
10
+ */
11
+ export function initializeFromEnv() {
12
+ const apiKey = process.env.BENJI_API_KEY;
13
+ if (!apiKey) {
14
+ throw new BenjiConfigError('BENJI_API_KEY environment variable is required. Get your API key from https://app.benji.so/settings');
15
+ }
16
+ const baseUrl = process.env.BENJI_BASE_URL;
17
+ configure({ apiKey, baseUrl });
18
+ }
@@ -0,0 +1,22 @@
1
+ export declare class BenjiError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare class BenjiConfigError extends BenjiError {
5
+ constructor(message: string);
6
+ }
7
+ export declare class BenjiApiError extends BenjiError {
8
+ readonly status: number;
9
+ readonly code: string;
10
+ readonly issues?: Array<{
11
+ message: string;
12
+ }>;
13
+ constructor(options: {
14
+ status: number;
15
+ code: string;
16
+ message: string;
17
+ issues?: Array<{
18
+ message: string;
19
+ }>;
20
+ });
21
+ }
22
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,gBAAiB,SAAQ,UAAU;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,aAAc,SAAQ,UAAU;IAC3C,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;gBAExC,OAAO,EAAE;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,KAAK,CAAC;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACrC;CAOF"}
package/dist/errors.js ADDED
@@ -0,0 +1,21 @@
1
+ export class BenjiError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = 'BenjiError';
5
+ }
6
+ }
7
+ export class BenjiConfigError extends BenjiError {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = 'BenjiConfigError';
11
+ }
12
+ }
13
+ export class BenjiApiError extends BenjiError {
14
+ constructor(options) {
15
+ super(options.message);
16
+ this.name = 'BenjiApiError';
17
+ this.status = options.status;
18
+ this.code = options.code;
19
+ this.issues = options.issues;
20
+ }
21
+ }
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- export * from "./client";
2
- import { client } from "./client/client.gen";
1
+ export * from "./client/index.js";
2
+ import { client } from "./client/client.gen.js";
3
3
  export interface BenjiConfig {
4
4
  /** Your Benji API key */
5
5
  apiKey: string;
6
- /** Optional custom base URL (defaults to https://app.benji.so/api/rest) */
6
+ /** Optional custom base URL (defaults to https://alpha.benji.so/api/rest) */
7
7
  baseUrl?: string;
8
8
  }
9
9
  /**
@@ -24,4 +24,9 @@ export interface BenjiConfig {
24
24
  */
25
25
  export declare function configure(options: BenjiConfig): void;
26
26
  export { client };
27
+ export { BenjiError, BenjiConfigError, BenjiApiError } from "./errors.js";
28
+ export { initializeFromEnv } from "./env.js";
29
+ export { callSdkMethod, listSdkMethods } from "./methods.js";
30
+ export type { SdkMethodDescriptor, SdkMethodOptions } from "./methods.js";
31
+ export { wrapSdkCall } from "./wrapper.js";
27
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AAGzB,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC1B,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,QAO7C;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAGlC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,QAO7C;AAED,OAAO,EAAE,MAAM,EAAE,CAAC;AAGlB,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC7D,YAAY,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // Re-export everything from generated client
2
- export * from "./client";
2
+ export * from "./client/index.js";
3
3
  // Import client config
4
- import { client } from "./client/client.gen";
4
+ import { client } from "./client/client.gen.js";
5
5
  /**
6
6
  * Configure the Benji SDK with your API key
7
7
  *
@@ -20,10 +20,15 @@ import { client } from "./client/client.gen";
20
20
  */
21
21
  export function configure(options) {
22
22
  client.setConfig({
23
- baseUrl: options.baseUrl ?? "https://app.benji.so/api/rest",
23
+ baseUrl: options.baseUrl ?? "https://alpha.benji.so/api/rest",
24
24
  headers: {
25
25
  "x-api-key": options.apiKey,
26
26
  },
27
27
  });
28
28
  }
29
29
  export { client };
30
+ // Error types and utilities
31
+ export { BenjiError, BenjiConfigError, BenjiApiError } from "./errors.js";
32
+ export { initializeFromEnv } from "./env.js";
33
+ export { callSdkMethod, listSdkMethods } from "./methods.js";
34
+ export { wrapSdkCall } from "./wrapper.js";
@@ -0,0 +1,2 @@
1
+ export declare const methodMetadata: {};
2
+ //# sourceMappingURL=method-metadata.gen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method-metadata.gen.d.ts","sourceRoot":"","sources":["../src/method-metadata.gen.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,IAAK,CAAC"}
@@ -0,0 +1,2 @@
1
+ // This file is auto-generated by generate-method-metadata.mjs
2
+ export const methodMetadata = {};
@@ -0,0 +1,27 @@
1
+ export interface SdkMethodOptions {
2
+ body?: unknown;
3
+ path?: Record<string, unknown>;
4
+ query?: Record<string, unknown>;
5
+ headers?: Record<string, string>;
6
+ [key: string]: unknown;
7
+ }
8
+ export interface SdkMethodDescriptor {
9
+ namespace: string;
10
+ method: string;
11
+ fullName: string;
12
+ resource: string;
13
+ action: string;
14
+ toolName: string;
15
+ operationId?: string;
16
+ summary?: string;
17
+ description?: string;
18
+ httpMethod?: string;
19
+ path?: string;
20
+ exampleInput?: Record<string, unknown>;
21
+ }
22
+ export declare function listSdkMethods(filters?: {
23
+ namespace?: string;
24
+ search?: string;
25
+ }): SdkMethodDescriptor[];
26
+ export declare function callSdkMethod<T = unknown>(methodName: string, options?: SdkMethodOptions): Promise<T>;
27
+ //# sourceMappingURL=methods.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxC;AAkKD,wBAAgB,cAAc,CAAC,OAAO,GAAE;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,GAAG,mBAAmB,EAAE,CAqB7B;AAED,wBAAsB,aAAa,CAAC,CAAC,GAAG,OAAO,EAC7C,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,CAAC,CAAC,CAwBZ"}
@@ -0,0 +1,147 @@
1
+ import * as generatedClient from "./client/index.js";
2
+ import { BenjiApiError } from "./errors.js";
3
+ import { methodMetadata } from "./method-metadata.gen.js";
4
+ import { wrapSdkCall } from "./wrapper.js";
5
+ const RESERVED_STATIC_PROPERTIES = new Set(["length", "name", "prototype"]);
6
+ const generatedMethodMetadata = methodMetadata;
7
+ let cachedDescriptors;
8
+ let cachedRegistry;
9
+ function toKebabCase(value) {
10
+ return value
11
+ .replace(/([a-z0-9])([A-Z])/g, "$1-$2")
12
+ .replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2")
13
+ .replace(/[_\s]+/g, "-")
14
+ .toLowerCase();
15
+ }
16
+ function toSnakeCase(value) {
17
+ return toKebabCase(value).replace(/-/g, "_");
18
+ }
19
+ function getCommonPrefix(values) {
20
+ if (values.length === 0) {
21
+ return "";
22
+ }
23
+ let prefix = values[0] ?? "";
24
+ for (const value of values.slice(1)) {
25
+ let index = 0;
26
+ while (index < prefix.length &&
27
+ index < value.length &&
28
+ prefix[index] === value[index]) {
29
+ index += 1;
30
+ }
31
+ prefix = prefix.slice(0, index);
32
+ if (!prefix) {
33
+ break;
34
+ }
35
+ }
36
+ return prefix;
37
+ }
38
+ function buildRegistry() {
39
+ const rawDescriptors = [];
40
+ const registry = new Map();
41
+ for (const [namespace, exportedValue] of Object.entries(generatedClient)) {
42
+ if (typeof exportedValue !== "function") {
43
+ continue;
44
+ }
45
+ const exportedRecord = exportedValue;
46
+ const staticMethods = Object.getOwnPropertyNames(exportedValue)
47
+ .filter((method) => !RESERVED_STATIC_PROPERTIES.has(method))
48
+ .filter((method) => typeof exportedRecord[method] === "function")
49
+ .sort();
50
+ if (staticMethods.length === 0) {
51
+ continue;
52
+ }
53
+ for (const method of staticMethods) {
54
+ const fullName = `${namespace}.${method}`;
55
+ const methodFn = exportedRecord[method];
56
+ registry.set(fullName, methodFn.bind(exportedValue));
57
+ rawDescriptors.push({ namespace, method, fullName });
58
+ }
59
+ }
60
+ const methodsByNamespace = new Map();
61
+ for (const descriptor of rawDescriptors) {
62
+ const methods = methodsByNamespace.get(descriptor.namespace) ?? [];
63
+ methods.push(descriptor.method);
64
+ methodsByNamespace.set(descriptor.namespace, methods);
65
+ }
66
+ const descriptors = rawDescriptors.map((descriptor) => {
67
+ const methods = methodsByNamespace.get(descriptor.namespace) ?? [];
68
+ const commonPrefix = getCommonPrefix(methods);
69
+ const resource = toKebabCase(descriptor.namespace);
70
+ const rawAction = descriptor.method.slice(commonPrefix.length) || descriptor.method;
71
+ const action = toKebabCase(rawAction);
72
+ return {
73
+ ...descriptor,
74
+ resource,
75
+ action,
76
+ toolName: `${toSnakeCase(resource)}_${toSnakeCase(action)}`,
77
+ ...(generatedMethodMetadata[descriptor.fullName] ?? {}),
78
+ };
79
+ });
80
+ descriptors.sort((left, right) => left.fullName.localeCompare(right.fullName));
81
+ return { descriptors, registry };
82
+ }
83
+ function ensureRegistry() {
84
+ if (cachedDescriptors && cachedRegistry) {
85
+ return;
86
+ }
87
+ const { descriptors, registry } = buildRegistry();
88
+ cachedDescriptors = descriptors;
89
+ cachedRegistry = registry;
90
+ }
91
+ function getDescriptors() {
92
+ ensureRegistry();
93
+ return cachedDescriptors ?? [];
94
+ }
95
+ function getRegistry() {
96
+ ensureRegistry();
97
+ return cachedRegistry ?? new Map();
98
+ }
99
+ function resolveMethodName(methodName) {
100
+ const registry = getRegistry();
101
+ if (registry.has(methodName)) {
102
+ return methodName;
103
+ }
104
+ const normalized = methodName.toLowerCase();
105
+ const descriptor = getDescriptors().find((entry) => entry.fullName.toLowerCase() === normalized);
106
+ if (descriptor) {
107
+ return descriptor.fullName;
108
+ }
109
+ throw new Error(`Unknown SDK method "${methodName}". Use listSdkMethods() to inspect the available generated methods.`);
110
+ }
111
+ export function listSdkMethods(filters = {}) {
112
+ const namespace = filters.namespace?.trim().toLowerCase();
113
+ const search = filters.search?.trim().toLowerCase();
114
+ return getDescriptors().filter((entry) => {
115
+ if (namespace && entry.namespace.toLowerCase() !== namespace) {
116
+ return false;
117
+ }
118
+ if (search &&
119
+ !entry.fullName.toLowerCase().includes(search) &&
120
+ !entry.method.toLowerCase().includes(search) &&
121
+ !entry.summary?.toLowerCase().includes(search) &&
122
+ !entry.description?.toLowerCase().includes(search)) {
123
+ return false;
124
+ }
125
+ return true;
126
+ });
127
+ }
128
+ export async function callSdkMethod(methodName, options = {}) {
129
+ const resolvedMethodName = resolveMethodName(methodName);
130
+ const method = getRegistry().get(resolvedMethodName);
131
+ if (!method) {
132
+ throw new Error(`SDK method "${resolvedMethodName}" is unavailable.`);
133
+ }
134
+ try {
135
+ const promise = method(options);
136
+ return await wrapSdkCall(promise);
137
+ }
138
+ catch (error) {
139
+ if (error instanceof BenjiApiError) {
140
+ throw error;
141
+ }
142
+ if (error instanceof Error) {
143
+ throw new Error(`Failed to call "${resolvedMethodName}": ${error.message}`);
144
+ }
145
+ throw error;
146
+ }
147
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Wraps an SDK call and normalizes errors into BenjiApiError.
3
+ *
4
+ * The @hey-api/openapi-ts client returns { data, error, response } in non-throw mode.
5
+ * This function extracts data on success or throws a BenjiApiError on failure.
6
+ * Network-level errors (DNS failure, connection refused, timeout) are also
7
+ * caught and wrapped as BenjiApiError with status 0.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const todos = await wrapSdkCall(Todos.todosList({ body: { screen: "today" } }));
12
+ * // todos is the data, or throws BenjiApiError
13
+ * ```
14
+ */
15
+ export declare function wrapSdkCall<T>(promise: Promise<{
16
+ data?: T;
17
+ error?: unknown;
18
+ response: Response;
19
+ }>): Promise<T>;
20
+ //# sourceMappingURL=wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper.d.ts","sourceRoot":"","sources":["../src/wrapper.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,OAAO,EAAE,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAC,GAClE,OAAO,CAAC,CAAC,CAAC,CAoCZ"}
@@ -0,0 +1,49 @@
1
+ import { BenjiApiError } from "./errors.js";
2
+ /**
3
+ * Wraps an SDK call and normalizes errors into BenjiApiError.
4
+ *
5
+ * The @hey-api/openapi-ts client returns { data, error, response } in non-throw mode.
6
+ * This function extracts data on success or throws a BenjiApiError on failure.
7
+ * Network-level errors (DNS failure, connection refused, timeout) are also
8
+ * caught and wrapped as BenjiApiError with status 0.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const todos = await wrapSdkCall(Todos.todosList({ body: { screen: "today" } }));
13
+ * // todos is the data, or throws BenjiApiError
14
+ * ```
15
+ */
16
+ export async function wrapSdkCall(promise) {
17
+ let result;
18
+ try {
19
+ result = await promise;
20
+ }
21
+ catch (networkError) {
22
+ const message = networkError instanceof Error
23
+ ? networkError.message
24
+ : "Network request failed";
25
+ throw new BenjiApiError({
26
+ status: 0,
27
+ code: "NETWORK_ERROR",
28
+ message,
29
+ });
30
+ }
31
+ if (result.error) {
32
+ const status = result.response?.status ?? 0;
33
+ const err = result.error;
34
+ throw new BenjiApiError({
35
+ status,
36
+ code: err.code ?? (status === 0 ? "NETWORK_ERROR" : `HTTP_${status}`),
37
+ message: err.message ?? (status === 0 ? "Network request failed" : `API request failed with status ${status}`),
38
+ issues: err.issues,
39
+ });
40
+ }
41
+ if (result.data === undefined) {
42
+ throw new BenjiApiError({
43
+ status: result.response.status,
44
+ code: "EMPTY_RESPONSE",
45
+ message: "API returned no data and no error",
46
+ });
47
+ }
48
+ return result.data;
49
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "benji-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Official TypeScript SDK for the Benji API - Your personal life operating system",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -8,8 +8,8 @@
8
8
  "types": "./dist/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
- "import": "./dist/index.js",
12
- "types": "./dist/index.d.ts"
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
13
  }
14
14
  },
15
15
  "files": [
@@ -17,7 +17,10 @@
17
17
  ],
18
18
  "scripts": {
19
19
  "generate": "openapi-ts",
20
- "build": "pnpm generate && tsc",
20
+ "generate-metadata": "node generate-method-metadata.mjs",
21
+ "fix-imports": "node fix-imports.mjs",
22
+ "build": "pnpm generate && pnpm generate-metadata && pnpm fix-imports && tsc",
23
+ "clean": "rm -rf dist",
21
24
  "prepublishOnly": "pnpm build"
22
25
  },
23
26
  "keywords": [
@@ -36,7 +39,8 @@
36
39
  "license": "MIT",
37
40
  "repository": {
38
41
  "type": "git",
39
- "url": "git+https://github.com/kitze/benji-sdk.git"
42
+ "url": "git+https://github.com/kitze/benji-sdk.git",
43
+ "directory": "packages/benji-sdk"
40
44
  },
41
45
  "bugs": {
42
46
  "url": "https://github.com/kitze/benji-sdk/issues"
@@ -46,4 +50,4 @@
46
50
  "@hey-api/openapi-ts": "0.90.0",
47
51
  "typescript": "^5.5.0"
48
52
  }
49
- }
53
+ }