@nylas-labs/cli-kit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/dashboard.d.ts +162 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +383 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/dpop.d.ts +32 -0
- package/dist/dpop.d.ts.map +1 -0
- package/dist/dpop.js +85 -0
- package/dist/dpop.js.map +1 -0
- package/dist/gateway.d.ts +76 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +144 -0
- package/dist/gateway.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/v3.d.ts +369 -0
- package/dist/v3.d.ts.map +1 -0
- package/dist/v3.js +420 -0
- package/dist/v3.js.map +1 -0
- package/package.json +29 -0
package/dist/dpop.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DPoP (RFC 9449) proof generation with Ed25519 via WebCrypto.
|
|
3
|
+
*
|
|
4
|
+
* Wire-compatible with the Nylas dashboard-account CLI token binding:
|
|
5
|
+
* header {typ: "dpop+jwt", alg: "EdDSA", jwk: {kty, crv, x}} and claims
|
|
6
|
+
* {jti, htm, htu, iat} plus `ath` (SHA-256 of the access token) when bound.
|
|
7
|
+
*
|
|
8
|
+
* Uses only WebCrypto + fetch-era globals so it runs in Node >= 20 and on
|
|
9
|
+
* Cloudflare Workers.
|
|
10
|
+
*/
|
|
11
|
+
const textEncoder = new TextEncoder();
|
|
12
|
+
function base64url(data) {
|
|
13
|
+
const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
14
|
+
let bin = '';
|
|
15
|
+
for (const b of bytes)
|
|
16
|
+
bin += String.fromCharCode(b);
|
|
17
|
+
return btoa(bin).replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '');
|
|
18
|
+
}
|
|
19
|
+
/** Strips fragments; dashboard-account validates `htu` with query params intact. */
|
|
20
|
+
function normalizeHtu(rawUrl) {
|
|
21
|
+
const u = new URL(rawUrl);
|
|
22
|
+
u.hash = '';
|
|
23
|
+
return u.toString();
|
|
24
|
+
}
|
|
25
|
+
export class DpopKey {
|
|
26
|
+
privateKey;
|
|
27
|
+
publicJwk;
|
|
28
|
+
privateJwk;
|
|
29
|
+
constructor(privateKey, publicJwk, privateJwk) {
|
|
30
|
+
this.privateKey = privateKey;
|
|
31
|
+
this.publicJwk = publicJwk;
|
|
32
|
+
this.privateJwk = privateJwk;
|
|
33
|
+
}
|
|
34
|
+
static async generate() {
|
|
35
|
+
const pair = (await crypto.subtle.generateKey({ name: 'Ed25519' }, true, [
|
|
36
|
+
'sign',
|
|
37
|
+
'verify',
|
|
38
|
+
]));
|
|
39
|
+
const privateJwk = await crypto.subtle.exportKey('jwk', pair.privateKey);
|
|
40
|
+
return DpopKey.fromStored({ privateJwk });
|
|
41
|
+
}
|
|
42
|
+
static async fromStored(stored) {
|
|
43
|
+
const jwk = stored.privateJwk;
|
|
44
|
+
if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519' || !jwk.x || !jwk.d) {
|
|
45
|
+
throw new Error('DPoP key must be an OKP/Ed25519 private JWK');
|
|
46
|
+
}
|
|
47
|
+
const privateKey = await crypto.subtle.importKey('jwk', jwk, { name: 'Ed25519' }, true, ['sign']);
|
|
48
|
+
return new DpopKey(privateKey, { kty: 'OKP', crv: 'Ed25519', x: jwk.x }, jwk);
|
|
49
|
+
}
|
|
50
|
+
/** Serializable form for persistence (contains the private key). */
|
|
51
|
+
toStored() {
|
|
52
|
+
return { privateJwk: this.privateJwk };
|
|
53
|
+
}
|
|
54
|
+
/** RFC 7638 JWK thumbprint of the public key. */
|
|
55
|
+
async thumbprint() {
|
|
56
|
+
const canonical = `{"crv":"Ed25519","kty":"OKP","x":"${this.publicJwk.x}"}`;
|
|
57
|
+
const hash = await crypto.subtle.digest('SHA-256', textEncoder.encode(canonical));
|
|
58
|
+
return base64url(hash);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generates a DPoP proof JWT for one HTTP request. When `accessToken` is
|
|
62
|
+
* provided the proof is bound to it via the `ath` claim.
|
|
63
|
+
*/
|
|
64
|
+
async proof(method, url, accessToken) {
|
|
65
|
+
const header = {
|
|
66
|
+
typ: 'dpop+jwt',
|
|
67
|
+
alg: 'EdDSA',
|
|
68
|
+
jwk: this.publicJwk,
|
|
69
|
+
};
|
|
70
|
+
const claims = {
|
|
71
|
+
jti: crypto.randomUUID(),
|
|
72
|
+
htm: method.toUpperCase(),
|
|
73
|
+
htu: normalizeHtu(url),
|
|
74
|
+
iat: Math.floor(Date.now() / 1000),
|
|
75
|
+
};
|
|
76
|
+
if (accessToken) {
|
|
77
|
+
const hash = await crypto.subtle.digest('SHA-256', textEncoder.encode(accessToken));
|
|
78
|
+
claims.ath = base64url(hash);
|
|
79
|
+
}
|
|
80
|
+
const signingInput = `${base64url(textEncoder.encode(JSON.stringify(header)))}.${base64url(textEncoder.encode(JSON.stringify(claims)))}`;
|
|
81
|
+
const signature = await crypto.subtle.sign({ name: 'Ed25519' }, this.privateKey, textEncoder.encode(signingInput));
|
|
82
|
+
return `${signingInput}.${base64url(signature)}`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=dpop.js.map
|
package/dist/dpop.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dpop.js","sourceRoot":"","sources":["../src/dpop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client for the Nylas dashboard-api-gateway GraphQL API.
|
|
3
|
+
*
|
|
4
|
+
* Scope: applications, API keys, and (agent-account) grants only. Org-level
|
|
5
|
+
* surfaces such as inbox domains live on dashboard-account — see dashboard.ts.
|
|
6
|
+
*
|
|
7
|
+
* Operations and shapes mirror the official Go CLI
|
|
8
|
+
* (cli/internal/adapters/dashboard/gateway_client.go).
|
|
9
|
+
*/
|
|
10
|
+
import type { DashboardTokens } from './dashboard.js';
|
|
11
|
+
import type { DpopKey } from './dpop.js';
|
|
12
|
+
export declare const GATEWAY_URLS: {
|
|
13
|
+
readonly us: 'https://dashboard-api-gateway.us.nylas.com/graphql';
|
|
14
|
+
readonly eu: 'https://dashboard-api-gateway.eu.nylas.com/graphql';
|
|
15
|
+
};
|
|
16
|
+
export type Region = keyof typeof GATEWAY_URLS;
|
|
17
|
+
export type GatewayApplication = {
|
|
18
|
+
applicationId: string;
|
|
19
|
+
organizationId: string;
|
|
20
|
+
region: string;
|
|
21
|
+
environment?: string;
|
|
22
|
+
branding?: {
|
|
23
|
+
name?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export type GatewayCreatedApplication = GatewayApplication & {
|
|
28
|
+
clientSecret: string;
|
|
29
|
+
};
|
|
30
|
+
export type GatewayApiKey = {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
status: string;
|
|
34
|
+
permissions?: string[];
|
|
35
|
+
expiresAt?: number;
|
|
36
|
+
createdAt?: number;
|
|
37
|
+
};
|
|
38
|
+
export type GatewayCreatedApiKey = GatewayApiKey & {
|
|
39
|
+
apiKey: string;
|
|
40
|
+
};
|
|
41
|
+
export declare class GatewayError extends Error {
|
|
42
|
+
readonly errors: GraphqlError[];
|
|
43
|
+
constructor(message: string, errors?: GraphqlError[]);
|
|
44
|
+
}
|
|
45
|
+
type GraphqlError = {
|
|
46
|
+
message?: string;
|
|
47
|
+
extensions?: {
|
|
48
|
+
message?: string;
|
|
49
|
+
code?: string;
|
|
50
|
+
supportId?: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export declare class GatewayClient {
|
|
54
|
+
private readonly dpop;
|
|
55
|
+
private readonly urls;
|
|
56
|
+
private readonly fetchImpl;
|
|
57
|
+
constructor(dpop: DpopKey, urls?: Record<Region, string>, fetchImpl?: typeof fetch);
|
|
58
|
+
listApplications(tokens: DashboardTokens, region: Region, orgPublicId: string): Promise<GatewayApplication[]>;
|
|
59
|
+
createApplication(tokens: DashboardTokens, region: Region, orgPublicId: string, options: {
|
|
60
|
+
region: Region;
|
|
61
|
+
environment?: string;
|
|
62
|
+
branding?: {
|
|
63
|
+
name?: string;
|
|
64
|
+
description?: string;
|
|
65
|
+
};
|
|
66
|
+
}): Promise<GatewayCreatedApplication>;
|
|
67
|
+
listApiKeys(tokens: DashboardTokens, region: Region, appId: string): Promise<GatewayApiKey[]>;
|
|
68
|
+
createApiKey(tokens: DashboardTokens, region: Region, appId: string, options?: {
|
|
69
|
+
name?: string;
|
|
70
|
+
expiresIn?: number;
|
|
71
|
+
}): Promise<GatewayCreatedApiKey>;
|
|
72
|
+
revokeApiKey(tokens: DashboardTokens, region: Region, appId: string, apiKeyId: string): Promise<void>;
|
|
73
|
+
private query;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=gateway.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
|
package/dist/gateway.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client for the Nylas dashboard-api-gateway GraphQL API.
|
|
3
|
+
*
|
|
4
|
+
* Scope: applications, API keys, and (agent-account) grants only. Org-level
|
|
5
|
+
* surfaces such as inbox domains live on dashboard-account — see dashboard.ts.
|
|
6
|
+
*
|
|
7
|
+
* Operations and shapes mirror the official Go CLI
|
|
8
|
+
* (cli/internal/adapters/dashboard/gateway_client.go).
|
|
9
|
+
*/
|
|
10
|
+
export const GATEWAY_URLS = {
|
|
11
|
+
us: 'https://dashboard-api-gateway.us.nylas.com/graphql',
|
|
12
|
+
eu: 'https://dashboard-api-gateway.eu.nylas.com/graphql',
|
|
13
|
+
};
|
|
14
|
+
const DEFAULT_HTTP_TIMEOUT_MS = 30_000;
|
|
15
|
+
export class GatewayError extends Error {
|
|
16
|
+
errors;
|
|
17
|
+
constructor(message, errors = []) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.errors = errors;
|
|
20
|
+
this.name = 'GatewayError';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class GatewayClient {
|
|
24
|
+
dpop;
|
|
25
|
+
urls;
|
|
26
|
+
fetchImpl;
|
|
27
|
+
constructor(dpop, urls = GATEWAY_URLS, fetchImpl = fetch) {
|
|
28
|
+
this.dpop = dpop;
|
|
29
|
+
this.urls = urls;
|
|
30
|
+
this.fetchImpl = fetchImpl;
|
|
31
|
+
}
|
|
32
|
+
async listApplications(tokens, region, orgPublicId) {
|
|
33
|
+
const data = await this.query(tokens, region, {
|
|
34
|
+
operationName: 'V3_GetApplications',
|
|
35
|
+
query: `query V3_GetApplications($filter: ApplicationFilter!) {
|
|
36
|
+
applications(filter: $filter) {
|
|
37
|
+
applications { applicationId organizationId region environment branding { name description } }
|
|
38
|
+
}
|
|
39
|
+
}`,
|
|
40
|
+
variables: { filter: { orgPublicId } },
|
|
41
|
+
});
|
|
42
|
+
return data.applications?.applications ?? [];
|
|
43
|
+
}
|
|
44
|
+
async createApplication(tokens, region, orgPublicId, options) {
|
|
45
|
+
const data = await this.query(tokens, region, {
|
|
46
|
+
operationName: 'V3_CreateApplication',
|
|
47
|
+
query: `mutation V3_CreateApplication($orgPublicId: String!, $options: ApplicationOptions!) {
|
|
48
|
+
createApplication(orgPublicId: $orgPublicId, options: $options) {
|
|
49
|
+
applicationId clientSecret organizationId region environment branding { name }
|
|
50
|
+
}
|
|
51
|
+
}`,
|
|
52
|
+
variables: { orgPublicId, options },
|
|
53
|
+
});
|
|
54
|
+
return data.createApplication;
|
|
55
|
+
}
|
|
56
|
+
async listApiKeys(tokens, region, appId) {
|
|
57
|
+
const data = await this.query(tokens, region, {
|
|
58
|
+
operationName: 'V3_ApiKeys',
|
|
59
|
+
query: `query V3_ApiKeys($appId: String!) {
|
|
60
|
+
apiKeys(appId: $appId) { id name status permissions expiresAt createdAt }
|
|
61
|
+
}`,
|
|
62
|
+
variables: { appId },
|
|
63
|
+
});
|
|
64
|
+
return data.apiKeys ?? [];
|
|
65
|
+
}
|
|
66
|
+
async createApiKey(tokens, region, appId, options) {
|
|
67
|
+
const data = await this.query(tokens, region, {
|
|
68
|
+
operationName: 'V3_CreateApiKey',
|
|
69
|
+
query: `mutation V3_CreateApiKey($appId: String!, $options: ApiKeyOptions) {
|
|
70
|
+
createApiKey(appId: $appId, options: $options) {
|
|
71
|
+
id name apiKey status permissions expiresAt createdAt
|
|
72
|
+
}
|
|
73
|
+
}`,
|
|
74
|
+
variables: { appId, options: options ?? {} },
|
|
75
|
+
});
|
|
76
|
+
return data.createApiKey;
|
|
77
|
+
}
|
|
78
|
+
async revokeApiKey(tokens, region, appId, apiKeyId) {
|
|
79
|
+
await this.query(tokens, region, {
|
|
80
|
+
operationName: 'V3_RevokeApiKey',
|
|
81
|
+
query: `mutation V3_RevokeApiKey($appId: String!, $apiKeyId: String!) {
|
|
82
|
+
revokeApiKey(appId: $appId, apiKeyId: $apiKeyId) { id }
|
|
83
|
+
}`,
|
|
84
|
+
variables: { appId, apiKeyId },
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
async query(tokens, region, body) {
|
|
88
|
+
const url = this.urls[region];
|
|
89
|
+
const res = await fetchWithTimeout(this.fetchImpl, url, {
|
|
90
|
+
method: 'POST',
|
|
91
|
+
headers: {
|
|
92
|
+
'Content-Type': 'application/json',
|
|
93
|
+
Authorization: `Bearer ${tokens.userToken}`,
|
|
94
|
+
...(tokens.orgToken ? { 'X-Nylas-Org': tokens.orgToken } : {}),
|
|
95
|
+
DPoP: await this.dpop.proof('POST', url, tokens.userToken),
|
|
96
|
+
},
|
|
97
|
+
body: JSON.stringify(body),
|
|
98
|
+
}, `gateway ${body.operationName}`);
|
|
99
|
+
if (!res.ok) {
|
|
100
|
+
const text = await res.text();
|
|
101
|
+
throw new GatewayError(`gateway ${body.operationName} failed with ${res.status}${text ? `: ${formatErrorBody(text)}` : ''}`);
|
|
102
|
+
}
|
|
103
|
+
const result = (await res.json());
|
|
104
|
+
if (result.errors?.length) {
|
|
105
|
+
throw new GatewayError(`gateway ${body.operationName} errors: ${result.errors.map(formatGraphqlError).join('; ')}`, result.errors);
|
|
106
|
+
}
|
|
107
|
+
if (!result.data) {
|
|
108
|
+
throw new GatewayError(`gateway ${body.operationName} returned no data`);
|
|
109
|
+
}
|
|
110
|
+
return result.data;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function formatGraphqlError(error) {
|
|
114
|
+
const message = error.extensions?.message ?? error.message ?? error.extensions?.code ?? 'unknown error';
|
|
115
|
+
return error.extensions?.supportId ? `${message} (supportId: ${error.extensions.supportId})` : message;
|
|
116
|
+
}
|
|
117
|
+
function formatErrorBody(text) {
|
|
118
|
+
try {
|
|
119
|
+
const parsed = JSON.parse(text);
|
|
120
|
+
if (parsed.errors?.length)
|
|
121
|
+
return parsed.errors.map(formatGraphqlError).join('; ');
|
|
122
|
+
return parsed.error?.message ?? parsed.message ?? text.slice(0, 500);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return text.slice(0, 500);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async function fetchWithTimeout(fetchImpl, input, init, label) {
|
|
129
|
+
const controller = new AbortController();
|
|
130
|
+
const timeout = setTimeout(() => controller.abort(), DEFAULT_HTTP_TIMEOUT_MS);
|
|
131
|
+
try {
|
|
132
|
+
return await fetchImpl(input, { ...init, signal: controller.signal });
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
if (err instanceof Error && err.name === 'AbortError') {
|
|
136
|
+
throw new Error(`${label} timed out after ${DEFAULT_HTTP_TIMEOUT_MS / 1000}s`);
|
|
137
|
+
}
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
clearTimeout(timeout);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { type AuthResponse, DashboardAccountClient, DashboardAccountError, type DashboardOrganization, type DashboardTokens, type DashboardUser, DEFAULT_DASHBOARD_ACCOUNT_URL, type DomainAvailability, type DomainVerificationResult, type InboxDomain, type OrgSwitchResponse, type SessionResponse, type SsoLoginType, type SsoMode, type SsoPollResponse, type SsoStartResponse, } from './dashboard.js';
|
|
2
|
+
export { DpopKey, type StoredDpopKey } from './dpop.js';
|
|
3
|
+
export { GATEWAY_URLS, type GatewayApiKey, type GatewayApplication, GatewayClient, type GatewayCreatedApiKey, type GatewayCreatedApplication, GatewayError, type Region, } from './gateway.js';
|
|
4
|
+
export * from './v3.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,6BAA6B,EAC7B,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACrB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAA;AACvD,OAAO,EACN,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,YAAY,EACZ,KAAK,MAAM,GACX,MAAM,cAAc,CAAA;AACrB,cAAc,SAAS,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { DashboardAccountClient, DashboardAccountError, DEFAULT_DASHBOARD_ACCOUNT_URL, } from './dashboard.js';
|
|
2
|
+
export { DpopKey } from './dpop.js';
|
|
3
|
+
export { GATEWAY_URLS, GatewayClient, GatewayError, } from './gateway.js';
|
|
4
|
+
export * from './v3.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,sBAAsB,EACtB,qBAAqB,EAIrB,6BAA6B,GAU7B,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,OAAO,EAAsB,MAAM,WAAW,CAAA;AACvD,OAAO,EACN,YAAY,EAGZ,aAAa,EAGb,YAAY,GAEZ,MAAM,cAAc,CAAA;AACrB,cAAc,SAAS,CAAA"}
|