@typeship-ax/cli 0.8.0 → 0.10.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 (106) hide show
  1. package/AGENTS.md +31 -0
  2. package/README.md +26 -9
  3. package/api.json +3509 -800
  4. package/api.md +444 -494
  5. package/dist/api-identity.d.ts +40 -0
  6. package/dist/api-identity.d.ts.map +1 -0
  7. package/dist/api-identity.js +128 -0
  8. package/dist/auth-profiles.d.ts +30 -0
  9. package/dist/auth-profiles.d.ts.map +1 -0
  10. package/dist/auth-profiles.js +138 -0
  11. package/dist/cli.js +522 -355
  12. package/dist/console-login-check.d.ts +21 -0
  13. package/dist/console-login-check.d.ts.map +1 -0
  14. package/dist/console-login-check.js +107 -0
  15. package/dist/console-login-contract.d.ts +45 -0
  16. package/dist/console-login-contract.d.ts.map +1 -0
  17. package/dist/console-login-contract.js +40 -0
  18. package/dist/core/http.d.ts +17 -2
  19. package/dist/core/http.d.ts.map +1 -1
  20. package/dist/core/http.js +78 -17
  21. package/dist/credential-storage.d.ts +24 -0
  22. package/dist/credential-storage.d.ts.map +1 -0
  23. package/dist/credential-storage.js +207 -0
  24. package/dist/docs.d.ts +25 -0
  25. package/dist/docs.d.ts.map +1 -1
  26. package/dist/docs.js +144 -0
  27. package/dist/errors.d.ts +18 -10
  28. package/dist/errors.d.ts.map +1 -1
  29. package/dist/errors.js +24 -14
  30. package/dist/index.d.ts +10 -3
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +20 -4
  33. package/dist/named-credentials.d.ts +21 -0
  34. package/dist/named-credentials.d.ts.map +1 -0
  35. package/dist/named-credentials.js +86 -0
  36. package/dist/oauth-login.d.ts +39 -0
  37. package/dist/oauth-login.d.ts.map +1 -0
  38. package/dist/oauth-login.js +171 -0
  39. package/dist/oauth-request.d.ts +21 -0
  40. package/dist/oauth-request.d.ts.map +1 -0
  41. package/dist/oauth-request.js +119 -0
  42. package/dist/oauth-session.d.ts +106 -0
  43. package/dist/oauth-session.d.ts.map +1 -0
  44. package/dist/oauth-session.js +244 -0
  45. package/dist/ops.d.ts +14 -1
  46. package/dist/ops.d.ts.map +1 -1
  47. package/dist/ops.js +34 -30
  48. package/dist/polling-login.d.ts +57 -0
  49. package/dist/polling-login.d.ts.map +1 -0
  50. package/dist/polling-login.js +204 -0
  51. package/dist/resources/account.d.ts +2 -2
  52. package/dist/resources/account.d.ts.map +1 -1
  53. package/dist/resources/account.js +1 -0
  54. package/dist/resources/api-keys.d.ts +3 -3
  55. package/dist/resources/api-keys.d.ts.map +1 -1
  56. package/dist/resources/api-keys.js +2 -0
  57. package/dist/resources/definition-revisions.d.ts +5 -5
  58. package/dist/resources/definition-revisions.d.ts.map +1 -1
  59. package/dist/resources/definition-revisions.js +4 -0
  60. package/dist/resources/definitions.d.ts +15 -4
  61. package/dist/resources/definitions.d.ts.map +1 -1
  62. package/dist/resources/definitions.js +11 -2
  63. package/dist/resources/generate.d.ts +14 -3
  64. package/dist/resources/generate.d.ts.map +1 -1
  65. package/dist/resources/generate.js +10 -2
  66. package/dist/resources/generations.d.ts +3 -3
  67. package/dist/resources/generations.d.ts.map +1 -1
  68. package/dist/resources/generations.js +2 -0
  69. package/dist/resources/projects.d.ts +56 -20
  70. package/dist/resources/projects.d.ts.map +1 -1
  71. package/dist/resources/projects.js +40 -4
  72. package/dist/resources/targets.d.ts +84 -10
  73. package/dist/resources/targets.d.ts.map +1 -1
  74. package/dist/resources/targets.js +127 -2
  75. package/dist/schemas.d.ts.map +1 -1
  76. package/dist/schemas.js +55 -26
  77. package/dist/types.d.ts +602 -123
  78. package/dist/types.d.ts.map +1 -1
  79. package/dist/types.js +24 -0
  80. package/package.json +2 -1
  81. package/src/api-identity.ts +98 -0
  82. package/src/auth-profiles.ts +114 -0
  83. package/src/cli.ts +444 -332
  84. package/src/console-login-check.ts +88 -0
  85. package/src/console-login-contract.ts +65 -0
  86. package/src/core/http.ts +88 -19
  87. package/src/credential-storage.ts +183 -0
  88. package/src/docs.ts +138 -0
  89. package/src/errors.ts +26 -15
  90. package/src/index.ts +29 -4
  91. package/src/named-credentials.ts +74 -0
  92. package/src/oauth-login.ts +184 -0
  93. package/src/oauth-request.ts +90 -0
  94. package/src/oauth-session.ts +258 -0
  95. package/src/ops.ts +48 -31
  96. package/src/polling-login.ts +165 -0
  97. package/src/resources/account.ts +3 -0
  98. package/src/resources/api-keys.ts +5 -0
  99. package/src/resources/definition-revisions.ts +9 -0
  100. package/src/resources/definitions.ts +25 -0
  101. package/src/resources/generate.ts +23 -0
  102. package/src/resources/generations.ts +5 -0
  103. package/src/resources/projects.ts +95 -7
  104. package/src/resources/targets.ts +241 -0
  105. package/src/schemas.ts +55 -26
  106. package/src/types.ts +640 -123
@@ -0,0 +1,207 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { createCipheriv, createDecipheriv, createHash, randomBytes, timingSafeEqual } from "node:crypto";
3
+ import { existsSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
4
+ import { join, resolve } from "node:path";
5
+ import { FileCredentialStore, CredentialStorageError } from "./oauth-session.js";
6
+ const nativeCommand = (executable, args, input) => {
7
+ const result = spawnSync(executable, args, { input, encoding: "utf8", timeout: 15_000, maxBuffer: 64 * 1024, windowsHide: true, shell: false });
8
+ return { status: result.status, stdout: result.stdout ?? "", stderr: result.stderr ?? "", ...(result.error ? { error: result.error } : {}) };
9
+ };
10
+ function unavailable(name, environmentName) {
11
+ throw new CredentialStorageError("Cannot access " + name + ". Unlock or enable your OS credential store and retry. For a headless session, supply credentials through environment variables. Plaintext storage requires explicitly setting " + environmentName + "=file.");
12
+ }
13
+ function parseKey(value) {
14
+ const encoded = value.trim();
15
+ if (!/^[A-Za-z0-9+/]{43}=$/.test(encoded))
16
+ throw new CredentialStorageError("The OS credential key is invalid. Restore access to the original key before using the saved session.");
17
+ const key = Buffer.from(encoded, "base64");
18
+ if (key.length !== 32)
19
+ throw new CredentialStorageError("The OS credential key is invalid.");
20
+ return key;
21
+ }
22
+ /** A small wrapping key avoids OS item-size limits; session files are encrypted
23
+ * separately so refresh rotation can retain the atomic file/lock transaction. */
24
+ export function nativeCredentialKeyStore(path, platform = process.platform, run = nativeCommand, environmentName = "CREDENTIAL_STORE") {
25
+ const failed = (name) => unavailable(name, environmentName);
26
+ const identity = createHash("sha256").update(resolve(path)).digest("hex");
27
+ const service = "typeship.credentials." + identity;
28
+ const account = "session-key";
29
+ if (platform === "darwin") {
30
+ const name = "macOS Keychain";
31
+ const lookup = () => run("/usr/bin/security", ["find-generic-password", "-s", service, "-a", account, "-w"]);
32
+ return {
33
+ name,
34
+ read() {
35
+ const result = lookup();
36
+ if (!result.error && result.status === 44)
37
+ return null; // errSecItemNotFound
38
+ if (result.error || result.status !== 0)
39
+ return failed(name);
40
+ return parseKey(result.stdout);
41
+ },
42
+ write(key) {
43
+ // security's interactive command stream keeps the key off argv. All
44
+ // tokens below have a fixed safe alphabet; no shell or user text is run.
45
+ const input = "add-generic-password -U -s " + service + " -a " + account + " -w " + key.toString("base64") + "\n";
46
+ const result = run("/usr/bin/security", ["-i"], input);
47
+ if (result.error || result.status !== 0)
48
+ return failed(name);
49
+ // Verify the write: an interactive tool's process status alone is not
50
+ // sufficient evidence that its command stored the requested item.
51
+ const saved = this.read();
52
+ if (!saved || !timingSafeEqual(saved, key))
53
+ return failed(name);
54
+ },
55
+ remove() {
56
+ const result = run("/usr/bin/security", ["delete-generic-password", "-s", service, "-a", account]);
57
+ if (result.error || (result.status !== 0 && result.status !== 44))
58
+ failed(name);
59
+ },
60
+ };
61
+ }
62
+ if (platform === "linux") {
63
+ const name = "Linux Secret Service (secret-tool)";
64
+ const attributes = ["service", service, "account", account];
65
+ return {
66
+ name,
67
+ read() {
68
+ const result = run("/usr/bin/secret-tool", ["lookup", ...attributes]);
69
+ if (!result.error && result.status === 1 && !result.stderr.trim())
70
+ return null;
71
+ if (result.error || result.status !== 0)
72
+ return failed(name);
73
+ return parseKey(result.stdout);
74
+ },
75
+ write(key) {
76
+ const result = run("/usr/bin/secret-tool", ["store", "--label=CLI session encryption key", ...attributes], key.toString("base64"));
77
+ if (result.error || result.status !== 0)
78
+ return failed(name);
79
+ const saved = this.read();
80
+ if (!saved || !timingSafeEqual(saved, key))
81
+ return failed(name);
82
+ },
83
+ remove() {
84
+ const result = run("/usr/bin/secret-tool", ["clear", ...attributes]);
85
+ if (result.error || result.status !== 0)
86
+ failed(name);
87
+ },
88
+ };
89
+ }
90
+ if (platform === "win32") {
91
+ const name = "Windows DPAPI (current user)";
92
+ const keyPath = path + ".key";
93
+ const executable = join(process.env.SystemRoot ?? "C:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
94
+ const script = `
95
+ $ErrorActionPreference = 'Stop'
96
+ try {
97
+ Add-Type -AssemblyName System.Security
98
+ $payload = [Console]::In.ReadToEnd() | ConvertFrom-Json
99
+ $bytes = [Convert]::FromBase64String([string]$payload.data)
100
+ $entropy = [Text.Encoding]::UTF8.GetBytes([string]$payload.service)
101
+ $scope = [System.Security.Cryptography.DataProtectionScope]::CurrentUser
102
+ if ($payload.action -eq 'protect') { $result = [System.Security.Cryptography.ProtectedData]::Protect($bytes, $entropy, $scope) }
103
+ elseif ($payload.action -eq 'unprotect') { $result = [System.Security.Cryptography.ProtectedData]::Unprotect($bytes, $entropy, $scope) }
104
+ else { exit 1 }
105
+ [Console]::Out.Write([Convert]::ToBase64String($result))
106
+ exit 0
107
+ } catch { exit 1 }
108
+ `;
109
+ const crypt = (action, data) => {
110
+ // EncodedCommand contains fixed code only. Sensitive data goes over stdin.
111
+ const result = run(executable, ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], JSON.stringify({ action, data, service }));
112
+ if (result.error || result.status !== 0 || !result.stdout.trim())
113
+ return failed(name);
114
+ return result.stdout.trim();
115
+ };
116
+ return {
117
+ name,
118
+ read() {
119
+ let wrapped;
120
+ try {
121
+ wrapped = readFileSync(keyPath, "utf8");
122
+ }
123
+ catch (error) {
124
+ if (error.code === "ENOENT")
125
+ return null;
126
+ return failed(name);
127
+ }
128
+ return parseKey(crypt("unprotect", wrapped));
129
+ },
130
+ write(key) {
131
+ const wrapped = crypt("protect", key.toString("base64"));
132
+ const temporary = keyPath + "." + randomBytes(16).toString("hex") + ".tmp";
133
+ try {
134
+ writeFileSync(temporary, wrapped, { mode: 0o600, flag: "wx", flush: true });
135
+ renameSync(temporary, keyPath);
136
+ }
137
+ finally {
138
+ rmSync(temporary, { force: true });
139
+ }
140
+ const saved = this.read();
141
+ if (!saved || !timingSafeEqual(saved, key))
142
+ return failed(name);
143
+ },
144
+ remove() { rmSync(keyPath, { force: true }); },
145
+ };
146
+ }
147
+ return { name: "OS credential storage", read: () => failed("OS credential storage on this platform"), write: () => failed("OS credential storage on this platform"), remove: () => failed("OS credential storage on this platform") };
148
+ }
149
+ export function encryptedCredentialCodec(path, keyStore) {
150
+ const associatedData = Buffer.from("cli-credentials-v1:" + resolve(path));
151
+ const key = (create) => {
152
+ const saved = keyStore.read();
153
+ if (saved)
154
+ return saved;
155
+ if (!create || existsSync(path))
156
+ throw new CredentialStorageError("The encryption key for this saved session is missing. Restore the original OS credential store, or run logout --local to remove the saved encrypted session before logging in again.");
157
+ const generated = randomBytes(32);
158
+ keyStore.write(generated);
159
+ return generated;
160
+ };
161
+ return {
162
+ name: keyStore.name,
163
+ prepare() { key(true); },
164
+ encode(plaintext) {
165
+ const nonce = randomBytes(12);
166
+ const cipher = createCipheriv("aes-256-gcm", key(true), nonce);
167
+ cipher.setAAD(associatedData);
168
+ const ciphertext = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
169
+ return JSON.stringify({ version: 1, algorithm: "aes-256-gcm", nonce: nonce.toString("base64"), tag: cipher.getAuthTag().toString("base64"), ciphertext: ciphertext.toString("base64") });
170
+ },
171
+ decode(encoded) {
172
+ let envelope;
173
+ try {
174
+ envelope = JSON.parse(encoded);
175
+ }
176
+ catch {
177
+ throw new CredentialStorageError("Saved encrypted credentials are damaged. Restore the credential file before logging in again.");
178
+ }
179
+ if (!envelope || envelope.version !== 1 || envelope.algorithm !== "aes-256-gcm" || typeof envelope.nonce !== "string" || typeof envelope.tag !== "string" || typeof envelope.ciphertext !== "string")
180
+ throw new CredentialStorageError("Saved encrypted credentials use an invalid format.");
181
+ const secret = key(false);
182
+ try {
183
+ const nonce = Buffer.from(envelope.nonce, "base64"), tag = Buffer.from(envelope.tag, "base64");
184
+ if (nonce.length !== 12 || tag.length !== 16)
185
+ throw new Error();
186
+ const decipher = createDecipheriv("aes-256-gcm", secret, nonce);
187
+ decipher.setAAD(associatedData);
188
+ decipher.setAuthTag(tag);
189
+ return Buffer.concat([decipher.update(Buffer.from(envelope.ciphertext, "base64")), decipher.final()]).toString("utf8");
190
+ }
191
+ catch {
192
+ throw new CredentialStorageError("Saved credentials could not be authenticated. Restore the original credential file and OS key; do not reuse this session.");
193
+ }
194
+ },
195
+ };
196
+ }
197
+ /** OS protection is the default. Plaintext storage is an explicit, separate
198
+ * store for environments where the owner accepts that tradeoff. Never migrate
199
+ * or fall back silently when an OS service is unavailable. */
200
+ export function createCredentialStore(directory, mode = "os", environmentName = "CREDENTIAL_STORE") {
201
+ if (mode === "file")
202
+ return new FileCredentialStore(join(directory, "credentials.json"));
203
+ if (mode !== "os")
204
+ throw new CredentialStorageError(environmentName + " must be os or file.");
205
+ const path = join(directory, "credentials.enc");
206
+ return new FileCredentialStore(path, 40_000, encryptedCredentialCodec(path, nativeCredentialKeyStore(path, process.platform, nativeCommand, environmentName)));
207
+ }
package/dist/docs.d.ts CHANGED
@@ -5,7 +5,32 @@ export declare function resolveDocsPageUrl(base: string | null, pathOrFile: stri
5
5
  * llms.txt location. Guide links may live on either the docs-site origin or
6
6
  * the index origin; no other origin is accepted. */
7
7
  export declare function resolveDocsContentUrl(base: string | null, indexUrl: string | null, pathOrFile: string): string | null;
8
+ export interface GuideMatch {
9
+ title: string;
10
+ section: string | null;
11
+ /** Kept for callers that displayed the original heading-only results. */
12
+ heading: string;
13
+ excerpt: string;
14
+ url: string;
15
+ }
16
+ interface GuidePage {
17
+ title: string;
18
+ url: string;
19
+ description: string;
20
+ }
21
+ export declare function docsIndexPages(index: string | null, base: string | null, indexUrl: string | null): GuidePage[];
22
+ /** Rank sections, then keep the strongest section of each real page. A heading
23
+ * match must have content: blank lines, fences, and source markers are not hits. */
24
+ export declare function searchGuidePages(prose: string | null, index: string | null, base: string | null, indexUrl: string | null, query: string): GuideMatch[];
25
+ export declare function searchConnectedGuides(base: string | null, indexUrl: string | null, fetchText: (path: string) => Promise<string | null>, query: string): Promise<{
26
+ guides: GuideMatch[];
27
+ status: "not_configured" | "unavailable" | "ok";
28
+ }>;
29
+ export declare function docsReadTarget(index: string | null, base: string | null, indexUrl: string | null, page: string): string;
30
+ /** One shell argument, including URLs with quotes, query strings, or fragments. */
31
+ export declare function docsReadCommand(bin: string, url: string): string;
8
32
  /** Markdown-preferred fetch with same-origin redirects, one deadline, and a
9
33
  * streaming byte cap. Returns null for every invalid or failed read. */
10
34
  export declare function fetchDocsText(url: string): Promise<string | null>;
35
+ export {};
11
36
  //# sourceMappingURL=docs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYzF;AAED;;oDAEoD;AACpD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAkBf;AAcD;wEACwE;AACxE,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyCvE"}
1
+ {"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAE9E,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYzF;AAED;;oDAEoD;AACpD,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAkBf;AAcD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,yEAAyE;IACzE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,SAAS;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE;AAUvE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,CAW9G;AAUD;oFACoF;AACpF,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GACtG,UAAU,EAAE,CAqEd;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,GAC/G,OAAO,CAAC;IAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAAC,MAAM,EAAE,gBAAgB,GAAG,aAAa,GAAG,IAAI,CAAA;CAAE,CAAC,CAIpF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAQvH;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;wEACwE;AACxE,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyCvE"}
package/dist/docs.js CHANGED
@@ -60,6 +60,150 @@ function safeHttpUrl(value) {
60
60
  return null;
61
61
  }
62
62
  }
63
+ /** Links in an index follow URL semantics, including site-root relative links. */
64
+ function docsLink(base, indexUrl, value) {
65
+ const index = resolveDocsContentUrl(base, indexUrl, "llms.txt");
66
+ if (!index)
67
+ return null;
68
+ try {
69
+ return resolveDocsContentUrl(base, indexUrl, new URL(value, index).toString());
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ }
75
+ export function docsIndexPages(index, base, indexUrl) {
76
+ const pages = new Map();
77
+ for (const line of (index ?? "").split("\n")) {
78
+ for (const match of line.matchAll(/\[([^\]]+)\]\(([^\s)]+)\)/g)) {
79
+ const url = docsLink(base, indexUrl, match[2]);
80
+ if (!url || /\/llms(?:-full)?\.txt(?:[?#]|$)/.test(url))
81
+ continue;
82
+ const description = line.slice(match.index + match[0].length).replace(/^\s*:\s*/, "").trim();
83
+ if (!pages.has(url))
84
+ pages.set(url, { title: match[1], url, description: cleanDocsText(description) });
85
+ }
86
+ }
87
+ return [...pages.values()];
88
+ }
89
+ function cleanDocsText(text) {
90
+ return text.replace(/^\s*(?:>\s*)+/, "").replace(/!?\[([^\]]+)\]\([^)]*\)/g, "$1").replace(/<[^>]*>/g, "").replace(/[*`]/g, "").replace(/^\s*[-*>]\s*/, "").replace(/\s+/g, " ").trim();
91
+ }
92
+ function docsTerms(query) {
93
+ return [...new Set(query.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/).filter((term) => term.length >= 2))];
94
+ }
95
+ /** Rank sections, then keep the strongest section of each real page. A heading
96
+ * match must have content: blank lines, fences, and source markers are not hits. */
97
+ export function searchGuidePages(prose, index, base, indexUrl, query) {
98
+ const pages = docsIndexPages(index, base, indexUrl);
99
+ const terms = docsTerms(query);
100
+ if (terms.length === 0)
101
+ return [];
102
+ const phrase = query.trim().toLowerCase();
103
+ const candidates = [];
104
+ const add = (title, section, url, lines) => {
105
+ if (!url)
106
+ return;
107
+ const content = lines.map(cleanDocsText).filter((line) => line.length > 0);
108
+ if (content.length === 0)
109
+ return;
110
+ const heading = (title + " " + (section ?? "")).toLowerCase();
111
+ const body = content.join(" ").toLowerCase();
112
+ const matched = terms.filter((term) => heading.includes(term) || body.includes(term));
113
+ if (matched.length === 0)
114
+ return;
115
+ const score = matched.length * 10 + (matched.length === terms.length ? 50 : 0)
116
+ + (heading.includes(phrase) ? 35 : body.includes(phrase) ? 25 : 0)
117
+ + (title.toLowerCase().includes(phrase) ? 25 : 0)
118
+ + terms.filter((term) => title.toLowerCase().includes(term)).length * 5
119
+ + terms.filter((term) => heading.includes(term)).length * 5
120
+ + terms.filter((term) => section?.toLowerCase().includes(term)).length * 3;
121
+ const excerpt = [...content].sort((a, b) => {
122
+ const rank = (line) => terms.filter((term) => line.toLowerCase().includes(term)).length;
123
+ return rank(b) - rank(a);
124
+ })[0].slice(0, 240);
125
+ candidates.push({ match: { title, section, heading: section ?? title, excerpt, url }, score });
126
+ };
127
+ let title = "";
128
+ let section = null;
129
+ let url = null;
130
+ let lines = [];
131
+ let fence = null;
132
+ const flush = () => { add(title, section, url, lines); lines = []; };
133
+ for (const line of (prose ?? "").split("\n")) {
134
+ const fenced = line.trim().match(/^(`{3,}|~{3,})/);
135
+ if (fenced) {
136
+ if (fence === null)
137
+ fence = fenced[1][0];
138
+ else if (fenced[1][0] === fence)
139
+ fence = null;
140
+ continue;
141
+ }
142
+ if (fence !== null) {
143
+ if (line.trim())
144
+ lines.push(line);
145
+ continue;
146
+ }
147
+ const heading = line.match(/^(#{1,6})\s+(.+?)\s*#*$/);
148
+ if (heading) {
149
+ flush();
150
+ if (heading[1] === "#") {
151
+ title = cleanDocsText(heading[2]);
152
+ section = null;
153
+ const link = heading[2].match(/\[[^\]]+\]\(([^\s)]+)\)/);
154
+ url = link ? docsLink(base, indexUrl, link[1]) : pages.find((page) => page.title.toLowerCase() === title.toLowerCase())?.url ?? null;
155
+ }
156
+ else
157
+ section = cleanDocsText(heading[2]);
158
+ continue;
159
+ }
160
+ const source = line.match(/^Source:\s*(?:\[[^\]]*\]\()?<?(https?:\/\/[^\s)>]+)>?\)?\s*$/i);
161
+ if (source) {
162
+ url = docsLink(base, indexUrl, source[1]);
163
+ continue;
164
+ }
165
+ // Markdown callouts are blockquotes; keep their text for search and excerpts.
166
+ if (!line.trim() || /^\s*(?:---+|\|[\s:|-]+\|)\s*$/.test(line) || /^\s*</.test(line))
167
+ continue;
168
+ lines.push(line);
169
+ }
170
+ flush();
171
+ // An index is useful without llms-full.txt, and may include additional pages.
172
+ const described = new Set(candidates.map(({ match }) => match.url.replace(/\.md(?=[?#]|$)/, "")));
173
+ for (const page of pages) {
174
+ if (!described.has(page.url.replace(/\.md(?=[?#]|$)/, "")))
175
+ add(page.title, null, page.url, [page.description || page.title]);
176
+ }
177
+ candidates.sort((a, b) => b.score - a.score || a.match.title.localeCompare(b.match.title) || a.match.url.localeCompare(b.match.url));
178
+ const distinct = new Map();
179
+ for (const { match } of candidates) {
180
+ const key = match.url.replace(/\.md(?=[?#]|$)/, "");
181
+ if (!distinct.has(key))
182
+ distinct.set(key, match);
183
+ }
184
+ return [...distinct.values()];
185
+ }
186
+ export async function searchConnectedGuides(base, indexUrl, fetchText, query) {
187
+ if (!base && !indexUrl)
188
+ return { guides: [], status: "not_configured" };
189
+ const [index, prose] = await Promise.all([fetchText("llms.txt"), fetchText("llms-full.txt")]);
190
+ return { guides: searchGuidePages(prose, index, base, indexUrl, query), status: index === null && prose === null ? "unavailable" : "ok" };
191
+ }
192
+ export function docsReadTarget(index, base, indexUrl, page) {
193
+ if (/^https?:\/\//.test(page))
194
+ return page;
195
+ const pages = docsIndexPages(index, base, indexUrl);
196
+ const term = page.toLowerCase();
197
+ const exact = pages.find((item) => item.title.toLowerCase() === term || new URL(item.url).pathname.toLowerCase() === term);
198
+ if (exact)
199
+ return exact.url;
200
+ const matches = pages.filter((item) => item.url.toLowerCase().includes(term));
201
+ return matches.length === 1 ? matches[0].url : page;
202
+ }
203
+ /** One shell argument, including URLs with quotes, query strings, or fragments. */
204
+ export function docsReadCommand(bin, url) {
205
+ return bin + " docs read '" + url.replace(/'/g, "'\\''") + "'";
206
+ }
63
207
  /** Markdown-preferred fetch with same-origin redirects, one deadline, and a
64
208
  * streaming byte cap. Returns null for every invalid or failed read. */
65
209
  export async function fetchDocsText(url) {
package/dist/errors.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ApiError, type ResponseMeta } from "./core/http.js";
2
2
  import type { ErrorModelRead } from "./types.js";
3
- export { ApiError, TransportError, UnexpectedApiError, ValidationError, type Violation, unwrap } from "./core/http.js";
3
+ export { ApiError, ResponseParseError, TransportError, UnexpectedApiError, ValidationError, type Violation, unwrap } from "./core/http.js";
4
4
  /**
5
5
  * The request body, Definition source, target selection, or package name is invalid.
6
6
  * Raised for HTTP 400 responses.
@@ -22,6 +22,13 @@ export declare class UnauthorizedError extends ApiError<401, ErrorModelRead> {
22
22
  export declare class ForbiddenError extends ApiError<403, ErrorModelRead> {
23
23
  constructor(body: ErrorModelRead, response: ResponseMeta);
24
24
  }
25
+ /**
26
+ * The key identifies changed intent.
27
+ * Raised for HTTP 409 responses.
28
+ */
29
+ export declare class ConflictError extends ApiError<409, ErrorModelRead> {
30
+ constructor(body: ErrorModelRead, response: ResponseMeta);
31
+ }
25
32
  /**
26
33
  * Spec exceeds the 10MB limit.
27
34
  * Raised for HTTP 413 responses.
@@ -37,7 +44,8 @@ export declare class UnprocessableEntityError extends ApiError<422, ErrorModelRe
37
44
  constructor(body: ErrorModelRead, response: ResponseMeta);
38
45
  }
39
46
  /**
40
- * Too many requests. Wait for Retry-After before retrying.
47
+ * Too many requests, or an identical write is still in progress. Wait for Retry-After before
48
+ * retrying.
41
49
  * Raised for HTTP 429 responses.
42
50
  */
43
51
  export declare class RateLimitedError extends ApiError<429, ErrorModelRead> {
@@ -58,14 +66,7 @@ export declare class PaymentRequiredError extends ApiError<402, ErrorModelRead>
58
66
  constructor(body: ErrorModelRead, response: ResponseMeta);
59
67
  }
60
68
  /**
61
- * The Idempotency-Key was already used with different request parameters.
62
- * Raised for HTTP 409 responses.
63
- */
64
- export declare class ConflictError extends ApiError<409, ErrorModelRead> {
65
- constructor(body: ErrorModelRead, response: ResponseMeta);
66
- }
67
- /**
68
- * The original idempotent request is temporarily unavailable.
69
+ * Project setup failed unexpectedly; the key reservation is released.
69
70
  * Raised for HTTP 500 responses.
70
71
  */
71
72
  export declare class InternalServerError extends ApiError<500, ErrorModelRead> {
@@ -78,4 +79,11 @@ export declare class InternalServerError extends ApiError<500, ErrorModelRead> {
78
79
  export declare class NotFoundError extends ApiError<404, ErrorModelRead> {
79
80
  constructor(body: ErrorModelRead, response: ResponseMeta);
80
81
  }
82
+ /**
83
+ * The Project was saved, but an obsolete release pull request could not be retired.
84
+ * Raised for HTTP 502 responses.
85
+ */
86
+ export declare class BadGatewayError extends ApiError<502, ErrorModelRead> {
87
+ constructor(body: ErrorModelRead, response: ResponseMeta);
88
+ }
81
89
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAEvH;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACpD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACtD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,cAAe,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACnD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACzD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBAC7D,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACrD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;gBACxD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACzD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBAClD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACxD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBAClD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAE3I;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACpD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACtD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,cAAe,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACnD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBAClD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACzD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,wBAAyB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBAC7D,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACrD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;gBACxD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACzD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACxD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,aAAc,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBAClD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC;gBACpD,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY;CAGzD"}
package/dist/errors.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // typeship — typed error classes.
2
2
  // Generated by typeship — https://typeship.dev — do not edit by hand.
3
3
  import { ApiError } from "./core/http.js";
4
- export { ApiError, TransportError, UnexpectedApiError, ValidationError, unwrap } from "./core/http.js";
4
+ export { ApiError, ResponseParseError, TransportError, UnexpectedApiError, ValidationError, unwrap } from "./core/http.js";
5
5
  /**
6
6
  * The request body, Definition source, target selection, or package name is invalid.
7
7
  * Raised for HTTP 400 responses.
@@ -29,6 +29,15 @@ export class ForbiddenError extends ApiError {
29
29
  super("The credentials are valid but cannot act on the requested organization.", 403, body, response);
30
30
  }
31
31
  }
32
+ /**
33
+ * The key identifies changed intent.
34
+ * Raised for HTTP 409 responses.
35
+ */
36
+ export class ConflictError extends ApiError {
37
+ constructor(body, response) {
38
+ super("The key identifies changed intent.", 409, body, response);
39
+ }
40
+ }
32
41
  /**
33
42
  * Spec exceeds the 10MB limit.
34
43
  * Raised for HTTP 413 responses.
@@ -48,12 +57,13 @@ export class UnprocessableEntityError extends ApiError {
48
57
  }
49
58
  }
50
59
  /**
51
- * Too many requests. Wait for Retry-After before retrying.
60
+ * Too many requests, or an identical write is still in progress. Wait for Retry-After before
61
+ * retrying.
52
62
  * Raised for HTTP 429 responses.
53
63
  */
54
64
  export class RateLimitedError extends ApiError {
55
65
  constructor(body, response) {
56
- super("Too many requests. Wait for Retry-After before retrying.", 429, body, response);
66
+ super("Too many requests, or an identical write is still in progress. Wait for Retry-After before retrying.", 429, body, response);
57
67
  }
58
68
  }
59
69
  /**
@@ -75,21 +85,12 @@ export class PaymentRequiredError extends ApiError {
75
85
  }
76
86
  }
77
87
  /**
78
- * The Idempotency-Key was already used with different request parameters.
79
- * Raised for HTTP 409 responses.
80
- */
81
- export class ConflictError extends ApiError {
82
- constructor(body, response) {
83
- super("The Idempotency-Key was already used with different request parameters.", 409, body, response);
84
- }
85
- }
86
- /**
87
- * The original idempotent request is temporarily unavailable.
88
+ * Project setup failed unexpectedly; the key reservation is released.
88
89
  * Raised for HTTP 500 responses.
89
90
  */
90
91
  export class InternalServerError extends ApiError {
91
92
  constructor(body, response) {
92
- super("The original idempotent request is temporarily unavailable.", 500, body, response);
93
+ super("Project setup failed unexpectedly; the key reservation is released.", 500, body, response);
93
94
  }
94
95
  }
95
96
  /**
@@ -101,3 +102,12 @@ export class NotFoundError extends ApiError {
101
102
  super("No such resource in this account.", 404, body, response);
102
103
  }
103
104
  }
105
+ /**
106
+ * The Project was saved, but an obsolete release pull request could not be retired.
107
+ * Raised for HTTP 502 responses.
108
+ */
109
+ export class BadGatewayError extends ApiError {
110
+ constructor(body, response) {
111
+ super("The Project was saved, but an obsolete release pull request could not be retired.", 502, body, response);
112
+ }
113
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type DebugEvent, type RequestContext } from "./core/http.js";
1
+ import { type AuthValue, type DebugEvent, type RequestContext } from "./core/http.js";
2
2
  import { GenerateResource } from "./resources/generate.js";
3
3
  import { ProjectsResource } from "./resources/projects.js";
4
4
  import { DefinitionsResource } from "./resources/definitions.js";
@@ -8,7 +8,7 @@ import { DefinitionRevisionsResource } from "./resources/definition-revisions.js
8
8
  import { AccountResource } from "./resources/account.js";
9
9
  import { ApiKeysResource } from "./resources/api-keys.js";
10
10
  /** This package's version, also sent as the `User-Agent`. */
11
- export declare const VERSION = "0.8.0";
11
+ export declare const VERSION = "0.10.0";
12
12
  export interface ClientOptions {
13
13
  /** Override the server URL. Default: `https://typeship.dev/api/v1` */
14
14
  baseUrl?: string;
@@ -17,6 +17,13 @@ export interface ClientOptions {
17
17
  * before every attempt.
18
18
  */
19
19
  bearerToken?: string | (() => string | Promise<string>);
20
+ /**
21
+ * Credentials keyed by the Definition's security scheme names. Only one complete alternative is
22
+ * sent for each operation. Named values take precedence over convenience options.
23
+ */
24
+ credentials?: {
25
+ "apiKey"?: AuthValue;
26
+ };
20
27
  /** Per-attempt timeout in milliseconds. Default: 30000. */
21
28
  timeoutMs?: number;
22
29
  /** Retries after the first attempt (retryable failures only). Default: 2. */
@@ -62,7 +69,7 @@ export interface ClientOptions {
62
69
  };
63
70
  }
64
71
  /**
65
- * typeship — v0.8.0
72
+ * typeship — v0.10.0
66
73
  *
67
74
  * Resolve an OpenAPI or GraphQL Definition, diagnose it, and keep every
68
75
  * selected SDK, CLI, and MCP Target current.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -11,10 +11,10 @@ import { DefinitionRevisionsResource } from "./resources/definition-revisions.js
11
11
  import { AccountResource } from "./resources/account.js";
12
12
  import { ApiKeysResource } from "./resources/api-keys.js";
13
13
  /** This package's version, also sent as the `User-Agent`. */
14
- export const VERSION = "0.8.0";
15
- const USER_AGENT = "@typeship-ax/cli/0.8.0 (typeship)";
14
+ export const VERSION = "0.10.0";
15
+ const USER_AGENT = "@typeship-ax/cli/0.10.0 (typeship)";
16
16
  /**
17
- * typeship — v0.8.0
17
+ * typeship — v0.10.0
18
18
  *
19
19
  * Resolve an OpenAPI or GraphQL Definition, diagnose it, and keep every
20
20
  * selected SDK, CLI, and MCP Target current.
@@ -47,8 +47,23 @@ export class TypeshipClient {
47
47
  ? (event) => console.error(formatDebugEvent("typeship", event))
48
48
  : undefined;
49
49
  const query = {};
50
+ const authHeaders = {};
51
+ const authQuery = {};
52
+ let bearerCredential;
50
53
  if (options.bearerToken !== undefined)
51
- headers["Authorization"] = bearerAuth(options.bearerToken);
54
+ bearerCredential = bearerAuth(options.bearerToken);
55
+ const allowedCredentials = new Set(["apiKey"]);
56
+ for (const name of Object.keys(options.credentials ?? {})) {
57
+ if (!allowedCredentials.has(name))
58
+ throw new Error("Unknown security scheme: " + name);
59
+ }
60
+ const credentials = Object.create(null);
61
+ {
62
+ const named = options.credentials && Object.hasOwn(options.credentials, "apiKey") ? options.credentials["apiKey"] : undefined;
63
+ const value = named !== undefined ? bearerAuth(named) : bearerCredential;
64
+ if (value !== undefined)
65
+ credentials["apiKey"] = { headers: { ["Authorization"]: value } };
66
+ }
52
67
  const v = options.validate;
53
68
  const validate = v
54
69
  ? {
@@ -61,6 +76,7 @@ export class TypeshipClient {
61
76
  baseUrl: options.baseUrl ?? "https://typeship.dev/api/v1",
62
77
  headers,
63
78
  query,
79
+ credentials,
64
80
  fetch: options.fetch ?? fetch,
65
81
  timeoutMs: options.timeoutMs ?? 30_000,
66
82
  maxRetries: options.maxRetries ?? 2,