@typeship-ax/mcp 0.6.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.
Files changed (73) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +43 -0
  3. package/api.json +5163 -0
  4. package/api.md +512 -0
  5. package/dist/core/http.d.ts +303 -0
  6. package/dist/core/http.d.ts.map +1 -0
  7. package/dist/core/http.js +770 -0
  8. package/dist/core/pagination.d.ts +51 -0
  9. package/dist/core/pagination.d.ts.map +1 -0
  10. package/dist/core/pagination.js +154 -0
  11. package/dist/dates.d.ts +33 -0
  12. package/dist/dates.d.ts.map +1 -0
  13. package/dist/dates.js +136 -0
  14. package/dist/errors.d.ts +81 -0
  15. package/dist/errors.d.ts.map +1 -0
  16. package/dist/errors.js +103 -0
  17. package/dist/index.d.ts +92 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +86 -0
  20. package/dist/mcp-protocol.d.ts +453 -0
  21. package/dist/mcp-protocol.d.ts.map +1 -0
  22. package/dist/mcp-protocol.js +1262 -0
  23. package/dist/mcp.d.ts +5 -0
  24. package/dist/mcp.d.ts.map +1 -0
  25. package/dist/mcp.js +449 -0
  26. package/dist/ops.d.ts +115 -0
  27. package/dist/ops.d.ts.map +1 -0
  28. package/dist/ops.js +79 -0
  29. package/dist/resources/account.d.ts +18 -0
  30. package/dist/resources/account.d.ts.map +1 -0
  31. package/dist/resources/account.js +26 -0
  32. package/dist/resources/api-keys.d.ts +37 -0
  33. package/dist/resources/api-keys.d.ts.map +1 -0
  34. package/dist/resources/api-keys.js +67 -0
  35. package/dist/resources/generate.d.ts +25 -0
  36. package/dist/resources/generate.d.ts.map +1 -0
  37. package/dist/resources/generate.js +41 -0
  38. package/dist/resources/generations.d.ts +31 -0
  39. package/dist/resources/generations.d.ts.map +1 -0
  40. package/dist/resources/generations.js +56 -0
  41. package/dist/resources/projects.d.ts +110 -0
  42. package/dist/resources/projects.d.ts.map +1 -0
  43. package/dist/resources/projects.js +220 -0
  44. package/dist/resources/spec-revisions.d.ts +47 -0
  45. package/dist/resources/spec-revisions.d.ts.map +1 -0
  46. package/dist/resources/spec-revisions.js +90 -0
  47. package/dist/schemas.d.ts +6 -0
  48. package/dist/schemas.d.ts.map +1 -0
  49. package/dist/schemas.js +88 -0
  50. package/dist/types.d.ts +759 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +37 -0
  53. package/dist/worker.d.ts +5 -0
  54. package/dist/worker.d.ts.map +1 -0
  55. package/dist/worker.js +12 -0
  56. package/package.json +45 -0
  57. package/src/core/http.ts +1008 -0
  58. package/src/core/pagination.ts +195 -0
  59. package/src/dates.ts +126 -0
  60. package/src/errors.ts +117 -0
  61. package/src/index.ts +153 -0
  62. package/src/mcp-protocol.ts +1451 -0
  63. package/src/mcp.ts +448 -0
  64. package/src/ops.ts +174 -0
  65. package/src/resources/account.ts +43 -0
  66. package/src/resources/api-keys.ts +105 -0
  67. package/src/resources/generate.ts +69 -0
  68. package/src/resources/generations.ts +100 -0
  69. package/src/resources/projects.ts +391 -0
  70. package/src/resources/spec-revisions.ts +150 -0
  71. package/src/schemas.ts +90 -0
  72. package/src/types.ts +825 -0
  73. package/src/worker.ts +13 -0
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Auto-pagination. Generated by typeship — https://typeship.dev
3
+ *
4
+ * List operations return a PagePromise: `await` it for one page (a typed
5
+ * ApiResult), or `for await` it to stream every item across every page.
6
+ */
7
+
8
+ import {
9
+ HttpCore,
10
+ type ApiResult,
11
+ type CoreRequest,
12
+ type ResponseMeta,
13
+ } from "./http.js";
14
+
15
+ export interface PageConfig {
16
+ style: "cursor" | "cursorFromLastId" | "page" | "offset";
17
+ /** Response field holding the item array ("data", "items", …). */
18
+ itemsField: string;
19
+ cursorParam?: string;
20
+ /** Dot-path into the response body ("next_cursor", "meta.next_cursor"). */
21
+ nextCursorField?: string;
22
+ hasMoreField?: string;
23
+ /** cursorFromLastId: item field whose value seeds the next request. */
24
+ idField?: string;
25
+ pageParam?: string;
26
+ offsetParam?: string;
27
+ limitParam?: string;
28
+ }
29
+
30
+ type FetchPage<Item, E> = (
31
+ query: Record<string, unknown>,
32
+ ) => Promise<ApiResult<Page<Item, E>, E>>;
33
+
34
+ export class Page<Item, E = unknown> {
35
+ private readonly fetchPage: FetchPage<Item, E>;
36
+ private readonly config: PageConfig;
37
+ private readonly params: Record<string, unknown>;
38
+ readonly body: unknown;
39
+ readonly response: ResponseMeta;
40
+
41
+ constructor(
42
+ fetchPage: FetchPage<Item, E>,
43
+ config: PageConfig,
44
+ params: Record<string, unknown>,
45
+ body: unknown,
46
+ response: ResponseMeta,
47
+ ) {
48
+ this.fetchPage = fetchPage;
49
+ this.config = config;
50
+ this.params = params;
51
+ this.body = body;
52
+ this.response = response;
53
+ }
54
+
55
+ get items(): Item[] {
56
+ const value = getPath(this.body, this.config.itemsField);
57
+ return Array.isArray(value) ? (value as Item[]) : [];
58
+ }
59
+
60
+ hasNextPage(): boolean {
61
+ return this.nextPageParams() !== null;
62
+ }
63
+
64
+ nextPageParams(): Record<string, unknown> | null {
65
+ const { config, params } = this;
66
+ const items = this.items;
67
+
68
+ if (config.hasMoreField !== undefined) {
69
+ const hasMore = getPath(this.body, config.hasMoreField);
70
+ if (hasMore === false) return null;
71
+ }
72
+
73
+ switch (config.style) {
74
+ case "cursor": {
75
+ const next = getPath(this.body, config.nextCursorField!);
76
+ if (next === undefined || next === null || next === "") return null;
77
+ return { ...params, [config.cursorParam!]: next };
78
+ }
79
+ case "cursorFromLastId": {
80
+ if (items.length === 0) return null;
81
+ const last = items[items.length - 1] as Record<string, unknown>;
82
+ const id = last?.[config.idField ?? "id"];
83
+ if (id === undefined || id === null) return null;
84
+ return { ...params, [config.cursorParam!]: id };
85
+ }
86
+ case "page": {
87
+ if (!this.looksLikeMore(items)) return null;
88
+ const current = Number(params[config.pageParam!] ?? 1);
89
+ return { ...params, [config.pageParam!]: current + 1 };
90
+ }
91
+ case "offset": {
92
+ if (!this.looksLikeMore(items)) return null;
93
+ const current = Number(params[config.offsetParam!] ?? 0);
94
+ return { ...params, [config.offsetParam!]: current + items.length };
95
+ }
96
+ }
97
+ }
98
+
99
+ /** Fetch the next page, or null when this is the last one. Throws the typed error on failure. */
100
+ async getNextPage(): Promise<Page<Item, E> | null> {
101
+ const next = this.nextPageParams();
102
+ if (next === null) return null;
103
+ const result = await this.fetchPage(next);
104
+ if (!result.ok) {
105
+ throw result.error instanceof Error ? result.error : new Error(String(result.error));
106
+ }
107
+ return result.data;
108
+ }
109
+
110
+ /** Iterate every item on this page and all following pages. */
111
+ async *[Symbol.asyncIterator](): AsyncIterator<Item, void, undefined> {
112
+ let page: Page<Item, E> | null = this;
113
+ while (page !== null) {
114
+ for (const item of page.items) yield item;
115
+ page = await page.getNextPage();
116
+ }
117
+ }
118
+
119
+ private looksLikeMore(items: Item[]): boolean {
120
+ if (items.length === 0) return false;
121
+ if (this.config.limitParam !== undefined) {
122
+ const limit = Number(this.params[this.config.limitParam]);
123
+ if (Number.isFinite(limit) && limit > 0) return items.length >= limit;
124
+ }
125
+ // Without a has_more signal or an explicit limit, an empty page is the
126
+ // only reliable stop condition.
127
+ return true;
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Awaitable (one page, as a typed ApiResult) and async-iterable (all items,
133
+ * all pages). Iteration throws the operation's typed error union on failure.
134
+ */
135
+ export class PagePromise<Item, E> implements PromiseLike<ApiResult<Page<Item, E>, E>>, AsyncIterable<Item> {
136
+ private readonly first: Promise<ApiResult<Page<Item, E>, E>>;
137
+ constructor(first: Promise<ApiResult<Page<Item, E>, E>>) {
138
+ this.first = first;
139
+ }
140
+
141
+ then<R1 = ApiResult<Page<Item, E>, E>, R2 = never>(
142
+ onfulfilled?: ((value: ApiResult<Page<Item, E>, E>) => R1 | PromiseLike<R1>) | null,
143
+ onrejected?: ((reason: unknown) => R2 | PromiseLike<R2>) | null,
144
+ ): Promise<R1 | R2> {
145
+ return this.first.then(onfulfilled, onrejected);
146
+ }
147
+
148
+ async *[Symbol.asyncIterator](): AsyncIterator<Item, void, undefined> {
149
+ const result = await this.first;
150
+ if (!result.ok) {
151
+ throw result.error instanceof Error ? result.error : new Error(String(result.error));
152
+ }
153
+ yield* result.data;
154
+ }
155
+ }
156
+
157
+ export function paginate<Item, E>(
158
+ core: HttpCore,
159
+ req: CoreRequest,
160
+ config: PageConfig,
161
+ ): PagePromise<Item, E> {
162
+ const isGraphql = req.graphqlField !== undefined;
163
+ const fetchPage: FetchPage<Item, E> = async (params) => {
164
+ const nextReq = isGraphql
165
+ ? {
166
+ ...req,
167
+ body: {
168
+ ...(req.body as Record<string, unknown>),
169
+ variables: { ...((req.body as { variables?: Record<string, unknown> })?.variables ?? {}), ...params },
170
+ },
171
+ }
172
+ : { ...req, query: params };
173
+ const result = await core.request<unknown, E>(nextReq);
174
+ if (!result.ok) return result;
175
+ const page = new Page<Item, E>(fetchPage, config, params, result.data, result.response);
176
+ return { ok: true, data: page, response: result.response };
177
+ };
178
+ const initial: Record<string, unknown> = {};
179
+ const seed = isGraphql
180
+ ? ((req.body as { variables?: Record<string, unknown> })?.variables ?? {})
181
+ : (req.query ?? {});
182
+ for (const [k, v] of Object.entries(seed)) {
183
+ if (v !== undefined) initial[k] = v;
184
+ }
185
+ return new PagePromise<Item, E>(fetchPage(initial));
186
+ }
187
+
188
+ function getPath(body: unknown, path: string): unknown {
189
+ let node: unknown = body;
190
+ for (const key of path.split(".")) {
191
+ if (typeof node !== "object" || node === null) return undefined;
192
+ node = (node as Record<string, unknown>)[key];
193
+ }
194
+ return node;
195
+ }
package/src/dates.ts ADDED
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Relative dates for date / date-time arguments. Generated by typeship — https://typeship.dev
3
+ *
4
+ * Agents rarely know "now" and often do know "a week ago", so date-shaped
5
+ * arguments of the CLI and the MCP server accept, besides an absolute
6
+ * ISO 8601 value, a relative form resolved here against the clock:
7
+ *
8
+ * now | today | yesterday | tomorrow
9
+ * -P7D, +PT1H signed ISO 8601 durations (negative = in the past)
10
+ * -7d, +2h, -1w signed shorthand: s m h d w mo y
11
+ * 7 days ago, in 2 weeks
12
+ *
13
+ * An unsigned duration ("7d", "P1D") is ambiguous and rejected with the two
14
+ * spellings that are not. Anything else passes through untouched; the API
15
+ * validates absolute values. Zero dependencies.
16
+ */
17
+
18
+ export type DateKind = "date" | "date-time";
19
+
20
+ const UNIT_MS: Record<string, number> = {
21
+ s: 1000, sec: 1000, second: 1000,
22
+ m: 60_000, min: 60_000, minute: 60_000,
23
+ h: 3_600_000, hr: 3_600_000, hour: 3_600_000,
24
+ d: 86_400_000, day: 86_400_000,
25
+ w: 604_800_000, wk: 604_800_000, week: 604_800_000,
26
+ };
27
+ const CALENDAR_UNITS = new Set(["mo", "month", "y", "yr", "year"]);
28
+
29
+ const HINT = "Use a signed form: -7d or -P7D for seven days ago, +7d or +P7D for seven days ahead; or an absolute ISO 8601 value.";
30
+
31
+ /** The forms a date-shaped argument accepts, for descriptions and help. */
32
+ export const RELATIVE_DATE_HINT = "Accepts ISO 8601 or a relative form: -P7D, -7d, 7 days ago, today, now.";
33
+
34
+ function shift(base: Date, amount: number, unit: string): Date {
35
+ const d = new Date(base.getTime());
36
+ if (CALENDAR_UNITS.has(unit)) {
37
+ if (unit.startsWith("y")) d.setUTCFullYear(d.getUTCFullYear() + amount);
38
+ else d.setUTCMonth(d.getUTCMonth() + amount);
39
+ return d;
40
+ }
41
+ return new Date(d.getTime() + amount * (UNIT_MS[unit] ?? 0));
42
+ }
43
+
44
+ function startOfUtcDay(d: Date): Date {
45
+ return new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
46
+ }
47
+
48
+ function format(d: Date, kind: DateKind): string {
49
+ return kind === "date" ? d.toISOString().slice(0, 10) : d.toISOString();
50
+ }
51
+
52
+ /** Apply a signed ISO 8601 duration (P1Y2M3W4DT5H6M7S) to a date. */
53
+ function applyIsoDuration(base: Date, sign: number, body: string): Date | null {
54
+ const m = /^P(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)W)?(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/i.exec(body);
55
+ if (!m || body.toUpperCase() === "P" || body.toUpperCase() === "PT") return null;
56
+ let d = new Date(base.getTime());
57
+ const [, y, mo, w, day, h, min, s] = m;
58
+ if (y) d = shift(d, sign * Number(y), "y");
59
+ if (mo) d = shift(d, sign * Number(mo), "mo");
60
+ if (w) d = shift(d, sign * Number(w), "w");
61
+ if (day) d = shift(d, sign * Number(day), "d");
62
+ if (h) d = shift(d, sign * Number(h), "h");
63
+ if (min) d = shift(d, sign * Number(min), "m");
64
+ if (s) d = new Date(d.getTime() + sign * Number(s) * 1000);
65
+ return d;
66
+ }
67
+
68
+ /**
69
+ * Resolve a relative date expression. `null` means "not a relative form,
70
+ * pass the value through"; `{ error }` means it looked relative but is
71
+ * ambiguous or malformed; `{ value }` is the absolute value in the
72
+ * argument's format (YYYY-MM-DD for date, ISO instant for date-time).
73
+ */
74
+ export function relativeDate(text: string, kind: DateKind, now: Date = new Date()): { value: string } | { error: string } | null {
75
+ const t = text.trim();
76
+ const lower = t.toLowerCase();
77
+ if (lower === "now") return { value: format(now, kind) };
78
+ if (lower === "today") return { value: format(kind === "date" ? now : startOfUtcDay(now), kind) };
79
+ if (lower === "yesterday") return { value: format(shift(kind === "date" ? now : startOfUtcDay(now), -1, "d"), kind) };
80
+ if (lower === "tomorrow") return { value: format(shift(kind === "date" ? now : startOfUtcDay(now), 1, "d"), kind) };
81
+
82
+ // Signed ISO 8601 duration: -P7D, +PT1H. Unsigned P7D is ambiguous.
83
+ const iso = /^([+-])?(P[\dYMWDTHS.]+)$/i.exec(t);
84
+ if (iso) {
85
+ const d = applyIsoDuration(now, iso[1] === "-" ? -1 : 1, iso[2]!);
86
+ if (!d) return null; // not a duration after all; let the API judge it
87
+ if (!iso[1]) return { error: "\"" + t + "\" does not say which direction. " + HINT };
88
+ return { value: format(d, kind) };
89
+ }
90
+
91
+ // Signed shorthand: -7d, +2h, -1w, -3mo, +1y. Unsigned is ambiguous.
92
+ const short = /^([+-])?(\d+)\s*(s|sec|seconds?|m|min|minutes?|h|hrs?|hours?|d|days?|w|wks?|weeks?|mo|months?|y|yrs?|years?)$/i.exec(t);
93
+ if (short) {
94
+ if (!short[1]) return { error: "\"" + t + "\" does not say which direction. " + HINT };
95
+ const unit = normalizeUnit(short[3]!);
96
+ return { value: format(shift(now, (short[1] === "-" ? -1 : 1) * Number(short[2]), unit), kind) };
97
+ }
98
+
99
+ // "7 days ago", "in 2 weeks", "2 hours from now".
100
+ const ago = /^(\d+)\s*(s|sec|seconds?|m|min|minutes?|h|hrs?|hours?|d|days?|w|wks?|weeks?|mo|months?|y|yrs?|years?)\s+ago$/i.exec(t);
101
+ if (ago) return { value: format(shift(now, -Number(ago[1]), normalizeUnit(ago[2]!)), kind) };
102
+ const ahead = /^(?:in\s+(\d+)\s*(s|sec|seconds?|m|min|minutes?|h|hrs?|hours?|d|days?|w|wks?|weeks?|mo|months?|y|yrs?|years?)|(\d+)\s*(s|sec|seconds?|m|min|minutes?|h|hrs?|hours?|d|days?|w|wks?|weeks?|mo|months?|y|yrs?|years?)\s+from\s+now)$/i.exec(t);
103
+ if (ahead) {
104
+ const n = Number(ahead[1] ?? ahead[3]);
105
+ const unit = normalizeUnit((ahead[2] ?? ahead[4])!);
106
+ return { value: format(shift(now, n, unit), kind) };
107
+ }
108
+ return null;
109
+ }
110
+
111
+ function normalizeUnit(raw: string): string {
112
+ const u = raw.toLowerCase();
113
+ if (u.startsWith("mo")) return "mo";
114
+ if (u.startsWith("y")) return "y";
115
+ if (u.startsWith("w")) return "w";
116
+ if (u.startsWith("d")) return "d";
117
+ if (u.startsWith("h")) return "h";
118
+ if (u === "m" || u.startsWith("mi")) return "m";
119
+ if (u.startsWith("s")) return "s";
120
+ return u;
121
+ }
122
+
123
+ /** The date kind a JSON Schema `format` names, or null. */
124
+ export function dateKindOf(format: unknown): DateKind | null {
125
+ return format === "date" ? "date" : format === "date-time" ? "date-time" : null;
126
+ }
package/src/errors.ts ADDED
@@ -0,0 +1,117 @@
1
+ // typeship — typed error classes.
2
+ // Generated by typeship — https://typeship.dev — do not edit by hand.
3
+
4
+ import { ApiError, type ResponseMeta } from "./core/http.js";
5
+ import type { ErrorModel } from "./types.js";
6
+
7
+ export { ApiError, GraphQLRequestError, TransportError, UnexpectedApiError, ValidationError, type Violation, unwrap } from "./core/http.js";
8
+
9
+ /**
10
+ * The request body, specification source, output selection, or package name is invalid.
11
+ * Raised for HTTP 400 responses.
12
+ */
13
+ export class BadRequestError extends ApiError<400, ErrorModel> {
14
+ constructor(body: ErrorModel, response: ResponseMeta) {
15
+ super("The request body, specification source, output selection, or package name is invalid.", 400, body, response);
16
+ }
17
+ }
18
+
19
+ /**
20
+ * Missing, invalid, expired, or revoked credentials.
21
+ * Raised for HTTP 401 responses.
22
+ */
23
+ export class UnauthorizedError extends ApiError<401, ErrorModel> {
24
+ constructor(body: ErrorModel, response: ResponseMeta) {
25
+ super("Missing, invalid, expired, or revoked credentials.", 401, body, response);
26
+ }
27
+ }
28
+
29
+ /**
30
+ * The credentials are valid but cannot act on the requested organization.
31
+ * Raised for HTTP 403 responses.
32
+ */
33
+ export class ForbiddenError extends ApiError<403, ErrorModel> {
34
+ constructor(body: ErrorModel, response: ResponseMeta) {
35
+ super("The credentials are valid but cannot act on the requested organization.", 403, body, response);
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Spec exceeds the 10MB limit.
41
+ * Raised for HTTP 413 responses.
42
+ */
43
+ export class PayloadTooLargeError extends ApiError<413, ErrorModel> {
44
+ constructor(body: ErrorModel, response: ResponseMeta) {
45
+ super("Spec exceeds the 10MB limit.", 413, body, response);
46
+ }
47
+ }
48
+
49
+ /**
50
+ * The spec could not be understood.
51
+ * Raised for HTTP 422 responses.
52
+ */
53
+ export class UnprocessableEntityError extends ApiError<422, ErrorModel> {
54
+ constructor(body: ErrorModel, response: ResponseMeta) {
55
+ super("The spec could not be understood.", 422, body, response);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Too many requests. Wait for Retry-After before retrying.
61
+ * Raised for HTTP 429 responses.
62
+ */
63
+ export class RateLimitedError extends ApiError<429, ErrorModel> {
64
+ constructor(body: ErrorModel, response: ResponseMeta) {
65
+ super("Too many requests. Wait for Retry-After before retrying.", 429, body, response);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Unexpected error.
71
+ * Raised for "default" responses.
72
+ */
73
+ export class ApiResponseError extends ApiError<number, ErrorModel> {
74
+ constructor(body: ErrorModel, response: ResponseMeta) {
75
+ super("Unexpected error.", response.status, body, response);
76
+ }
77
+ }
78
+
79
+ /**
80
+ * The plan does not include another project or the requested output configuration.
81
+ * Raised for HTTP 402 responses.
82
+ */
83
+ export class PaymentRequiredError extends ApiError<402, ErrorModel> {
84
+ constructor(body: ErrorModel, response: ResponseMeta) {
85
+ super("The plan does not include another project or the requested output configuration.", 402, body, response);
86
+ }
87
+ }
88
+
89
+ /**
90
+ * The Idempotency-Key was already used with different request parameters.
91
+ * Raised for HTTP 409 responses.
92
+ */
93
+ export class ConflictError extends ApiError<409, ErrorModel> {
94
+ constructor(body: ErrorModel, response: ResponseMeta) {
95
+ super("The Idempotency-Key was already used with different request parameters.", 409, body, response);
96
+ }
97
+ }
98
+
99
+ /**
100
+ * The original idempotent request is temporarily unavailable.
101
+ * Raised for HTTP 500 responses.
102
+ */
103
+ export class InternalServerError extends ApiError<500, ErrorModel> {
104
+ constructor(body: ErrorModel, response: ResponseMeta) {
105
+ super("The original idempotent request is temporarily unavailable.", 500, body, response);
106
+ }
107
+ }
108
+
109
+ /**
110
+ * No such resource in this account.
111
+ * Raised for HTTP 404 responses.
112
+ */
113
+ export class NotFoundError extends ApiError<404, ErrorModel> {
114
+ constructor(body: ErrorModel, response: ResponseMeta) {
115
+ super("No such resource in this account.", 404, body, response);
116
+ }
117
+ }
package/src/index.ts ADDED
@@ -0,0 +1,153 @@
1
+ // typeship — client entry point.
2
+ // Generated by typeship — https://typeship.dev — do not edit by hand.
3
+
4
+ import {
5
+ HttpCore,
6
+ formatDebugEvent,
7
+ type AuthValue,
8
+ type DebugEvent,
9
+ type RequestContext,
10
+ bearerAuth,
11
+ } from "./core/http.js";
12
+ import { DEFS, SCHEMAS } from "./schemas.js";
13
+
14
+ import { GenerateResource } from "./resources/generate.js";
15
+ import { ProjectsResource } from "./resources/projects.js";
16
+ import { GenerationsResource } from "./resources/generations.js";
17
+ import { SpecRevisionsResource } from "./resources/spec-revisions.js";
18
+ import { AccountResource } from "./resources/account.js";
19
+ import { ApiKeysResource } from "./resources/api-keys.js";
20
+
21
+ /** This package's version, also sent as the `User-Agent`. */
22
+ export const VERSION = "0.6.0";
23
+ const USER_AGENT = "@typeship-ax/mcp/0.6.0 (typeship)";
24
+
25
+ export interface ClientOptions {
26
+ /** Override the server URL. Default: `https://typeship.dev/api/v1` */
27
+ baseUrl?: string;
28
+ /**
29
+ * Sent as `Authorization: Bearer <token>`. Pass a callback for tokens that expire; it is resolved
30
+ * before every attempt.
31
+ */
32
+ bearerToken?: string | (() => string | Promise<string>);
33
+ /** Per-attempt timeout in milliseconds. Default: 30000. */
34
+ timeoutMs?: number;
35
+ /** Retries after the first attempt (retryable failures only). Default: 2. */
36
+ maxRetries?: number;
37
+ /** Custom fetch implementation (proxies, testing, instrumentation). */
38
+ fetch?: typeof fetch;
39
+ /** Headers sent with every request. */
40
+ defaultHeaders?: Record<string, string>;
41
+ /**
42
+ * Called before every attempt; mutate context.headers or context.url for logging, tracing, or
43
+ * custom auth.
44
+ */
45
+ onRequest?: (context: RequestContext) => void | Promise<void>;
46
+ /**
47
+ * Called after every HTTP response, before parsing and retries. Clone the response before reading
48
+ * its body.
49
+ */
50
+ onResponse?: (response: Response, context: RequestContext) => void | Promise<void>;
51
+ /**
52
+ * Called once per failed call, after retries, with the typed error about to be returned.
53
+ * Observability only.
54
+ */
55
+ onError?: (error: unknown, request: { method: string; path: string }) => void | Promise<void>;
56
+ /**
57
+ * One redacted line per attempt: true logs to console.error; a function receives the structured
58
+ * DebugEvent for your own logger. Also enabled by the TYPESHIP_DEBUG=1 env var. Never includes
59
+ * headers or bodies.
60
+ */
61
+ debug?: boolean | ((event: DebugEvent) => void);
62
+ /**
63
+ * Opt-in zero-dependency runtime validation of JSON bodies against the spec's schemas: true
64
+ * checks requests and responses and returns a ValidationError on mismatch (as the ApiResult
65
+ * error, never thrown); mode "warn" logs via console.warn and lets the call proceed. Catches spec
66
+ * drift the type system can't see.
67
+ */
68
+ validate?: boolean | { requests?: boolean; responses?: boolean; mode?: "throw" | "warn" };
69
+ }
70
+
71
+ /**
72
+ * typeship — v0.6.0
73
+ *
74
+ * Generate production SDKs, CLIs, and MCP servers from an OpenAPI or
75
+ * GraphQL spec, and keep every selected output current.
76
+ *
77
+ * Every operation but one requires an API key, created in the console and
78
+ * sent as `Authorization: Bearer ak_...`. A browser session is not a
79
+ * credential for this API. The exception is POST /generate, which works
80
+ * anonymously with the free plan's limits.
81
+ */
82
+ export class TypeshipClient {
83
+ readonly generate: GenerateResource;
84
+ readonly projects: ProjectsResource;
85
+ readonly generations: GenerationsResource;
86
+ readonly specRevisions: SpecRevisionsResource;
87
+ readonly account: AccountResource;
88
+ readonly apiKeys: ApiKeysResource;
89
+
90
+ constructor(options: ClientOptions = {}) {
91
+ // Identifies this package to the API (ignored by browsers, which
92
+ // control their own User-Agent); override via defaultHeaders.
93
+ const headers: Record<string, AuthValue> = { "User-Agent": USER_AGENT, ...options.defaultHeaders };
94
+ const debugOption = options.debug
95
+ ?? (typeof process !== "undefined" && process.env?.["TYPESHIP_DEBUG"] === "1");
96
+ const debug = typeof debugOption === "function"
97
+ ? debugOption
98
+ : debugOption === true
99
+ ? (event: DebugEvent) => console.error(formatDebugEvent("typeship", event))
100
+ : undefined;
101
+ const query: Record<string, AuthValue> = {};
102
+ if (options.bearerToken !== undefined) headers["Authorization"] = bearerAuth(options.bearerToken);
103
+ const v = options.validate;
104
+ const validate = v
105
+ ? {
106
+ requests: typeof v === "object" ? v.requests !== false : true,
107
+ responses: typeof v === "object" ? v.responses !== false : true,
108
+ mode: (typeof v === "object" && v.mode) || ("throw" as const),
109
+ }
110
+ : undefined;
111
+ const core = new HttpCore({
112
+ baseUrl: options.baseUrl ?? "https://typeship.dev/api/v1",
113
+ headers,
114
+ query,
115
+ fetch: options.fetch ?? fetch,
116
+ timeoutMs: options.timeoutMs ?? 30_000,
117
+ maxRetries: options.maxRetries ?? 2,
118
+ onRequest: options.onRequest,
119
+ onResponse: options.onResponse,
120
+ onError: options.onError,
121
+ debug,
122
+ validate,
123
+ schemas: validate ? SCHEMAS : undefined,
124
+ schemaDefs: validate ? DEFS : undefined,
125
+ });
126
+ this.generate = new GenerateResource(core);
127
+ this.projects = new ProjectsResource(core);
128
+ this.generations = new GenerationsResource(core);
129
+ this.specRevisions = new SpecRevisionsResource(core);
130
+ this.account = new AccountResource(core);
131
+ this.apiKeys = new ApiKeysResource(core);
132
+ }
133
+ }
134
+
135
+ export * from "./types.js";
136
+ export * from "./errors.js";
137
+ export {
138
+ formatDebugEvent,
139
+ type ApiResult,
140
+ type AuthValue,
141
+ type DebugEvent,
142
+ type RequestContext,
143
+ type RequestOptions,
144
+ type ResponseMeta,
145
+ } from "./core/http.js";
146
+ export { Page, PagePromise } from "./core/pagination.js";
147
+
148
+ export * from "./resources/generate.js";
149
+ export * from "./resources/projects.js";
150
+ export * from "./resources/generations.js";
151
+ export * from "./resources/spec-revisions.js";
152
+ export * from "./resources/account.js";
153
+ export * from "./resources/api-keys.js";