nylas 8.1.1 → 8.2.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/lib/cjs/apiClient.js +12 -5
- package/lib/cjs/models/domains.js +2 -0
- package/lib/cjs/models/index.js +3 -0
- package/lib/cjs/models/messages.js +1 -0
- package/lib/cjs/models/serviceAccount.js +99 -0
- package/lib/cjs/models/workspaces.js +2 -0
- package/lib/cjs/nylas.js +4 -0
- package/lib/cjs/resources/applications.js +13 -0
- package/lib/cjs/resources/attachments.js +26 -4
- package/lib/cjs/resources/domains.js +232 -0
- package/lib/cjs/resources/messages.js +2 -1
- package/lib/cjs/resources/redirectUris.js +2 -2
- package/lib/cjs/resources/resource.js +18 -4
- package/lib/cjs/resources/threads.js +2 -1
- package/lib/cjs/resources/workspaces.js +95 -0
- package/lib/cjs/version.js +1 -1
- package/lib/esm/apiClient.js +11 -4
- package/lib/esm/models/domains.js +1 -0
- package/lib/esm/models/index.js +3 -0
- package/lib/esm/models/messages.js +1 -0
- package/lib/esm/models/serviceAccount.js +93 -0
- package/lib/esm/models/workspaces.js +1 -0
- package/lib/esm/nylas.js +4 -0
- package/lib/esm/resources/applications.js +13 -0
- package/lib/esm/resources/attachments.js +26 -4
- package/lib/esm/resources/domains.js +228 -0
- package/lib/esm/resources/messages.js +2 -1
- package/lib/esm/resources/redirectUris.js +2 -2
- package/lib/esm/resources/resource.js +18 -4
- package/lib/esm/resources/threads.js +2 -1
- package/lib/esm/resources/workspaces.js +91 -0
- package/lib/esm/version.js +1 -1
- package/lib/types/apiClient.d.ts +1 -0
- package/lib/types/config.d.ts +6 -0
- package/lib/types/models/agentLists.d.ts +5 -0
- package/lib/types/models/applicationDetails.d.ts +149 -11
- package/lib/types/models/domains.d.ts +177 -0
- package/lib/types/models/events.d.ts +5 -0
- package/lib/types/models/index.d.ts +3 -0
- package/lib/types/models/messages.d.ts +10 -0
- package/lib/types/models/policies.d.ts +6 -2
- package/lib/types/models/redirectUri.d.ts +15 -4
- package/lib/types/models/rules.d.ts +7 -1
- package/lib/types/models/serviceAccount.d.ts +46 -0
- package/lib/types/models/threads.d.ts +7 -0
- package/lib/types/models/workspaces.d.ts +191 -0
- package/lib/types/nylas.d.ts +10 -0
- package/lib/types/resources/applications.d.ts +14 -1
- package/lib/types/resources/attachments.d.ts +17 -4
- package/lib/types/resources/domains.d.ts +137 -0
- package/lib/types/resources/messages.d.ts +4 -2
- package/lib/types/resources/redirectUris.d.ts +2 -2
- package/lib/types/resources/resource.d.ts +2 -0
- package/lib/types/resources/threads.d.ts +3 -2
- package/lib/types/resources/workspaces.d.ts +98 -0
- package/lib/types/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Workspaces = void 0;
|
|
4
|
+
const utils_js_1 = require("../utils.js");
|
|
5
|
+
const resource_js_1 = require("./resource.js");
|
|
6
|
+
/**
|
|
7
|
+
* Nylas Workspaces API
|
|
8
|
+
*
|
|
9
|
+
* Workspaces group grants in a Nylas application by email domain. Grants can be
|
|
10
|
+
* auto-grouped by matching email domain or manually assigned and removed.
|
|
11
|
+
*/
|
|
12
|
+
class Workspaces extends resource_js_1.Resource {
|
|
13
|
+
/**
|
|
14
|
+
* Return all workspaces for the application.
|
|
15
|
+
*
|
|
16
|
+
* The list endpoint is not paginated and returns every workspace as a flat array.
|
|
17
|
+
* @return The list of workspaces.
|
|
18
|
+
*/
|
|
19
|
+
list({ queryParams, overrides, } = {}) {
|
|
20
|
+
return super._list({
|
|
21
|
+
queryParams,
|
|
22
|
+
path: (0, utils_js_1.makePathParams)('/v3/workspaces', {}),
|
|
23
|
+
overrides,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Return a workspace.
|
|
28
|
+
* @return The workspace.
|
|
29
|
+
*/
|
|
30
|
+
find({ workspaceId, overrides, }) {
|
|
31
|
+
return super._find({
|
|
32
|
+
path: (0, utils_js_1.makePathParams)('/v3/workspaces/{workspaceId}', { workspaceId }),
|
|
33
|
+
overrides,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create a workspace.
|
|
38
|
+
* @return The created workspace.
|
|
39
|
+
*/
|
|
40
|
+
create({ requestBody, overrides, }) {
|
|
41
|
+
return super._create({
|
|
42
|
+
path: (0, utils_js_1.makePathParams)('/v3/workspaces', {}),
|
|
43
|
+
requestBody,
|
|
44
|
+
overrides,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Update a workspace.
|
|
49
|
+
*
|
|
50
|
+
* Issued as PATCH; the workspace must be addressed by its UUID.
|
|
51
|
+
* @return The updated workspace.
|
|
52
|
+
*/
|
|
53
|
+
update({ workspaceId, requestBody, overrides, }) {
|
|
54
|
+
return super._updatePatch({
|
|
55
|
+
path: (0, utils_js_1.makePathParams)('/v3/workspaces/{workspaceId}', { workspaceId }),
|
|
56
|
+
requestBody,
|
|
57
|
+
overrides,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Delete a workspace.
|
|
62
|
+
* @return The deletion response.
|
|
63
|
+
*/
|
|
64
|
+
destroy({ workspaceId, overrides, }) {
|
|
65
|
+
return super._destroy({
|
|
66
|
+
path: (0, utils_js_1.makePathParams)('/v3/workspaces/{workspaceId}', { workspaceId }),
|
|
67
|
+
overrides,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Start a background job that auto-groups grants into workspaces by email domain.
|
|
72
|
+
* @return The auto-group job response.
|
|
73
|
+
*/
|
|
74
|
+
autoGroup({ requestBody, overrides, } = {}) {
|
|
75
|
+
return super._create({
|
|
76
|
+
path: (0, utils_js_1.makePathParams)('/v3/workspaces/auto-group', {}),
|
|
77
|
+
requestBody: requestBody ?? {},
|
|
78
|
+
overrides,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Manually assign grants to and/or remove grants from a workspace.
|
|
83
|
+
* @return The assignment response.
|
|
84
|
+
*/
|
|
85
|
+
manualAssign({ workspaceId, requestBody, overrides, }) {
|
|
86
|
+
return super._create({
|
|
87
|
+
path: (0, utils_js_1.makePathParams)('/v3/workspaces/{workspaceId}/manual-assign', {
|
|
88
|
+
workspaceId,
|
|
89
|
+
}),
|
|
90
|
+
requestBody,
|
|
91
|
+
overrides,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.Workspaces = Workspaces;
|
package/lib/cjs/version.js
CHANGED
package/lib/esm/apiClient.js
CHANGED
|
@@ -2,7 +2,7 @@ import { NylasApiError, NylasOAuthError, NylasSdkTimeoutError, } from './models/
|
|
|
2
2
|
import { objKeysToCamelCase, objKeysToSnakeCase } from './utils.js';
|
|
3
3
|
import { SDK_VERSION } from './version.js';
|
|
4
4
|
import { FormDataEncoder } from 'form-data-encoder';
|
|
5
|
-
import { Readable } from 'stream';
|
|
5
|
+
import { Readable } from 'node:stream';
|
|
6
6
|
import { snakeCase } from 'change-case';
|
|
7
7
|
/**
|
|
8
8
|
* The header key for the debugging flow ID
|
|
@@ -63,12 +63,15 @@ export default class APIClient {
|
|
|
63
63
|
...this.headers,
|
|
64
64
|
...overrides?.headers,
|
|
65
65
|
};
|
|
66
|
-
|
|
66
|
+
const defaultHeaders = {
|
|
67
67
|
Accept: 'application/json',
|
|
68
68
|
'User-Agent': `Nylas Node SDK v${SDK_VERSION}`,
|
|
69
|
-
Authorization: `Bearer ${overrides?.apiKey || this.apiKey}`,
|
|
70
69
|
...mergedHeaders,
|
|
71
70
|
};
|
|
71
|
+
if (!overrides?.skipAuth) {
|
|
72
|
+
defaultHeaders.Authorization = `Bearer ${overrides?.apiKey || this.apiKey}`;
|
|
73
|
+
}
|
|
74
|
+
return defaultHeaders;
|
|
72
75
|
}
|
|
73
76
|
async sendRequest(options) {
|
|
74
77
|
const req = await this.newRequest(options);
|
|
@@ -147,7 +150,11 @@ export default class APIClient {
|
|
|
147
150
|
requestOptions.url = this.setRequestUrl(optionParams);
|
|
148
151
|
requestOptions.headers = this.setRequestHeaders(optionParams);
|
|
149
152
|
requestOptions.method = optionParams.method;
|
|
150
|
-
if (optionParams.
|
|
153
|
+
if (optionParams.serializedBody) {
|
|
154
|
+
requestOptions.body = optionParams.serializedBody;
|
|
155
|
+
requestOptions.headers['Content-Type'] = 'application/json';
|
|
156
|
+
}
|
|
157
|
+
else if (optionParams.body) {
|
|
151
158
|
requestOptions.body = JSON.stringify(objKeysToSnakeCase(optionParams.body, ['metadata']) // metadata should remain as is
|
|
152
159
|
);
|
|
153
160
|
requestOptions.headers['Content-Type'] = 'application/json';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/esm/models/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export * from './calendars.js';
|
|
|
8
8
|
export * from './connectors.js';
|
|
9
9
|
export * from './contacts.js';
|
|
10
10
|
export * from './credentials.js';
|
|
11
|
+
export * from './domains.js';
|
|
11
12
|
export * from './drafts.js';
|
|
12
13
|
export * from './error.js';
|
|
13
14
|
export * from './events.js';
|
|
@@ -22,6 +23,8 @@ export * from './redirectUri.js';
|
|
|
22
23
|
export * from './response.js';
|
|
23
24
|
export * from './rules.js';
|
|
24
25
|
export * from './scheduler.js';
|
|
26
|
+
export * from './serviceAccount.js';
|
|
25
27
|
export * from './smartCompose.js';
|
|
26
28
|
export * from './threads.js';
|
|
27
29
|
export * from './webhooks.js';
|
|
30
|
+
export * from './workspaces.js';
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
export var MessageFields;
|
|
5
5
|
(function (MessageFields) {
|
|
6
6
|
MessageFields["STANDARD"] = "standard";
|
|
7
|
+
MessageFields["INCLUDE_BASIC_HEADERS"] = "include_basic_headers";
|
|
7
8
|
MessageFields["INCLUDE_HEADERS"] = "include_headers";
|
|
8
9
|
MessageFields["INCLUDE_TRACKING_OPTIONS"] = "include_tracking_options";
|
|
9
10
|
MessageFields["RAW_MIME"] = "raw_mime";
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { createPrivateKey, createSign, randomInt, } from 'node:crypto';
|
|
2
|
+
const NONCE_LENGTH = 20;
|
|
3
|
+
const NONCE_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
4
|
+
const SIGNED_BODY_METHODS = new Set(['post', 'put', 'patch']);
|
|
5
|
+
function normalizePrivateKey(privateKeyPem) {
|
|
6
|
+
if (Buffer.isBuffer(privateKeyPem) || privateKeyPem.includes('BEGIN')) {
|
|
7
|
+
return privateKeyPem;
|
|
8
|
+
}
|
|
9
|
+
return Buffer.from(privateKeyPem, 'base64').toString('utf8');
|
|
10
|
+
}
|
|
11
|
+
function loadRsaPrivateKey(privateKeyPem) {
|
|
12
|
+
const privateKey = createPrivateKey(normalizePrivateKey(privateKeyPem));
|
|
13
|
+
if (privateKey.asymmetricKeyType !== 'rsa') {
|
|
14
|
+
throw new Error('Service account private key must be RSA.');
|
|
15
|
+
}
|
|
16
|
+
return privateKey;
|
|
17
|
+
}
|
|
18
|
+
export function generateNonce(length = NONCE_LENGTH) {
|
|
19
|
+
if (!Number.isInteger(length) || length <= 0) {
|
|
20
|
+
throw new Error('Nonce length must be a positive integer.');
|
|
21
|
+
}
|
|
22
|
+
let nonce = '';
|
|
23
|
+
for (let i = 0; i < length; i++) {
|
|
24
|
+
nonce += NONCE_ALPHABET[randomInt(NONCE_ALPHABET.length)];
|
|
25
|
+
}
|
|
26
|
+
return nonce;
|
|
27
|
+
}
|
|
28
|
+
function canonicalValue(value) {
|
|
29
|
+
if (value === undefined || typeof value === 'function') {
|
|
30
|
+
return 'null';
|
|
31
|
+
}
|
|
32
|
+
if (Array.isArray(value)) {
|
|
33
|
+
return `[${value.map(canonicalValue).join(',')}]`;
|
|
34
|
+
}
|
|
35
|
+
if (typeof value === 'number' && !Number.isFinite(value)) {
|
|
36
|
+
throw new Error('Service account signing only supports finite numbers.');
|
|
37
|
+
}
|
|
38
|
+
if (value && typeof value === 'object') {
|
|
39
|
+
const data = value;
|
|
40
|
+
return `{${Object.keys(data)
|
|
41
|
+
.filter((key) => {
|
|
42
|
+
const item = data[key];
|
|
43
|
+
return item !== undefined && typeof item !== 'function';
|
|
44
|
+
})
|
|
45
|
+
.sort()
|
|
46
|
+
.map((key) => `${JSON.stringify(key)}:${canonicalValue(data[key])}`)
|
|
47
|
+
.join(',')}}`;
|
|
48
|
+
}
|
|
49
|
+
return JSON.stringify(value);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Serialize JSON deterministically with sorted object keys and no extra
|
|
53
|
+
* whitespace, matching Nylas Service Account signing requirements.
|
|
54
|
+
*/
|
|
55
|
+
export function canonicalJson(data) {
|
|
56
|
+
return canonicalValue(data);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Generates Nylas Service Account request signing headers.
|
|
60
|
+
*/
|
|
61
|
+
export class ServiceAccountSigner {
|
|
62
|
+
constructor({ privateKeyPem, privateKeyId }) {
|
|
63
|
+
this.privateKey = loadRsaPrivateKey(privateKeyPem);
|
|
64
|
+
this.privateKeyId = privateKeyId;
|
|
65
|
+
}
|
|
66
|
+
buildHeaders({ method, path, body, timestamp = Math.floor(Date.now() / 1000), nonce = generateNonce(), }) {
|
|
67
|
+
const methodLower = method.toLowerCase();
|
|
68
|
+
const serializedBody = body && SIGNED_BODY_METHODS.has(methodLower)
|
|
69
|
+
? canonicalJson(body)
|
|
70
|
+
: undefined;
|
|
71
|
+
const signingEnvelope = {
|
|
72
|
+
method: methodLower,
|
|
73
|
+
nonce,
|
|
74
|
+
path,
|
|
75
|
+
timestamp,
|
|
76
|
+
};
|
|
77
|
+
if (serializedBody) {
|
|
78
|
+
signingEnvelope.payload = serializedBody;
|
|
79
|
+
}
|
|
80
|
+
const signature = createSign('RSA-SHA256')
|
|
81
|
+
.update(canonicalJson(signingEnvelope))
|
|
82
|
+
.sign(this.privateKey, 'base64');
|
|
83
|
+
return {
|
|
84
|
+
headers: {
|
|
85
|
+
'X-Nylas-Kid': this.privateKeyId,
|
|
86
|
+
'X-Nylas-Nonce': nonce,
|
|
87
|
+
'X-Nylas-Timestamp': String(timestamp),
|
|
88
|
+
'X-Nylas-Signature': signature,
|
|
89
|
+
},
|
|
90
|
+
serializedBody,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/lib/esm/nylas.js
CHANGED
|
@@ -16,8 +16,10 @@ import { Contacts } from './resources/contacts.js';
|
|
|
16
16
|
import { Attachments } from './resources/attachments.js';
|
|
17
17
|
import { Scheduler } from './resources/scheduler.js';
|
|
18
18
|
import { Notetakers } from './resources/notetakers.js';
|
|
19
|
+
import { Domains } from './resources/domains.js';
|
|
19
20
|
import { Policies } from './resources/policies.js';
|
|
20
21
|
import { Rules } from './resources/rules.js';
|
|
22
|
+
import { Workspaces } from './resources/workspaces.js';
|
|
21
23
|
import { AgentLists } from './resources/agentLists.js';
|
|
22
24
|
/**
|
|
23
25
|
* The entry point to the Node SDK
|
|
@@ -45,8 +47,10 @@ class Nylas {
|
|
|
45
47
|
this.grants = new Grants(this.apiClient);
|
|
46
48
|
this.messages = new Messages(this.apiClient);
|
|
47
49
|
this.notetakers = new Notetakers(this.apiClient);
|
|
50
|
+
this.domains = new Domains(this.apiClient);
|
|
48
51
|
this.policies = new Policies(this.apiClient);
|
|
49
52
|
this.rules = new Rules(this.apiClient);
|
|
53
|
+
this.workspaces = new Workspaces(this.apiClient);
|
|
50
54
|
this.lists = new AgentLists(this.apiClient);
|
|
51
55
|
this.threads = new Threads(this.apiClient);
|
|
52
56
|
this.webhooks = new Webhooks(this.apiClient);
|
|
@@ -24,4 +24,17 @@ export class Applications extends Resource {
|
|
|
24
24
|
overrides,
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Update application details.
|
|
29
|
+
*
|
|
30
|
+
* Each supplied nested object is a full replace, not a deep merge.
|
|
31
|
+
* @returns The updated application details
|
|
32
|
+
*/
|
|
33
|
+
update({ requestBody, overrides, }) {
|
|
34
|
+
return super._updatePatch({
|
|
35
|
+
path: makePathParams('/v3/applications', {}),
|
|
36
|
+
requestBody,
|
|
37
|
+
overrides,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
27
40
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { makePathParams } from '../utils.js';
|
|
2
2
|
import { Resource } from './resource.js';
|
|
3
|
+
import { Readable } from 'node:stream';
|
|
3
4
|
/**
|
|
4
5
|
* Nylas Attachments API
|
|
5
6
|
*
|
|
@@ -20,15 +21,15 @@ export class Attachments extends Resource {
|
|
|
20
21
|
/**
|
|
21
22
|
* Download the attachment data
|
|
22
23
|
*
|
|
23
|
-
* This method returns a
|
|
24
|
+
* This method returns a Web ReadableStream which can be used to stream the attachment data.
|
|
24
25
|
* This is particularly useful for handling large attachments efficiently, as it avoids loading
|
|
25
|
-
* the entire file into memory.
|
|
26
|
-
*
|
|
26
|
+
* the entire file into memory. In Node.js, convert it with Readable.fromWeb() when a
|
|
27
|
+
* NodeJS.ReadableStream is required.
|
|
27
28
|
*
|
|
28
29
|
* @param identifier Grant ID or email account to query
|
|
29
30
|
* @param attachmentId The id of the attachment to download.
|
|
30
31
|
* @param queryParams The query parameters to include in the request
|
|
31
|
-
* @returns {
|
|
32
|
+
* @returns {ReadableStream<Uint8Array>} The ReadableStream containing the file data.
|
|
32
33
|
*/
|
|
33
34
|
download({ identifier, attachmentId, queryParams, overrides, }) {
|
|
34
35
|
return this._getStream({
|
|
@@ -37,6 +38,27 @@ export class Attachments extends Resource {
|
|
|
37
38
|
overrides,
|
|
38
39
|
});
|
|
39
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Download the attachment data as a Node.js readable stream.
|
|
43
|
+
*
|
|
44
|
+
* This is a Node.js convenience wrapper around {@link Attachments.download}. Use
|
|
45
|
+
* {@link Attachments.download} directly in Fetch-native runtimes, such as Cloudflare Workers,
|
|
46
|
+
* where Web ReadableStreams are the standard stream primitive.
|
|
47
|
+
*
|
|
48
|
+
* @param identifier Grant ID or email account to query
|
|
49
|
+
* @param attachmentId The id of the attachment to download.
|
|
50
|
+
* @param queryParams The query parameters to include in the request
|
|
51
|
+
* @returns {NodeJS.ReadableStream} The Node.js readable stream containing the file data.
|
|
52
|
+
*/
|
|
53
|
+
async downloadNodeStream({ identifier, attachmentId, queryParams, overrides, }) {
|
|
54
|
+
const stream = await this.download({
|
|
55
|
+
identifier,
|
|
56
|
+
attachmentId,
|
|
57
|
+
queryParams,
|
|
58
|
+
overrides,
|
|
59
|
+
});
|
|
60
|
+
return Readable.fromWeb(stream);
|
|
61
|
+
}
|
|
40
62
|
/**
|
|
41
63
|
* Download the attachment as a byte array
|
|
42
64
|
* @param identifier Grant ID or email account to query
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { canonicalJson, } from '../models/serviceAccount.js';
|
|
2
|
+
import { makePathParams, objKeysToSnakeCase } from '../utils.js';
|
|
3
|
+
import { Resource } from './resource.js';
|
|
4
|
+
/**
|
|
5
|
+
* Nylas Manage Domains API
|
|
6
|
+
*
|
|
7
|
+
* Register email domains and run their DNS verification flow
|
|
8
|
+
* (ownership / MX / SPF / DKIM / feedback) for Transactional Send and Nylas Inbound.
|
|
9
|
+
*/
|
|
10
|
+
export class Domains extends Resource {
|
|
11
|
+
assertServiceAccountSigningHeaders(overrides) {
|
|
12
|
+
const headers = {
|
|
13
|
+
...(this.apiClient.headers ?? {}),
|
|
14
|
+
...(overrides?.headers ?? {}),
|
|
15
|
+
};
|
|
16
|
+
const normalizedHeaders = Object.fromEntries(Object.entries(headers).map(([header, value]) => [
|
|
17
|
+
header.toLowerCase(),
|
|
18
|
+
value,
|
|
19
|
+
]));
|
|
20
|
+
const missingHeader = Domains.REQUIRED_SERVICE_ACCOUNT_HEADERS.some((header) => !normalizedHeaders[header]?.trim());
|
|
21
|
+
if (missingHeader) {
|
|
22
|
+
throw new Error('Manage Domains API requests require Nylas Service Account signing headers.');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
buildSignedRequest({ method, path, requestBody, signer, overrides, }) {
|
|
26
|
+
if (!signer) {
|
|
27
|
+
this.assertServiceAccountSigningHeaders(overrides);
|
|
28
|
+
const body = requestBody ? objKeysToSnakeCase(requestBody) : undefined;
|
|
29
|
+
return {
|
|
30
|
+
overrides: { ...overrides, skipAuth: true },
|
|
31
|
+
serializedBody: body ? canonicalJson(body) : undefined,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const body = requestBody ? objKeysToSnakeCase(requestBody) : undefined;
|
|
35
|
+
const signedRequest = signer.buildHeaders({ method, path, body });
|
|
36
|
+
const signedOverrides = {
|
|
37
|
+
...overrides,
|
|
38
|
+
skipAuth: true,
|
|
39
|
+
headers: {
|
|
40
|
+
...(overrides?.headers ?? {}),
|
|
41
|
+
...signedRequest.headers,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
this.assertServiceAccountSigningHeaders(signedOverrides);
|
|
45
|
+
return {
|
|
46
|
+
overrides: signedOverrides,
|
|
47
|
+
serializedBody: signedRequest.serializedBody,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Return all domains for the caller's organization.
|
|
52
|
+
*
|
|
53
|
+
* Requires Nylas Service Account request signing headers:
|
|
54
|
+
* X-Nylas-Kid, X-Nylas-Timestamp, X-Nylas-Nonce, and X-Nylas-Signature.
|
|
55
|
+
* @return The list of domains.
|
|
56
|
+
*/
|
|
57
|
+
list({ queryParams, signer, overrides, } = {}) {
|
|
58
|
+
const path = makePathParams('/v3/admin/domains', {});
|
|
59
|
+
if (signer) {
|
|
60
|
+
return super._list({
|
|
61
|
+
queryParams,
|
|
62
|
+
path,
|
|
63
|
+
getOverrides: () => this.buildSignedRequest({
|
|
64
|
+
method: 'GET',
|
|
65
|
+
path,
|
|
66
|
+
signer,
|
|
67
|
+
overrides,
|
|
68
|
+
}).overrides,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const signed = this.buildSignedRequest({
|
|
72
|
+
method: 'GET',
|
|
73
|
+
path,
|
|
74
|
+
overrides,
|
|
75
|
+
});
|
|
76
|
+
return super._list({
|
|
77
|
+
queryParams,
|
|
78
|
+
path,
|
|
79
|
+
overrides: signed.overrides,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Return a domain.
|
|
84
|
+
*
|
|
85
|
+
* Requires Nylas Service Account request signing headers:
|
|
86
|
+
* X-Nylas-Kid, X-Nylas-Timestamp, X-Nylas-Nonce, and X-Nylas-Signature.
|
|
87
|
+
* @return The domain.
|
|
88
|
+
*/
|
|
89
|
+
find({ domainId, signer, overrides, }) {
|
|
90
|
+
const path = makePathParams('/v3/admin/domains/{domainId}', { domainId });
|
|
91
|
+
const signed = this.buildSignedRequest({
|
|
92
|
+
method: 'GET',
|
|
93
|
+
path,
|
|
94
|
+
signer,
|
|
95
|
+
overrides,
|
|
96
|
+
});
|
|
97
|
+
return super._find({
|
|
98
|
+
path,
|
|
99
|
+
overrides: signed.overrides,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Create a domain.
|
|
104
|
+
*
|
|
105
|
+
* Requires Nylas Service Account request signing headers:
|
|
106
|
+
* X-Nylas-Kid, X-Nylas-Timestamp, X-Nylas-Nonce, and X-Nylas-Signature.
|
|
107
|
+
* @return The created domain.
|
|
108
|
+
*/
|
|
109
|
+
create({ requestBody, signer, overrides, }) {
|
|
110
|
+
const path = makePathParams('/v3/admin/domains', {});
|
|
111
|
+
const signed = this.buildSignedRequest({
|
|
112
|
+
method: 'POST',
|
|
113
|
+
path,
|
|
114
|
+
requestBody,
|
|
115
|
+
signer,
|
|
116
|
+
overrides,
|
|
117
|
+
});
|
|
118
|
+
return super._create({
|
|
119
|
+
path,
|
|
120
|
+
requestBody,
|
|
121
|
+
serializedBody: signed.serializedBody,
|
|
122
|
+
overrides: signed.overrides,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Update a domain.
|
|
127
|
+
*
|
|
128
|
+
* Note: the response echoes the sparse cleared input (typically just `name`
|
|
129
|
+
* and `updatedAt`), not a full domain. Re-fetch the domain with `find` if you
|
|
130
|
+
* need the complete record.
|
|
131
|
+
*
|
|
132
|
+
* Requires Nylas Service Account request signing headers:
|
|
133
|
+
* X-Nylas-Kid, X-Nylas-Timestamp, X-Nylas-Nonce, and X-Nylas-Signature.
|
|
134
|
+
* @return The updated domain fields.
|
|
135
|
+
*/
|
|
136
|
+
update({ domainId, requestBody, signer, overrides, }) {
|
|
137
|
+
const path = makePathParams('/v3/admin/domains/{domainId}', { domainId });
|
|
138
|
+
const signed = this.buildSignedRequest({
|
|
139
|
+
method: 'PUT',
|
|
140
|
+
path,
|
|
141
|
+
requestBody,
|
|
142
|
+
signer,
|
|
143
|
+
overrides,
|
|
144
|
+
});
|
|
145
|
+
return super._update({
|
|
146
|
+
path,
|
|
147
|
+
requestBody,
|
|
148
|
+
serializedBody: signed.serializedBody,
|
|
149
|
+
overrides: signed.overrides,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Delete a domain.
|
|
154
|
+
*
|
|
155
|
+
* Requires Nylas Service Account request signing headers:
|
|
156
|
+
* X-Nylas-Kid, X-Nylas-Timestamp, X-Nylas-Nonce, and X-Nylas-Signature.
|
|
157
|
+
* @return The deletion response.
|
|
158
|
+
*/
|
|
159
|
+
destroy({ domainId, signer, overrides, }) {
|
|
160
|
+
const path = makePathParams('/v3/admin/domains/{domainId}', { domainId });
|
|
161
|
+
const signed = this.buildSignedRequest({
|
|
162
|
+
method: 'DELETE',
|
|
163
|
+
path,
|
|
164
|
+
signer,
|
|
165
|
+
overrides,
|
|
166
|
+
});
|
|
167
|
+
return super._destroy({
|
|
168
|
+
path,
|
|
169
|
+
overrides: signed.overrides,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get the DNS record a customer must configure for a given verification type.
|
|
174
|
+
*
|
|
175
|
+
* Requires Nylas Service Account request signing headers:
|
|
176
|
+
* X-Nylas-Kid, X-Nylas-Timestamp, X-Nylas-Nonce, and X-Nylas-Signature.
|
|
177
|
+
* @return The verification result, including the DNS record to configure.
|
|
178
|
+
*/
|
|
179
|
+
info({ domainId, requestBody, signer, overrides, }) {
|
|
180
|
+
const path = makePathParams('/v3/admin/domains/{domainId}/info', {
|
|
181
|
+
domainId,
|
|
182
|
+
});
|
|
183
|
+
const signed = this.buildSignedRequest({
|
|
184
|
+
method: 'POST',
|
|
185
|
+
path,
|
|
186
|
+
requestBody,
|
|
187
|
+
signer,
|
|
188
|
+
overrides,
|
|
189
|
+
});
|
|
190
|
+
return super._create({
|
|
191
|
+
path,
|
|
192
|
+
requestBody,
|
|
193
|
+
serializedBody: signed.serializedBody,
|
|
194
|
+
overrides: signed.overrides,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Trigger a DNS verification check for a given verification type.
|
|
199
|
+
*
|
|
200
|
+
* Requires Nylas Service Account request signing headers:
|
|
201
|
+
* X-Nylas-Kid, X-Nylas-Timestamp, X-Nylas-Nonce, and X-Nylas-Signature.
|
|
202
|
+
* @return The verification result, including the current status.
|
|
203
|
+
*/
|
|
204
|
+
verify({ domainId, requestBody, signer, overrides, }) {
|
|
205
|
+
const path = makePathParams('/v3/admin/domains/{domainId}/verify', {
|
|
206
|
+
domainId,
|
|
207
|
+
});
|
|
208
|
+
const signed = this.buildSignedRequest({
|
|
209
|
+
method: 'POST',
|
|
210
|
+
path,
|
|
211
|
+
requestBody,
|
|
212
|
+
signer,
|
|
213
|
+
overrides,
|
|
214
|
+
});
|
|
215
|
+
return super._create({
|
|
216
|
+
path,
|
|
217
|
+
requestBody,
|
|
218
|
+
serializedBody: signed.serializedBody,
|
|
219
|
+
overrides: signed.overrides,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
Domains.REQUIRED_SERVICE_ACCOUNT_HEADERS = [
|
|
224
|
+
'x-nylas-kid',
|
|
225
|
+
'x-nylas-timestamp',
|
|
226
|
+
'x-nylas-nonce',
|
|
227
|
+
'x-nylas-signature',
|
|
228
|
+
];
|
|
@@ -78,13 +78,14 @@ export class Messages extends Resource {
|
|
|
78
78
|
* Send an email
|
|
79
79
|
* @return The sent message
|
|
80
80
|
*/
|
|
81
|
-
async send({ identifier, requestBody, overrides, }) {
|
|
81
|
+
async send({ identifier, requestBody, queryParams, overrides, }) {
|
|
82
82
|
const path = makePathParams('/v3/grants/{identifier}/messages/send', {
|
|
83
83
|
identifier,
|
|
84
84
|
});
|
|
85
85
|
const requestOptions = {
|
|
86
86
|
method: 'POST',
|
|
87
87
|
path,
|
|
88
|
+
queryParams,
|
|
88
89
|
overrides,
|
|
89
90
|
};
|
|
90
91
|
// Use form data if the total payload size (body + attachments) is greater than 3mb
|
|
@@ -44,7 +44,7 @@ export class RedirectUris extends Resource {
|
|
|
44
44
|
* @return The updated Redirect URI
|
|
45
45
|
*/
|
|
46
46
|
update({ redirectUriId, requestBody, overrides, }) {
|
|
47
|
-
return super.
|
|
47
|
+
return super._updatePatch({
|
|
48
48
|
overrides,
|
|
49
49
|
path: makePathParams('/v3/applications/redirect-uris/{redirectUriId}', {
|
|
50
50
|
redirectUriId,
|
|
@@ -54,7 +54,7 @@ export class RedirectUris extends Resource {
|
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
56
|
* Delete a Redirect URI
|
|
57
|
-
* @return The
|
|
57
|
+
* @return The deletion response
|
|
58
58
|
*/
|
|
59
59
|
destroy({ redirectUriId, overrides, }) {
|
|
60
60
|
return super._destroy({
|
|
@@ -10,13 +10,26 @@ export class Resource {
|
|
|
10
10
|
constructor(apiClient) {
|
|
11
11
|
this.apiClient = apiClient;
|
|
12
12
|
}
|
|
13
|
-
async fetchList({ queryParams, path, overrides, }) {
|
|
13
|
+
async fetchList({ queryParams, path, overrides, getOverrides, }) {
|
|
14
14
|
const res = await this.apiClient.request({
|
|
15
15
|
method: 'GET',
|
|
16
16
|
path,
|
|
17
17
|
queryParams,
|
|
18
|
-
overrides,
|
|
18
|
+
overrides: getOverrides ? getOverrides() : overrides,
|
|
19
19
|
});
|
|
20
|
+
// Some list endpoints return a nested envelope after key conversion:
|
|
21
|
+
// { data: { items: T[], nextCursor? } }.
|
|
22
|
+
// This guard remaps that nested shape back to the flat shape the list machinery
|
|
23
|
+
// and public SDK surface expect.
|
|
24
|
+
const data = res.data;
|
|
25
|
+
if (data != null &&
|
|
26
|
+
!Array.isArray(data) &&
|
|
27
|
+
typeof data === 'object' &&
|
|
28
|
+
Array.isArray(data.items)) {
|
|
29
|
+
const nested = data;
|
|
30
|
+
res.data = nested.items;
|
|
31
|
+
res.nextCursor = nested.nextCursor ?? res.nextCursor;
|
|
32
|
+
}
|
|
20
33
|
if (queryParams?.limit) {
|
|
21
34
|
let entriesRemaining = queryParams.limit;
|
|
22
35
|
while (res.data.length != queryParams.limit) {
|
|
@@ -32,7 +45,7 @@ export class Resource {
|
|
|
32
45
|
limit: entriesRemaining,
|
|
33
46
|
pageToken: res.nextCursor,
|
|
34
47
|
},
|
|
35
|
-
overrides,
|
|
48
|
+
overrides: getOverrides ? getOverrides() : overrides,
|
|
36
49
|
});
|
|
37
50
|
res.data = res.data.concat(nextRes.data);
|
|
38
51
|
res.requestId = nextRes.requestId;
|
|
@@ -78,12 +91,13 @@ export class Resource {
|
|
|
78
91
|
overrides,
|
|
79
92
|
});
|
|
80
93
|
}
|
|
81
|
-
payloadRequest(method, { path, queryParams, requestBody, overrides }) {
|
|
94
|
+
payloadRequest(method, { path, queryParams, requestBody, serializedBody, overrides, }) {
|
|
82
95
|
return this.apiClient.request({
|
|
83
96
|
method,
|
|
84
97
|
path,
|
|
85
98
|
queryParams,
|
|
86
99
|
body: requestBody,
|
|
100
|
+
serializedBody,
|
|
87
101
|
overrides,
|
|
88
102
|
});
|
|
89
103
|
}
|