@typeship-ax/cli 0.22.0 → 0.24.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 (146) hide show
  1. package/AGENTS.md +13 -9
  2. package/README.md +14 -27
  3. package/api.json +8898 -9026
  4. package/api.md +370 -328
  5. package/dist/arguments.d.ts +54 -0
  6. package/dist/arguments.d.ts.map +1 -0
  7. package/dist/arguments.js +265 -0
  8. package/dist/cli-agent.d.ts +73 -9
  9. package/dist/cli-agent.d.ts.map +1 -1
  10. package/dist/cli-agent.js +331 -44
  11. package/dist/cli.js +802 -291
  12. package/dist/core/http.d.ts +162 -19
  13. package/dist/core/http.d.ts.map +1 -1
  14. package/dist/core/http.js +381 -48
  15. package/dist/core/pagination.d.ts +42 -6
  16. package/dist/core/pagination.d.ts.map +1 -1
  17. package/dist/core/pagination.js +111 -17
  18. package/dist/credential-storage.d.ts +10 -3
  19. package/dist/credential-storage.d.ts.map +1 -1
  20. package/dist/credential-storage.js +15 -6
  21. package/dist/dates.d.ts +1 -1
  22. package/dist/dates.js +1 -1
  23. package/dist/errors.d.ts +20 -84
  24. package/dist/errors.d.ts.map +1 -1
  25. package/dist/errors.js +20 -108
  26. package/dist/fields.d.ts +36 -0
  27. package/dist/fields.d.ts.map +1 -0
  28. package/dist/fields.js +187 -0
  29. package/dist/index.d.ts +28 -18
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +35 -25
  32. package/dist/named-credentials.d.ts +19 -0
  33. package/dist/named-credentials.d.ts.map +1 -1
  34. package/dist/named-credentials.js +81 -1
  35. package/dist/oauth-login.d.ts +8 -2
  36. package/dist/oauth-login.d.ts.map +1 -1
  37. package/dist/oauth-login.js +31 -19
  38. package/dist/oauth-request.d.ts +7 -1
  39. package/dist/oauth-request.d.ts.map +1 -1
  40. package/dist/oauth-request.js +26 -4
  41. package/dist/oauth-session.d.ts +13 -1
  42. package/dist/oauth-session.d.ts.map +1 -1
  43. package/dist/oauth-session.js +34 -18
  44. package/dist/ops.d.ts +58 -5
  45. package/dist/ops.d.ts.map +1 -1
  46. package/dist/ops.js +110 -41
  47. package/dist/polling-login.d.ts +8 -2
  48. package/dist/polling-login.d.ts.map +1 -1
  49. package/dist/polling-login.js +25 -11
  50. package/dist/resources/api-keys.d.ts +10 -7
  51. package/dist/resources/api-keys.d.ts.map +1 -1
  52. package/dist/resources/api-keys.js +10 -31
  53. package/dist/resources/deliveries.d.ts +89 -5
  54. package/dist/resources/deliveries.d.ts.map +1 -1
  55. package/dist/resources/deliveries.js +96 -19
  56. package/dist/resources/drafts.d.ts +16 -16
  57. package/dist/resources/drafts.d.ts.map +1 -1
  58. package/dist/resources/drafts.js +12 -65
  59. package/dist/resources/files.d.ts +4 -4
  60. package/dist/resources/files.d.ts.map +1 -1
  61. package/dist/resources/files.js +3 -12
  62. package/dist/resources/generations.d.ts +16 -16
  63. package/dist/resources/generations.d.ts.map +1 -1
  64. package/dist/resources/generations.js +23 -47
  65. package/dist/resources/organization.d.ts +4 -4
  66. package/dist/resources/organization.d.ts.map +1 -1
  67. package/dist/resources/organization.js +3 -10
  68. package/dist/resources/{generate.d.ts → packages.d.ts} +16 -16
  69. package/dist/resources/packages.d.ts.map +1 -0
  70. package/dist/resources/{generate.js → packages.js} +13 -29
  71. package/dist/resources/projects.d.ts +50 -50
  72. package/dist/resources/projects.d.ts.map +1 -1
  73. package/dist/resources/projects.js +60 -116
  74. package/dist/resources/releases.d.ts +22 -17
  75. package/dist/resources/releases.d.ts.map +1 -1
  76. package/dist/resources/releases.js +19 -40
  77. package/dist/resources/spec-revisions.d.ts +16 -7
  78. package/dist/resources/spec-revisions.d.ts.map +1 -1
  79. package/dist/resources/spec-revisions.js +7 -29
  80. package/dist/resources/specs.d.ts +7 -7
  81. package/dist/resources/specs.d.ts.map +1 -1
  82. package/dist/resources/specs.js +6 -34
  83. package/dist/resources/targets.d.ts +49 -49
  84. package/dist/resources/targets.d.ts.map +1 -1
  85. package/dist/resources/targets.js +59 -115
  86. package/dist/schemas.d.ts.map +1 -1
  87. package/dist/schemas.js +83 -81
  88. package/dist/search.d.ts +54 -0
  89. package/dist/search.d.ts.map +1 -0
  90. package/dist/search.js +421 -0
  91. package/dist/table.d.ts +28 -0
  92. package/dist/table.d.ts.map +1 -0
  93. package/dist/table.js +167 -0
  94. package/dist/type-docs.d.ts +61 -0
  95. package/dist/type-docs.d.ts.map +1 -0
  96. package/dist/type-docs.js +174 -0
  97. package/dist/types.d.ts +499 -339
  98. package/dist/types.d.ts.map +1 -1
  99. package/dist/types.js +18 -18
  100. package/package.json +5 -2
  101. package/src/arguments.ts +254 -0
  102. package/src/cli-agent.ts +351 -46
  103. package/src/cli.ts +753 -266
  104. package/src/core/http.ts +457 -58
  105. package/src/core/pagination.ts +129 -18
  106. package/src/credential-storage.ts +16 -6
  107. package/src/dates.ts +1 -1
  108. package/src/errors.ts +46 -115
  109. package/src/fields.ts +167 -0
  110. package/src/index.ts +45 -28
  111. package/src/named-credentials.ts +66 -1
  112. package/src/oauth-login.ts +36 -21
  113. package/src/oauth-request.ts +32 -6
  114. package/src/oauth-session.ts +37 -19
  115. package/src/ops.ts +146 -45
  116. package/src/polling-login.ts +24 -11
  117. package/src/resources/api-keys.ts +34 -48
  118. package/src/resources/deliveries.ts +213 -32
  119. package/src/resources/drafts.ts +62 -109
  120. package/src/resources/files.ts +19 -20
  121. package/src/resources/generations.ts +61 -79
  122. package/src/resources/organization.ts +11 -16
  123. package/src/resources/{generate.ts → packages.ts} +43 -51
  124. package/src/resources/projects.ts +145 -200
  125. package/src/resources/releases.ts +50 -67
  126. package/src/resources/spec-revisions.ts +40 -49
  127. package/src/resources/specs.ts +39 -59
  128. package/src/resources/targets.ts +144 -194
  129. package/src/schemas.ts +83 -81
  130. package/src/search.ts +434 -0
  131. package/src/table.ts +167 -0
  132. package/src/type-docs.ts +205 -0
  133. package/src/types.ts +538 -357
  134. package/dist/console-login-check.d.ts +0 -21
  135. package/dist/console-login-check.d.ts.map +0 -1
  136. package/dist/console-login-check.js +0 -107
  137. package/dist/console-login-contract.d.ts +0 -45
  138. package/dist/console-login-contract.d.ts.map +0 -1
  139. package/dist/console-login-contract.js +0 -40
  140. package/dist/resources/generate.d.ts.map +0 -1
  141. package/dist/resources/publications.d.ts +0 -47
  142. package/dist/resources/publications.d.ts.map +0 -1
  143. package/dist/resources/publications.js +0 -70
  144. package/src/console-login-check.ts +0 -88
  145. package/src/console-login-contract.ts +0 -65
  146. package/src/resources/publications.ts +0 -140
@@ -1,21 +0,0 @@
1
- import { type ConsoleLoginCheck, type ConsoleLoginConfiguration } from "./console-login-contract.js";
2
- import { type OAuthLoginSession } from "./oauth-login.js";
3
- import { type CredentialSchemes, type NamedCredentials } from "./named-credentials.js";
4
- /** No traffic to Typeship occurs without the explicit --console-check action.
5
- * Only the credentials selected for the identity read leave this process;
6
- * refresh tokens and other stored logins are never sent to the Console. */
7
- export declare function checkConsoleBrowserLogin(input: {
8
- file: string;
9
- configuration: ConsoleLoginConfiguration;
10
- schemes: CredentialSchemes;
11
- credentials: NamedCredentials;
12
- login(timeoutMs: number): Promise<OAuthLoginSession>;
13
- verify(credentials: NamedCredentials, expectations: ConsoleLoginCheck["expectations"]): Promise<void>;
14
- progress(message: string): void;
15
- }): Promise<{
16
- ok: true;
17
- method: "oauth_browser";
18
- console_verified: true;
19
- revoked: boolean | null;
20
- }>;
21
- //# sourceMappingURL=console-login-check.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"console-login-check.d.ts","sourceRoot":"","sources":["../src/console-login-check.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgE,KAAK,iBAAiB,EAAE,KAAK,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AACnK,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAyB,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAuB9G;;2EAE2E;AAC3E,wBAAsB,wBAAwB,CAAC,KAAK,EAAE;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,yBAAyB,CAAC;IACzC,OAAO,EAAE,iBAAiB,CAAC;IAC3B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACrD,MAAM,CAAC,WAAW,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtG,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,eAAe,CAAC;IAAC,gBAAgB,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,CAAC,CAiDlG"}
@@ -1,107 +0,0 @@
1
- import { openSync, readSync, closeSync, fstatSync, constants } from "node:fs";
2
- import { oauthJsonRequest } from "./oauth-request.js";
3
- import { sameConsoleLoginConfiguration, matchesConsoleBrowserEvidence } from "./console-login-contract.js";
4
- import { parseNamedCredentials } from "./named-credentials.js";
5
- function readCheck(path) {
6
- let fd;
7
- try {
8
- fd = openSync(path, constants.O_RDONLY | constants.O_NONBLOCK);
9
- if (!fstatSync(fd).isFile())
10
- throw new Error();
11
- const buffer = Buffer.alloc(65_537);
12
- let size = 0;
13
- while (size < buffer.length) {
14
- const n = readSync(fd, buffer, size, buffer.length - size, null);
15
- if (!n)
16
- break;
17
- size += n;
18
- }
19
- if (size > 65_536)
20
- throw new Error();
21
- const value = JSON.parse(buffer.subarray(0, size).toString("utf8"));
22
- if (value.version !== 1 || typeof value.ticket !== "string" || !/^[A-Za-z0-9_-]{43}$/.test(value.ticket) || !value.configuration || !Array.isArray(value.expectations) || !value.expectations.length || value.expectations.length > 3)
23
- throw new Error();
24
- const endpoint = new URL(value.endpoint);
25
- const development = endpoint.protocol === "http:" && ["127.0.0.1", "[::1]"].includes(endpoint.hostname);
26
- if (!(endpoint.origin === "https://typeship.dev" || development) || endpoint.pathname !== "/api/authentication/browser" || endpoint.username || endpoint.password || endpoint.search || endpoint.hash)
27
- throw new Error();
28
- const remaining = Date.parse(value.expiresAt) - Date.now();
29
- if (!Number.isFinite(remaining) || remaining <= 0 || remaining > 600_000)
30
- throw new Error();
31
- return value;
32
- }
33
- catch {
34
- throw new Error("Download a new login check from your Typeship Console and pass its JSON file to --console-check. Checks expire after ten minutes.");
35
- }
36
- finally {
37
- if (fd !== undefined)
38
- closeSync(fd);
39
- }
40
- }
41
- /** No traffic to Typeship occurs without the explicit --console-check action.
42
- * Only the credentials selected for the identity read leave this process;
43
- * refresh tokens and other stored logins are never sent to the Console. */
44
- export async function checkConsoleBrowserLogin(input) {
45
- const check = readCheck(input.file);
46
- if (!sameConsoleLoginConfiguration(input.configuration, check.configuration))
47
- throw new Error("This CLI's authentication settings do not match the saved Target. Regenerate the CLI, select the matching environment, and download a new check.");
48
- const send = async (body, timeoutMs = 30_000) => {
49
- const response = await oauthJsonRequest(check.endpoint, { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json" }, body: JSON.stringify({ ticket: check.ticket, ...body }) }, timeoutMs);
50
- if (response.status === 422)
51
- throw new Error("Typeship could not verify this login. Check the expected identity, API permissions and saved Target settings, then download a new check.");
52
- if (response.status !== 200 || response.data?.ok !== true)
53
- throw new Error("The Console check expired, was already used, changed, or could not be completed. Download a new check and try again.");
54
- return response.data;
55
- };
56
- await send({ action: "inspect" });
57
- let revoked = null;
58
- try {
59
- const supplied = parseNamedCredentials(input.credentials, input.schemes);
60
- // Only a complete alternative that uses the fresh browser token proves
61
- // browser access. An unrelated key-only alternative is not sufficient.
62
- const requirement = input.configuration.requirements.find((entry) => {
63
- const names = Object.keys(entry);
64
- if (!names.some((name) => input.schemes[name]?.kind === "bearer") || !names.every((name) => input.schemes[name]?.kind === "bearer" || supplied[name] !== undefined))
65
- return false;
66
- const selected = input.configuration.requirements.find((candidate) => Object.keys(candidate).every((name) => names.includes(name)));
67
- return selected && Object.keys(selected).some((name) => input.schemes[name]?.kind === "bearer");
68
- });
69
- if (!requirement)
70
- throw new Error("Supply the additional named credentials required by the identity read with --credentials @file or environment variables.");
71
- input.progress("This check runs a temporary browser login. Typeship will receive only the access token and any additional credentials required for the identity read; refresh tokens stay on this computer.");
72
- const session = await input.login(Math.max(1, Date.parse(check.expiresAt) - Date.now()));
73
- try {
74
- const evidence = { method: "oauth_browser", issuer: session.issuer, clientId: session.clientId, redirectUri: session.redirectUri };
75
- if (!matchesConsoleBrowserEvidence(input.configuration, evidence))
76
- throw new Error("The browser login did not use the Target's client registration and native callback.");
77
- const credentials = Object.fromEntries(Object.keys(requirement).map((name) => [name, input.schemes[name].kind === "bearer" ? session.accessToken : supplied[name]]));
78
- await input.verify(credentials, check.expectations);
79
- await send({ action: "complete", configuration: input.configuration, evidence, credentials, expectations: check.expectations });
80
- }
81
- finally {
82
- // Verification sessions never replace the customer's saved login.
83
- // Revoke the temporary grant when the provider advertises an endpoint.
84
- if (session.revocationUrl) {
85
- try {
86
- const response = await fetch(session.revocationUrl, { method: "POST", redirect: "error", credentials: "omit", signal: AbortSignal.timeout(10_000), headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ token: session.refreshToken ?? session.accessToken, token_type_hint: session.refreshToken ? "refresh_token" : "access_token", client_id: session.clientId }) });
87
- void response.body?.cancel().catch(() => { });
88
- revoked = response.status === 200;
89
- }
90
- catch {
91
- revoked = false;
92
- }
93
- }
94
- }
95
- }
96
- catch (error) {
97
- // Report only that the attempt ended. Never send provider errors, identity
98
- // values or credentials, and never replace the original local error. A
99
- // consumed check rejects this report, preserving any completed API proof.
100
- try {
101
- await send({ action: "fail" }, 5_000);
102
- }
103
- catch { /* Best effort; the Console can still expire the check. */ }
104
- throw error;
105
- }
106
- return { ok: true, method: "oauth_browser", console_verified: true, revoked };
107
- }
@@ -1,45 +0,0 @@
1
- export interface ConsoleLoginConfiguration {
2
- baseUrl: string;
3
- environment: string | null;
4
- operation: string;
5
- request: {
6
- method: string;
7
- path: string;
8
- graphqlField: string | null;
9
- graphqlQuery: string | null;
10
- };
11
- requirements: Record<string, string[]>[];
12
- issuer: string;
13
- clientId: string;
14
- discoveryUrl: string | null;
15
- authorizationUrl: string | null;
16
- tokenUrl: string | null;
17
- redirectUri: string;
18
- scopes: string[];
19
- audience: string | null;
20
- resource: string | null;
21
- }
22
- export interface ConsoleIdentityExpectation {
23
- kind: "account" | "organization" | "user";
24
- pointer: string;
25
- expected: string | number;
26
- }
27
- export interface ConsoleLoginCheck {
28
- version: 1;
29
- endpoint: string;
30
- ticket: string;
31
- expiresAt: string;
32
- configuration: ConsoleLoginConfiguration;
33
- expectations: ConsoleIdentityExpectation[];
34
- }
35
- export interface ConsoleBrowserEvidence {
36
- method: "oauth_browser";
37
- issuer: string;
38
- clientId: string;
39
- redirectUri: string;
40
- }
41
- /** Compare the generated product's own settings with the reviewed check.
42
- * The downloaded file never supplies the CLI's OAuth or API destination. */
43
- export declare function sameConsoleLoginConfiguration(left: ConsoleLoginConfiguration, right: ConsoleLoginConfiguration): boolean;
44
- export declare function matchesConsoleBrowserEvidence(config: ConsoleLoginConfiguration, evidence: ConsoleBrowserEvidence): boolean;
45
- //# sourceMappingURL=console-login-contract.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"console-login-contract.d.ts","sourceRoot":"","sources":["../src/console-login-contract.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACpG,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AACD,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,SAAS,GAAG,cAAc,GAAG,MAAM,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B;AACD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,yBAAyB,CAAC;IACzC,YAAY,EAAE,0BAA0B,EAAE,CAAC;CAC5C;AACD,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAQD;4EAC4E;AAC5E,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAOxH;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,yBAAyB,EAAE,QAAQ,EAAE,sBAAsB,GAAG,OAAO,CAU1H"}
@@ -1,40 +0,0 @@
1
- function canonical(value) {
2
- if (Array.isArray(value))
3
- return "[" + value.map(canonical).join(",") + "]";
4
- if (value && typeof value === "object")
5
- return "{" + Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => JSON.stringify(key) + ":" + canonical(item)).join(",") + "}";
6
- return JSON.stringify(value) ?? "null";
7
- }
8
- /** Compare the generated product's own settings with the reviewed check.
9
- * The downloaded file never supplies the CLI's OAuth or API destination. */
10
- export function sameConsoleLoginConfiguration(left, right) {
11
- const normalize = (value) => ({ ...value,
12
- baseUrl: new URL(value.baseUrl).href,
13
- scopes: [...new Set(value.scopes)].sort(),
14
- requirements: value.requirements.map((entry) => Object.fromEntries(Object.entries(entry).map(([key, scopes]) => [key, [...new Set(scopes)].sort()]))),
15
- });
16
- try {
17
- return canonical(normalize(left)) === canonical(normalize(right));
18
- }
19
- catch {
20
- return false;
21
- }
22
- }
23
- export function matchesConsoleBrowserEvidence(config, evidence) {
24
- try {
25
- if (evidence.method !== "oauth_browser" || evidence.issuer !== config.issuer || evidence.clientId !== config.clientId)
26
- return false;
27
- const configured = new URL(config.redirectUri), actual = new URL(evidence.redirectUri);
28
- if (configured.protocol !== "http:" || !["127.0.0.1", "[::1]"].includes(configured.hostname) || configured.username || configured.password || configured.search || configured.hash)
29
- return false;
30
- if (configured.port && configured.port !== actual.port)
31
- return false;
32
- if (!actual.port)
33
- return false;
34
- configured.port = actual.port;
35
- return configured.href === actual.href;
36
- }
37
- catch {
38
- return false;
39
- }
40
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/resources/generate.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,eAAe,EAAoB,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAE3F,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,QAAQ;IAC5C;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACG,GAAG,CACP,IAAI,EAAE,eAAe,EACrB,MAAM,CAAC,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,oBAAoB,CAAC;IA0BhC;;;;;;;;;;;;OAYG;IACG,eAAe,CAAC,MAAM,EAAE,6BAA6B,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAmBtG;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,oCAAoC;AACpC,MAAM,MAAM,gBAAgB,GACxB,eAAe,GACf,iBAAiB,GACjB,cAAc,GACd,aAAa,GACb,oBAAoB,GACpB,wBAAwB,GACxB,gBAAgB,GAChB,mBAAmB,GACnB,gBAAgB,GAChB,kBAAkB,GAClB,kBAAkB,GAClB,cAAc,GACd,eAAe,CAAC;AAEpB,MAAM,WAAW,6BAA6B;IAC5C,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,gDAAgD;AAChD,MAAM,MAAM,4BAA4B,GACpC,eAAe,GACf,aAAa,GACb,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,kBAAkB,GAClB,cAAc,GACd,eAAe,CAAC"}
@@ -1,47 +0,0 @@
1
- import { HttpCore, type RequestOptions } from "../core/http.js";
2
- import { PagePromise } from "../core/pagination.js";
3
- import { ResponseParseError, TransportError, UnexpectedApiError, ValidationError, BadRequestError, ForbiddenError, InternalServerError, NotFoundError, RateLimitedError, UnauthorizedError } from "../errors.js";
4
- import type { PublicationId, PublicationRead, PublicationResponseRead, ReleaseId } from "../types.js";
5
- export declare class PublicationsResource {
6
- private readonly _core;
7
- constructor(_core: HttpCore);
8
- /**
9
- * List publications
10
- *
11
- * Auto-paginates: `for await (const item of …)` walks every page.
12
- * `GET /publications`
13
- */
14
- list(params?: PublicationsListParams, options?: RequestOptions): PagePromise<PublicationRead, PublicationsListError>;
15
- /**
16
- * Get publishing status
17
- *
18
- * Returns the registry publishing status for a release. A status in another organization returns
19
- * 404 resource_not_found.
20
- * `GET /publications/{publication_id}`
21
- */
22
- get(publicationId: PublicationId, options?: RequestOptions): Promise<PublicationResponseRead>;
23
- }
24
- export interface PublicationsListParams {
25
- /**
26
- * Maximum number of resources to return. Omit for 20; otherwise supply base-10 digits
27
- * representing an integer from 1 to 100. Empty, malformed, or out-of-range values return 400
28
- * input_invalid. List query parameters must appear only once; repeated or unrecognized parameters
29
- * return 400 query_param_invalid.
30
- */
31
- limit?: number;
32
- /**
33
- * Opaque cursor from the preceding page's next_cursor. Valid only for the same organization,
34
- * operation, filters, and ordering that issued it. Omit to start at the first page. Empty or
35
- * malformed cursors, and cursors issued for different filters, return 400 cursor_invalid; start
36
- * again from the first page. Repeated cursors return 400 query_param_invalid. The page limit may
37
- * change between requests.
38
- */
39
- cursor?: string;
40
- /** Only publications of this release. */
41
- releaseId?: ReleaseId;
42
- }
43
- /** Typed errors `list` can throw. */
44
- export type PublicationsListError = BadRequestError | UnauthorizedError | ForbiddenError | NotFoundError | RateLimitedError | InternalServerError | UnexpectedApiError | ResponseParseError | TransportError | ValidationError;
45
- /** Typed errors `get` can throw. */
46
- export type PublicationsGetError = UnauthorizedError | ForbiddenError | NotFoundError | RateLimitedError | InternalServerError | UnexpectedApiError | ResponseParseError | TransportError | ValidationError;
47
- //# sourceMappingURL=publications.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"publications.d.ts","sourceRoot":"","sources":["../../src/resources/publications.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAY,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAEV,aAAa,EAGb,eAAe,EAEf,uBAAuB,EACvB,SAAS,EACV,MAAM,aAAa,CAAC;AAErB,qBAAa,oBAAoB;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,QAAQ;IAC5C;;;;;OAKG;IACH,IAAI,CACF,MAAM,CAAC,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE,cAAc,GACvB,WAAW,CAAC,eAAe,EAAE,qBAAqB,CAAC;IA+BtD;;;;;;OAMG;IACG,GAAG,CAAC,aAAa,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,uBAAuB,CAAC;CAiBpG;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,qCAAqC;AACrC,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf,iBAAiB,GACjB,cAAc,GACd,aAAa,GACb,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,kBAAkB,GAClB,cAAc,GACd,eAAe,CAAC;AAEpB,oCAAoC;AACpC,MAAM,MAAM,oBAAoB,GAC5B,iBAAiB,GACjB,cAAc,GACd,aAAa,GACb,gBAAgB,GAChB,mBAAmB,GACnB,kBAAkB,GAClB,kBAAkB,GAClB,cAAc,GACd,eAAe,CAAC"}
@@ -1,70 +0,0 @@
1
- // typeship — publications resource.
2
- // Generated by typeship — https://typeship.dev
3
- import { paginate } from "../core/pagination.js";
4
- import { BadRequestError, ForbiddenError, InternalServerError, NotFoundError, RateLimitedError, UnauthorizedError, } from "../errors.js";
5
- export class PublicationsResource {
6
- _core;
7
- constructor(_core) {
8
- this._core = _core;
9
- }
10
- /**
11
- * List publications
12
- *
13
- * Auto-paginates: `for await (const item of …)` walks every page.
14
- * `GET /publications`
15
- */
16
- list(params, options) {
17
- return paginate(this._core, {
18
- method: "GET",
19
- path: "/publications",
20
- security: [{ "apiKey": [] }],
21
- query: {
22
- limit: params?.limit,
23
- cursor: params?.cursor,
24
- release_id: params?.releaseId,
25
- },
26
- errors: {
27
- "400": BadRequestError,
28
- "401": UnauthorizedError,
29
- "403": ForbiddenError,
30
- "404": NotFoundError,
31
- "429": RateLimitedError,
32
- "500": InternalServerError,
33
- },
34
- idempotent: true,
35
- schemaKey: "publications.list",
36
- options,
37
- }, {
38
- style: "cursor",
39
- itemsField: "data",
40
- cursorParam: "cursor",
41
- nextCursorField: "next_cursor",
42
- hasMoreField: "has_more",
43
- limitParam: "limit",
44
- });
45
- }
46
- /**
47
- * Get publishing status
48
- *
49
- * Returns the registry publishing status for a release. A status in another organization returns
50
- * 404 resource_not_found.
51
- * `GET /publications/{publication_id}`
52
- */
53
- async get(publicationId, options) {
54
- return this._core.requestData({
55
- method: "GET",
56
- path: `/publications/${encodeURIComponent(String(publicationId))}`,
57
- security: [{ "apiKey": [] }],
58
- errors: {
59
- "401": UnauthorizedError,
60
- "403": ForbiddenError,
61
- "404": NotFoundError,
62
- "429": RateLimitedError,
63
- "500": InternalServerError,
64
- },
65
- idempotent: true,
66
- schemaKey: "publications.get",
67
- options,
68
- });
69
- }
70
- }
@@ -1,88 +0,0 @@
1
- import { openSync, readSync, closeSync, fstatSync, constants } from "node:fs";
2
- import { oauthJsonRequest } from "./oauth-request.js";
3
- import { sameConsoleLoginConfiguration, matchesConsoleBrowserEvidence, type ConsoleLoginCheck, type ConsoleLoginConfiguration } from "./console-login-contract.js";
4
- import { type OAuthLoginSession } from "./oauth-login.js";
5
- import { parseNamedCredentials, type CredentialSchemes, type NamedCredentials } from "./named-credentials.js";
6
-
7
- function readCheck(path: string): ConsoleLoginCheck {
8
- let fd: number | undefined;
9
- try {
10
- fd = openSync(path, constants.O_RDONLY | constants.O_NONBLOCK);
11
- if (!fstatSync(fd).isFile()) throw new Error();
12
- const buffer = Buffer.alloc(65_537);
13
- let size = 0;
14
- while (size < buffer.length) { const n = readSync(fd, buffer, size, buffer.length - size, null); if (!n) break; size += n; }
15
- if (size > 65_536) throw new Error();
16
- const value = JSON.parse(buffer.subarray(0, size).toString("utf8")) as ConsoleLoginCheck;
17
- if (value.version !== 1 || typeof value.ticket !== "string" || !/^[A-Za-z0-9_-]{43}$/.test(value.ticket) || !value.configuration || !Array.isArray(value.expectations) || !value.expectations.length || value.expectations.length > 3) throw new Error();
18
- const endpoint = new URL(value.endpoint);
19
- const development = endpoint.protocol === "http:" && ["127.0.0.1", "[::1]"].includes(endpoint.hostname);
20
- if (!(endpoint.origin === "https://typeship.dev" || development) || endpoint.pathname !== "/api/authentication/browser" || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) throw new Error();
21
- const remaining = Date.parse(value.expiresAt) - Date.now();
22
- if (!Number.isFinite(remaining) || remaining <= 0 || remaining > 600_000) throw new Error();
23
- return value;
24
- } catch { throw new Error("Download a new login check from your Typeship Console and pass its JSON file to --console-check. Checks expire after ten minutes."); }
25
- finally { if (fd !== undefined) closeSync(fd); }
26
- }
27
-
28
- /** No traffic to Typeship occurs without the explicit --console-check action.
29
- * Only the credentials selected for the identity read leave this process;
30
- * refresh tokens and other stored logins are never sent to the Console. */
31
- export async function checkConsoleBrowserLogin(input: {
32
- file: string;
33
- configuration: ConsoleLoginConfiguration;
34
- schemes: CredentialSchemes;
35
- credentials: NamedCredentials;
36
- login(timeoutMs: number): Promise<OAuthLoginSession>;
37
- verify(credentials: NamedCredentials, expectations: ConsoleLoginCheck["expectations"]): Promise<void>;
38
- progress(message: string): void;
39
- }): Promise<{ ok: true; method: "oauth_browser"; console_verified: true; revoked: boolean | null }> {
40
- const check = readCheck(input.file);
41
- if (!sameConsoleLoginConfiguration(input.configuration, check.configuration)) throw new Error("This CLI's authentication settings do not match the saved Target. Regenerate the CLI, select the matching environment, and download a new check.");
42
- const send = async (body: Record<string, unknown>, timeoutMs = 30_000) => {
43
- const response = await oauthJsonRequest(check.endpoint, { method: "POST", headers: { "Content-Type": "application/json", Accept: "application/json" }, body: JSON.stringify({ ticket: check.ticket, ...body }) }, timeoutMs);
44
- if (response.status === 422) throw new Error("Typeship could not verify this login. Check the expected identity, API permissions and saved Target settings, then download a new check.");
45
- if (response.status !== 200 || response.data?.ok !== true) throw new Error("The Console check expired, was already used, changed, or could not be completed. Download a new check and try again.");
46
- return response.data;
47
- };
48
- await send({ action: "inspect" });
49
- let revoked: boolean | null = null;
50
- try {
51
- const supplied = parseNamedCredentials(input.credentials, input.schemes);
52
- // Only a complete alternative that uses the fresh browser token proves
53
- // browser access. An unrelated key-only alternative is not sufficient.
54
- const requirement = input.configuration.requirements.find((entry) => {
55
- const names = Object.keys(entry);
56
- if (!names.some((name) => input.schemes[name]?.kind === "bearer") || !names.every((name) => input.schemes[name]?.kind === "bearer" || supplied[name] !== undefined)) return false;
57
- const selected = input.configuration.requirements.find((candidate) => Object.keys(candidate).every((name) => names.includes(name)));
58
- return selected && Object.keys(selected).some((name) => input.schemes[name]?.kind === "bearer");
59
- });
60
- if (!requirement) throw new Error("Supply the additional named credentials required by the identity read with --credentials @file or environment variables.");
61
- input.progress("This check runs a temporary browser login. Typeship will receive only the access token and any additional credentials required for the identity read; refresh tokens stay on this computer.");
62
- const session = await input.login(Math.max(1, Date.parse(check.expiresAt) - Date.now()));
63
- try {
64
- const evidence = { method: "oauth_browser" as const, issuer: session.issuer, clientId: session.clientId, redirectUri: session.redirectUri };
65
- if (!matchesConsoleBrowserEvidence(input.configuration, evidence)) throw new Error("The browser login did not use the Target's client registration and native callback.");
66
- const credentials: NamedCredentials = Object.fromEntries(Object.keys(requirement).map((name) => [name, input.schemes[name]!.kind === "bearer" ? session.accessToken : supplied[name]! ]));
67
- await input.verify(credentials, check.expectations);
68
- await send({ action: "complete", configuration: input.configuration, evidence, credentials, expectations: check.expectations });
69
- } finally {
70
- // Verification sessions never replace the customer's saved login.
71
- // Revoke the temporary grant when the provider advertises an endpoint.
72
- if (session.revocationUrl) {
73
- try {
74
- const response = await fetch(session.revocationUrl, { method: "POST", redirect: "error", credentials: "omit", signal: AbortSignal.timeout(10_000), headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ token: session.refreshToken ?? session.accessToken, token_type_hint: session.refreshToken ? "refresh_token" : "access_token", client_id: session.clientId }) });
75
- void response.body?.cancel().catch(() => {});
76
- revoked = response.status === 200;
77
- } catch { revoked = false; }
78
- }
79
- }
80
- } catch (error) {
81
- // Report only that the attempt ended. Never send provider errors, identity
82
- // values or credentials, and never replace the original local error. A
83
- // consumed check rejects this report, preserving any completed API proof.
84
- try { await send({ action: "fail" }, 5_000); } catch { /* Best effort; the Console can still expire the check. */ }
85
- throw error;
86
- }
87
- return { ok: true, method: "oauth_browser", console_verified: true, revoked };
88
- }
@@ -1,65 +0,0 @@
1
-
2
- export interface ConsoleLoginConfiguration {
3
- baseUrl: string;
4
- environment: string | null;
5
- operation: string;
6
- request: { method: string; path: string; graphqlField: string | null; graphqlQuery: string | null };
7
- requirements: Record<string, string[]>[];
8
- issuer: string;
9
- clientId: string;
10
- discoveryUrl: string | null;
11
- authorizationUrl: string | null;
12
- tokenUrl: string | null;
13
- redirectUri: string;
14
- scopes: string[];
15
- audience: string | null;
16
- resource: string | null;
17
- }
18
- export interface ConsoleIdentityExpectation {
19
- kind: "account" | "organization" | "user";
20
- pointer: string;
21
- expected: string | number;
22
- }
23
- export interface ConsoleLoginCheck {
24
- version: 1;
25
- endpoint: string;
26
- ticket: string;
27
- expiresAt: string;
28
- configuration: ConsoleLoginConfiguration;
29
- expectations: ConsoleIdentityExpectation[];
30
- }
31
- export interface ConsoleBrowserEvidence {
32
- method: "oauth_browser";
33
- issuer: string;
34
- clientId: string;
35
- redirectUri: string;
36
- }
37
-
38
- function canonical(value: unknown): string {
39
- if (Array.isArray(value)) return "[" + value.map(canonical).join(",") + "]";
40
- if (value && typeof value === "object") return "{" + Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => JSON.stringify(key) + ":" + canonical(item)).join(",") + "}";
41
- return JSON.stringify(value) ?? "null";
42
- }
43
-
44
- /** Compare the generated product's own settings with the reviewed check.
45
- * The downloaded file never supplies the CLI's OAuth or API destination. */
46
- export function sameConsoleLoginConfiguration(left: ConsoleLoginConfiguration, right: ConsoleLoginConfiguration): boolean {
47
- const normalize = (value: ConsoleLoginConfiguration) => ({ ...value,
48
- baseUrl: new URL(value.baseUrl).href,
49
- scopes: [...new Set(value.scopes)].sort(),
50
- requirements: value.requirements.map((entry) => Object.fromEntries(Object.entries(entry).map(([key, scopes]) => [key, [...new Set(scopes)].sort()]))),
51
- });
52
- try { return canonical(normalize(left)) === canonical(normalize(right)); } catch { return false; }
53
- }
54
-
55
- export function matchesConsoleBrowserEvidence(config: ConsoleLoginConfiguration, evidence: ConsoleBrowserEvidence): boolean {
56
- try {
57
- if (evidence.method !== "oauth_browser" || evidence.issuer !== config.issuer || evidence.clientId !== config.clientId) return false;
58
- const configured = new URL(config.redirectUri), actual = new URL(evidence.redirectUri);
59
- if (configured.protocol !== "http:" || !["127.0.0.1", "[::1]"].includes(configured.hostname) || configured.username || configured.password || configured.search || configured.hash) return false;
60
- if (configured.port && configured.port !== actual.port) return false;
61
- if (!actual.port) return false;
62
- configured.port = actual.port;
63
- return configured.href === actual.href;
64
- } catch { return false; }
65
- }
@@ -1,140 +0,0 @@
1
- // typeship — publications resource.
2
- // Generated by typeship — https://typeship.dev
3
-
4
- import { HttpCore, type RequestOptions } from "../core/http.js";
5
- import { paginate, PagePromise } from "../core/pagination.js";
6
- import {
7
- ResponseParseError,
8
- TransportError,
9
- UnexpectedApiError,
10
- ValidationError,
11
- BadRequestError,
12
- ForbiddenError,
13
- InternalServerError,
14
- NotFoundError,
15
- RateLimitedError,
16
- UnauthorizedError,
17
- } from "../errors.js";
18
- import type {
19
- Publication,
20
- PublicationId,
21
- PublicationList,
22
- PublicationListRead,
23
- PublicationRead,
24
- PublicationResponse,
25
- PublicationResponseRead,
26
- ReleaseId,
27
- } from "../types.js";
28
-
29
- export class PublicationsResource {
30
- constructor(private readonly _core: HttpCore) {}
31
- /**
32
- * List publications
33
- *
34
- * Auto-paginates: `for await (const item of …)` walks every page.
35
- * `GET /publications`
36
- */
37
- list(
38
- params?: PublicationsListParams,
39
- options?: RequestOptions,
40
- ): PagePromise<PublicationRead, PublicationsListError> {
41
- return paginate<PublicationRead, PublicationsListError>(this._core, {
42
- method: "GET",
43
- path: "/publications",
44
- security: [{"apiKey":[]}],
45
- query: {
46
- limit: params?.limit,
47
- cursor: params?.cursor,
48
- release_id: params?.releaseId,
49
- },
50
- errors: {
51
- "400": BadRequestError,
52
- "401": UnauthorizedError,
53
- "403": ForbiddenError,
54
- "404": NotFoundError,
55
- "429": RateLimitedError,
56
- "500": InternalServerError,
57
- },
58
- idempotent: true,
59
- schemaKey: "publications.list",
60
- options,
61
- }, {
62
- style: "cursor",
63
- itemsField: "data",
64
- cursorParam: "cursor",
65
- nextCursorField: "next_cursor",
66
- hasMoreField: "has_more",
67
- limitParam: "limit",
68
- });
69
- }
70
-
71
- /**
72
- * Get publishing status
73
- *
74
- * Returns the registry publishing status for a release. A status in another organization returns
75
- * 404 resource_not_found.
76
- * `GET /publications/{publication_id}`
77
- */
78
- async get(publicationId: PublicationId, options?: RequestOptions): Promise<PublicationResponseRead> {
79
- return this._core.requestData<PublicationResponseRead, PublicationsGetError>({
80
- method: "GET",
81
- path: `/publications/${encodeURIComponent(String(publicationId))}`,
82
- security: [{"apiKey":[]}],
83
- errors: {
84
- "401": UnauthorizedError,
85
- "403": ForbiddenError,
86
- "404": NotFoundError,
87
- "429": RateLimitedError,
88
- "500": InternalServerError,
89
- },
90
- idempotent: true,
91
- schemaKey: "publications.get",
92
- options,
93
- });
94
- }
95
- }
96
-
97
- export interface PublicationsListParams {
98
- /**
99
- * Maximum number of resources to return. Omit for 20; otherwise supply base-10 digits
100
- * representing an integer from 1 to 100. Empty, malformed, or out-of-range values return 400
101
- * input_invalid. List query parameters must appear only once; repeated or unrecognized parameters
102
- * return 400 query_param_invalid.
103
- */
104
- limit?: number;
105
- /**
106
- * Opaque cursor from the preceding page's next_cursor. Valid only for the same organization,
107
- * operation, filters, and ordering that issued it. Omit to start at the first page. Empty or
108
- * malformed cursors, and cursors issued for different filters, return 400 cursor_invalid; start
109
- * again from the first page. Repeated cursors return 400 query_param_invalid. The page limit may
110
- * change between requests.
111
- */
112
- cursor?: string;
113
- /** Only publications of this release. */
114
- releaseId?: ReleaseId;
115
- }
116
-
117
- /** Typed errors `list` can throw. */
118
- export type PublicationsListError =
119
- | BadRequestError
120
- | UnauthorizedError
121
- | ForbiddenError
122
- | NotFoundError
123
- | RateLimitedError
124
- | InternalServerError
125
- | UnexpectedApiError
126
- | ResponseParseError
127
- | TransportError
128
- | ValidationError;
129
-
130
- /** Typed errors `get` can throw. */
131
- export type PublicationsGetError =
132
- | UnauthorizedError
133
- | ForbiddenError
134
- | NotFoundError
135
- | RateLimitedError
136
- | InternalServerError
137
- | UnexpectedApiError
138
- | ResponseParseError
139
- | TransportError
140
- | ValidationError;