Skip to content

Commit c0faa44

Browse files
committed
some basic changes to demo @nylas/connect
- cleaned up styling - button on the homepage to click - takes you through connect auth (just uses Nylas Applets (US) app) - returns access token, grant id, etc after auth
1 parent 632c5a6 commit c0faa44

8 files changed

Lines changed: 253 additions & 28 deletions

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"husky": "^8.0.3",
6868
"nx": "21.5.2",
6969
"oxlint": "^1.16.0",
70-
"prettier": "^3.4.2"
70+
"prettier": "^3.4.2",
71+
"typescript": "^5.3.3"
7172
}
7273
}

packages/nylas-connect/app.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import { auth } from "./auth-instance.js";
2+
3+
const connectButton = document.getElementById("connectButton");
4+
const resultContainer = document.getElementById("resultContainer");
5+
const resultContent = document.getElementById("resultContent");
6+
7+
connectButton.addEventListener("click", async () => {
8+
// Disable button and show loading state
9+
connectButton.disabled = true;
10+
connectButton.textContent = "Connecting...";
11+
resultContainer.classList.remove("show");
12+
resultContent.innerHTML =
13+
'<p class="loading">Opening authentication window...</p>';
14+
15+
try {
16+
const result = await auth.connect({ method: "popup" });
17+
18+
// Display the result
19+
displayResult(result);
20+
} catch (error) {
21+
// Display error
22+
displayError(error);
23+
} finally {
24+
// Re-enable button
25+
connectButton.disabled = false;
26+
connectButton.textContent = "Connect your inbox";
27+
}
28+
});
29+
30+
function displayResult(result) {
31+
const expiresAt = new Date(result.expiresAt);
32+
const expiresIn = Math.floor((result.expiresAt - Date.now()) / 1000 / 60);
33+
34+
let html = '<span class="success-badge">✓ Authentication Successful</span>';
35+
html += "<h2>Connection Details</h2>";
36+
37+
// Access Token
38+
html += '<div class="result-section">';
39+
html += '<div class="result-label">Access Token</div>';
40+
html += `<div class="result-value token-value">${escapeHtml(result.accessToken)}</div>`;
41+
html += "</div>";
42+
43+
// Grant ID
44+
html += '<div class="result-section">';
45+
html += '<div class="result-label">Grant ID</div>';
46+
html += `<div class="result-value">${escapeHtml(result.grantId)}</div>`;
47+
html += "</div>";
48+
49+
// Grant Info (if available)
50+
if (result.grantInfo) {
51+
if (result.grantInfo.email) {
52+
html += '<div class="result-section">';
53+
html += '<div class="result-label">Email</div>';
54+
html += `<div class="result-value">${escapeHtml(result.grantInfo.email)}</div>`;
55+
html += "</div>";
56+
}
57+
58+
if (result.grantInfo.provider) {
59+
html += '<div class="result-section">';
60+
html += '<div class="result-label">Provider</div>';
61+
html += `<div class="result-value">${escapeHtml(result.grantInfo.provider)}</div>`;
62+
html += "</div>";
63+
}
64+
65+
if (result.grantInfo.name) {
66+
html += '<div class="result-section">';
67+
html += '<div class="result-label">Name</div>';
68+
html += `<div class="result-value">${escapeHtml(result.grantInfo.name)}</div>`;
69+
html += "</div>";
70+
}
71+
}
72+
73+
// Scopes
74+
html += '<div class="result-section">';
75+
html += '<div class="result-label">Granted Scopes</div>';
76+
html += `<div class="result-value">${escapeHtml(result.scope)}</div>`;
77+
html += "</div>";
78+
79+
// Expiration
80+
html += '<div class="result-section">';
81+
html += '<div class="result-label">Expires</div>';
82+
html += `<div class="result-value">${expiresAt.toLocaleString()} (in ${expiresIn} minutes)</div>`;
83+
html += "</div>";
84+
85+
resultContent.innerHTML = html;
86+
resultContainer.classList.add("show");
87+
}
88+
89+
function displayError(error) {
90+
const errorMessage = error instanceof Error ? error.message : String(error);
91+
resultContent.innerHTML = `
92+
<div class="error-message">
93+
<strong>Authentication Error:</strong><br>
94+
${escapeHtml(errorMessage)}
95+
</div>
96+
`;
97+
resultContainer.classList.add("show");
98+
}
99+
100+
function escapeHtml(text) {
101+
const div = document.createElement("div");
102+
div.textContent = text;
103+
return div.innerHTML;
104+
}

packages/nylas-connect/auth-instance.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { NylasConnect } from "./src/index.ts";
22

33
// Shared auth configuration
44
export const auth = new NylasConnect({
5-
clientId: "3531f8b3-3d7f-4412-a073-2d4aa397508f",
6-
apiUrl: "https://api-staging.us.nylas.com/v3",
5+
clientId: "09e06084-b8a4-483c-92e2-07985e0d0489",
6+
apiUrl: "https://api.us.nylas.com/v3",
77
redirectUri:
88
(globalThis.window?.location?.origin || "http://localhost:3000") +
99
"/callback.html",

packages/nylas-connect/index.html

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,21 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>Nylas Auth - Development</title>
7-
<style>
8-
body {
9-
font-family:
10-
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
11-
max-width: 800px;
12-
margin: 0 auto;
13-
padding: 2rem;
14-
background: #f8f9fa;
15-
}
16-
</style>
7+
<link rel="stylesheet" href="styles.css" />
178
</head>
189
<body>
19-
<h1>Open the console to see the output</h1>
20-
<script type="module">
21-
import { auth } from "./auth-instance.js";
22-
23-
auth.connect().then((result) => {
24-
//{ method: "popup" }
25-
console.group("Auth result");
26-
console.log(result);
27-
console.groupEnd();
28-
});
29-
</script>
10+
<div class="demo-container">
11+
<h1>Nylas Connect Demo</h1>
12+
<p class="demo-description">
13+
Click the button below to connect your inbox using Nylas Hosted Auth.
14+
</p>
15+
<button id="connectButton" class="connect-button">
16+
Connect your inbox
17+
</button>
18+
<div id="resultContainer" class="result-container">
19+
<div id="resultContent"></div>
20+
</div>
21+
</div>
22+
<script type="module" src="./app.js"></script>
3023
</body>
3124
</html>

packages/nylas-connect/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
],
1919
"scripts": {
2020
"dev": "vite",
21-
"build": "tsc && vite build",
21+
"build": "../../node_modules/.bin/tsc && vite build",
2222
"preview": "vite preview",
23-
"typecheck": "tsc --noEmit",
23+
"typecheck": "../../node_modules/.bin/tsc --noEmit",
2424
"format": "pnpm --workspace-root prettier --write packages/nylas-connect/",
2525
"format:check": "pnpm --workspace-root prettier --check packages/nylas-connect/",
2626
"lint": "oxlint --fix . && exit 0",

packages/nylas-connect/styles.css

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
body {
2+
font-family:
3+
-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
4+
margin: 0;
5+
padding: 0;
6+
background: #f8f9fa;
7+
min-height: 100vh;
8+
}
9+
10+
.demo-container {
11+
max-width: 800px;
12+
margin: 0 auto;
13+
padding: 2rem;
14+
}
15+
16+
h1 {
17+
color: #333;
18+
margin-bottom: 0.5rem;
19+
font-size: 2rem;
20+
}
21+
22+
.demo-description {
23+
color: #64748b;
24+
margin-bottom: 2rem;
25+
font-size: 1rem;
26+
}
27+
28+
.connect-button {
29+
background: #0066ff;
30+
color: white;
31+
border: none;
32+
padding: 0.75rem 1.5rem;
33+
font-size: 1rem;
34+
font-weight: 500;
35+
border-radius: 6px;
36+
cursor: pointer;
37+
transition: background 0.2s;
38+
margin-bottom: 2rem;
39+
}
40+
41+
.connect-button:hover:not(:disabled) {
42+
background: #0052cc;
43+
}
44+
45+
.connect-button:disabled {
46+
background: #94a3b8;
47+
cursor: not-allowed;
48+
}
49+
50+
.result-container {
51+
display: none;
52+
background: white;
53+
border-radius: 8px;
54+
padding: 1.5rem;
55+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
56+
margin-top: 2rem;
57+
}
58+
59+
.result-container.show {
60+
display: block;
61+
}
62+
63+
.result-container h2 {
64+
margin-top: 0;
65+
color: #333;
66+
font-size: 1.25rem;
67+
}
68+
69+
.result-section {
70+
margin-bottom: 1.5rem;
71+
}
72+
73+
.result-section:last-child {
74+
margin-bottom: 0;
75+
}
76+
77+
.result-label {
78+
font-weight: 600;
79+
color: #64748b;
80+
font-size: 0.875rem;
81+
text-transform: uppercase;
82+
letter-spacing: 0.05em;
83+
margin-bottom: 0.5rem;
84+
}
85+
86+
.result-value {
87+
color: #1e293b;
88+
word-break: break-all;
89+
font-family: "Monaco", "Menlo", "Ubuntu Mono", monospace;
90+
font-size: 0.875rem;
91+
background: #f1f5f9;
92+
padding: 0.75rem;
93+
border-radius: 4px;
94+
border: 1px solid #e2e8f0;
95+
}
96+
97+
.token-value {
98+
font-size: 0.75rem;
99+
line-height: 1.6;
100+
}
101+
102+
.error-message {
103+
background: #fee2e2;
104+
color: #991b1b;
105+
padding: 1rem;
106+
border-radius: 6px;
107+
border: 1px solid #fecaca;
108+
}
109+
110+
.success-badge {
111+
display: inline-block;
112+
background: #d1fae5;
113+
color: #065f46;
114+
padding: 0.25rem 0.75rem;
115+
border-radius: 4px;
116+
font-size: 0.875rem;
117+
font-weight: 500;
118+
margin-bottom: 1rem;
119+
}
120+
121+
.loading {
122+
color: #64748b;
123+
font-style: italic;
124+
}

packages/react/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "React components and hooks for Nylas API integration",
55
"type": "module",
66
"scripts": {
7-
"build": "tsc && vite build",
7+
"build": "../../node_modules/.bin/tsc && vite build",
88
"test": "vitest run",
99
"test:watch": "vitest",
1010
"format": "pnpm --workspace-root prettier --write packages/react/",
@@ -13,7 +13,7 @@
1313
"lint:check": "oxlint .",
1414
"clean": "rm -rf dist",
1515
"dev": "vite build --watch --emptyOutDir=false",
16-
"typecheck": "tsc --noEmit",
16+
"typecheck": "../../node_modules/.bin/tsc --noEmit",
1717
"preview": "vite preview",
1818
"coverage": "vitest run --coverage",
1919
"docs": "typedoc"

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)