@hasna/connectors 0.7.1 → 0.7.2

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/bin/index.js CHANGED
@@ -5254,13 +5254,38 @@ function getAllConnectorsWithAuth() {
5254
5254
  };
5255
5255
  });
5256
5256
  }
5257
- function errorPage(title, message, hint) {
5258
- return `<!DOCTYPE html><html><head><meta charset="utf-8"></head><body style="font-family:system-ui,sans-serif;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;background:var(--bg,#0a0a0a);color:var(--fg,#e5e5e5);">
5259
- <style>@media(prefers-color-scheme:light){:root{--bg:#fff;--fg:#111;--sub:#666;--hint:#888}}:root{--bg:#0a0a0a;--fg:#e5e5e5;--sub:#888;--hint:#666}</style>
5260
- <div style="text-align:center;">
5261
- <h2 style="color:#ef4444;">${title}</h2>
5262
- <p style="color:var(--sub);">${message}</p>
5263
- ${hint ? `<p style="color:var(--hint);font-size:14px;">${hint}</p>` : ""}
5257
+ function oauthPage(type, title, message, hint, extra) {
5258
+ const icons = {
5259
+ success: `<div class="icon icon-success"><svg fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></div>`,
5260
+ error: `<div class="icon icon-error"><svg fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg></div>`,
5261
+ warning: `<div class="icon icon-warning"><svg fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v4m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg></div>`
5262
+ };
5263
+ return `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
5264
+ <style>
5265
+ * { margin:0; padding:0; box-sizing:border-box; }
5266
+ body { font-family:ui-sans-serif,system-ui,-apple-system,sans-serif; display:flex; justify-content:center; align-items:center; min-height:100vh; background:#09090b; color:#fafafa; }
5267
+ .card { background:#18181b; border:1px solid #27272a; border-radius:12px; padding:48px 40px; max-width:420px; width:100%; text-align:center; }
5268
+ .icon { width:64px; height:64px; border-radius:50%; display:flex; align-items:center; justify-content:center; margin:0 auto 24px; }
5269
+ .icon svg { width:32px; height:32px; }
5270
+ .icon-success { background:#052e16; }
5271
+ .icon-success svg { color:#22c55e; }
5272
+ .icon-error { background:#450a0a; }
5273
+ .icon-error svg { color:#ef4444; }
5274
+ .icon-warning { background:#422006; }
5275
+ .icon-warning svg { color:#eab308; }
5276
+ h2 { font-size:24px; font-weight:600; margin-bottom:8px; color:#fafafa; }
5277
+ .subtitle { color:#a1a1aa; font-size:15px; margin-top:12px; line-height:1.5; }
5278
+ .connector { color:#22c55e; font-weight:600; }
5279
+ .hint { color:#52525b; font-size:13px; margin-top:24px; }
5280
+ code, .cmd { background:#27272a; color:#e4e4e7; padding:2px 8px; border-radius:4px; font-family:ui-monospace,monospace; font-size:12px; }
5281
+ </style>
5282
+ </head><body>
5283
+ <div class="card">
5284
+ ${icons[type]}
5285
+ <h2>${title}</h2>
5286
+ <p class="subtitle">${message}</p>
5287
+ ${hint ? `<p class="hint">${hint}</p>` : ""}
5288
+ ${extra?.script ? `<script>${extra.script}</script>` : ""}
5264
5289
  </div>
5265
5290
  </body></html>`;
5266
5291
  }
@@ -5586,7 +5611,7 @@ Dashboard not found at: ${dashboardDir}`);
5586
5611
  const redirectUri = `http://localhost:${port}/oauth/${name}/callback`;
5587
5612
  const authUrl = getOAuthStartUrl(name, redirectUri);
5588
5613
  if (!authUrl) {
5589
- return htmlResponse(errorPage("OAuth Not Available", `No OAuth client credentials found for <strong>${name}</strong>.`, `Set up credentials at <code>~/.connectors/connect-${name}/credentials.json</code>`));
5614
+ return htmlResponse(oauthPage("warning", "OAuth Not Available", `No OAuth client credentials found for <span class="connector">${name}</span>.`, `Set up credentials at <code>~/.connectors/connect-${name}/credentials.json</code>`));
5590
5615
  }
5591
5616
  return Response.redirect(authUrl, 302);
5592
5617
  }
@@ -5597,46 +5622,21 @@ Dashboard not found at: ${dashboardDir}`);
5597
5622
  const error = url2.searchParams.get("error");
5598
5623
  const state = url2.searchParams.get("state");
5599
5624
  if (error) {
5600
- return htmlResponse(errorPage("Authentication Failed", error, "You can close this window."));
5625
+ return htmlResponse(oauthPage("error", "Authentication Failed", error, "You can close this window."));
5601
5626
  }
5602
5627
  if (!validateOAuthState(state, name)) {
5603
- return htmlResponse(errorPage("Invalid State", "CSRF validation failed. The OAuth state parameter is missing or invalid.", "Please try again from the dashboard."));
5628
+ return htmlResponse(oauthPage("error", "Invalid State", "CSRF validation failed. The OAuth state parameter is missing or invalid.", "Please try again from the dashboard."));
5604
5629
  }
5605
5630
  if (!code) {
5606
- return htmlResponse(errorPage("Missing Authorization Code", "No code received from the OAuth provider.", "You can close this window and try again."));
5631
+ return htmlResponse(oauthPage("error", "Missing Authorization Code", "No code received from the OAuth provider.", "You can close this window and try again."));
5607
5632
  }
5608
5633
  try {
5609
5634
  const redirectUri = `http://localhost:${port}/oauth/${name}/callback`;
5610
5635
  await exchangeOAuthCode(name, code, redirectUri);
5611
5636
  logActivity("oauth_connected", name);
5612
- return htmlResponse(`<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
5613
- <style>
5614
- * { margin:0; padding:0; box-sizing:border-box; }
5615
- body { font-family:ui-sans-serif,system-ui,-apple-system,sans-serif; display:flex; justify-content:center; align-items:center; min-height:100vh; background:#09090b; color:#fafafa; }
5616
- .card { background:#18181b; border:1px solid #27272a; border-radius:12px; padding:48px 40px; max-width:420px; text-align:center; }
5617
- .icon { width:64px; height:64px; border-radius:50%; background:#052e16; display:flex; align-items:center; justify-content:center; margin:0 auto 24px; }
5618
- .icon svg { width:32px; height:32px; color:#22c55e; }
5619
- h2 { font-size:24px; font-weight:600; margin-bottom:8px; color:#fafafa; }
5620
- .connector { color:#22c55e; font-weight:600; }
5621
- .subtitle { color:#a1a1aa; font-size:15px; margin-top:12px; line-height:1.5; }
5622
- .hint { color:#52525b; font-size:13px; margin-top:24px; }
5623
- .cmd { background:#27272a; color:#e4e4e7; padding:2px 8px; border-radius:4px; font-family:ui-monospace,monospace; font-size:12px; }
5624
- </style>
5625
- </head><body>
5626
- <div class="card">
5627
- <div class="icon"><svg fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></div>
5628
- <h2>Connected!</h2>
5629
- <p class="subtitle"><span class="connector">${name}</span> is now authenticated and ready to use.</p>
5630
- <p class="hint">You can close this window.<br>Try <span class="cmd">connectors run ${name} --help</span></p>
5631
- <script>
5632
- if (window.opener) {
5633
- window.opener.postMessage({ type: 'oauth-complete', connector: '${name}' }, 'http://localhost:${port}');
5634
- }
5635
- </script>
5636
- </div>
5637
- </body></html>`);
5637
+ return htmlResponse(oauthPage("success", "Connected!", `<span class="connector">${name}</span> is now authenticated and ready to use.`, `You can close this window.<br>Try <code>connectors run ${name} --help</code>`, { script: `if(window.opener){window.opener.postMessage({type:'oauth-complete',connector:'${name}'},'http://localhost:${port}');}` }));
5638
5638
  } catch (e) {
5639
- return htmlResponse(errorPage("Authentication Failed", e instanceof Error ? e.message : "Unknown error", "You can close this window."));
5639
+ return htmlResponse(oauthPage("error", "Authentication Failed", e instanceof Error ? e.message : "Unknown error", "You can close this window."));
5640
5640
  }
5641
5641
  }
5642
5642
  if (method === "OPTIONS") {
@@ -7545,7 +7545,7 @@ var PRESETS = {
7545
7545
  commerce: { description: "Commerce and finance", connectors: ["stripe", "shopify", "revolut", "mercury", "pandadoc"] }
7546
7546
  };
7547
7547
  var program2 = new Command;
7548
- program2.name("connectors").description("Install API connectors for your project").version("0.7.1").enablePositionalOptions();
7548
+ program2.name("connectors").description("Install API connectors for your project").version("0.7.2").enablePositionalOptions();
7549
7549
  program2.command("interactive", { isDefault: true }).alias("i").description("Interactive connector browser").action(() => {
7550
7550
  if (!isTTY) {
7551
7551
  console.log(`Non-interactive environment detected. Use a subcommand:
package/bin/mcp.js CHANGED
@@ -21013,7 +21013,7 @@ async function getConnectorCommandHelp(name, command) {
21013
21013
  loadConnectorVersions();
21014
21014
  var server = new McpServer({
21015
21015
  name: "connectors",
21016
- version: "0.7.1"
21016
+ version: "0.7.2"
21017
21017
  });
21018
21018
  server.registerTool("search_connectors", {
21019
21019
  title: "Search Connectors",
package/bin/serve.js CHANGED
@@ -1732,13 +1732,38 @@ function getAllConnectorsWithAuth() {
1732
1732
  };
1733
1733
  });
1734
1734
  }
1735
- function errorPage(title, message, hint) {
1736
- return `<!DOCTYPE html><html><head><meta charset="utf-8"></head><body style="font-family:system-ui,sans-serif;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;background:var(--bg,#0a0a0a);color:var(--fg,#e5e5e5);">
1737
- <style>@media(prefers-color-scheme:light){:root{--bg:#fff;--fg:#111;--sub:#666;--hint:#888}}:root{--bg:#0a0a0a;--fg:#e5e5e5;--sub:#888;--hint:#666}</style>
1738
- <div style="text-align:center;">
1739
- <h2 style="color:#ef4444;">${title}</h2>
1740
- <p style="color:var(--sub);">${message}</p>
1741
- ${hint ? `<p style="color:var(--hint);font-size:14px;">${hint}</p>` : ""}
1735
+ function oauthPage(type, title, message, hint, extra) {
1736
+ const icons = {
1737
+ success: `<div class="icon icon-success"><svg fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></div>`,
1738
+ error: `<div class="icon icon-error"><svg fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg></div>`,
1739
+ warning: `<div class="icon icon-warning"><svg fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v4m0 4h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg></div>`
1740
+ };
1741
+ return `<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
1742
+ <style>
1743
+ * { margin:0; padding:0; box-sizing:border-box; }
1744
+ body { font-family:ui-sans-serif,system-ui,-apple-system,sans-serif; display:flex; justify-content:center; align-items:center; min-height:100vh; background:#09090b; color:#fafafa; }
1745
+ .card { background:#18181b; border:1px solid #27272a; border-radius:12px; padding:48px 40px; max-width:420px; width:100%; text-align:center; }
1746
+ .icon { width:64px; height:64px; border-radius:50%; display:flex; align-items:center; justify-content:center; margin:0 auto 24px; }
1747
+ .icon svg { width:32px; height:32px; }
1748
+ .icon-success { background:#052e16; }
1749
+ .icon-success svg { color:#22c55e; }
1750
+ .icon-error { background:#450a0a; }
1751
+ .icon-error svg { color:#ef4444; }
1752
+ .icon-warning { background:#422006; }
1753
+ .icon-warning svg { color:#eab308; }
1754
+ h2 { font-size:24px; font-weight:600; margin-bottom:8px; color:#fafafa; }
1755
+ .subtitle { color:#a1a1aa; font-size:15px; margin-top:12px; line-height:1.5; }
1756
+ .connector { color:#22c55e; font-weight:600; }
1757
+ .hint { color:#52525b; font-size:13px; margin-top:24px; }
1758
+ code, .cmd { background:#27272a; color:#e4e4e7; padding:2px 8px; border-radius:4px; font-family:ui-monospace,monospace; font-size:12px; }
1759
+ </style>
1760
+ </head><body>
1761
+ <div class="card">
1762
+ ${icons[type]}
1763
+ <h2>${title}</h2>
1764
+ <p class="subtitle">${message}</p>
1765
+ ${hint ? `<p class="hint">${hint}</p>` : ""}
1766
+ ${extra?.script ? `<script>${extra.script}</script>` : ""}
1742
1767
  </div>
1743
1768
  </body></html>`;
1744
1769
  }
@@ -2064,7 +2089,7 @@ Dashboard not found at: ${dashboardDir}`);
2064
2089
  const redirectUri = `http://localhost:${port}/oauth/${name}/callback`;
2065
2090
  const authUrl = getOAuthStartUrl(name, redirectUri);
2066
2091
  if (!authUrl) {
2067
- return htmlResponse(errorPage("OAuth Not Available", `No OAuth client credentials found for <strong>${name}</strong>.`, `Set up credentials at <code>~/.connectors/connect-${name}/credentials.json</code>`));
2092
+ return htmlResponse(oauthPage("warning", "OAuth Not Available", `No OAuth client credentials found for <span class="connector">${name}</span>.`, `Set up credentials at <code>~/.connectors/connect-${name}/credentials.json</code>`));
2068
2093
  }
2069
2094
  return Response.redirect(authUrl, 302);
2070
2095
  }
@@ -2075,46 +2100,21 @@ Dashboard not found at: ${dashboardDir}`);
2075
2100
  const error = url2.searchParams.get("error");
2076
2101
  const state = url2.searchParams.get("state");
2077
2102
  if (error) {
2078
- return htmlResponse(errorPage("Authentication Failed", error, "You can close this window."));
2103
+ return htmlResponse(oauthPage("error", "Authentication Failed", error, "You can close this window."));
2079
2104
  }
2080
2105
  if (!validateOAuthState(state, name)) {
2081
- return htmlResponse(errorPage("Invalid State", "CSRF validation failed. The OAuth state parameter is missing or invalid.", "Please try again from the dashboard."));
2106
+ return htmlResponse(oauthPage("error", "Invalid State", "CSRF validation failed. The OAuth state parameter is missing or invalid.", "Please try again from the dashboard."));
2082
2107
  }
2083
2108
  if (!code) {
2084
- return htmlResponse(errorPage("Missing Authorization Code", "No code received from the OAuth provider.", "You can close this window and try again."));
2109
+ return htmlResponse(oauthPage("error", "Missing Authorization Code", "No code received from the OAuth provider.", "You can close this window and try again."));
2085
2110
  }
2086
2111
  try {
2087
2112
  const redirectUri = `http://localhost:${port}/oauth/${name}/callback`;
2088
2113
  await exchangeOAuthCode(name, code, redirectUri);
2089
2114
  logActivity("oauth_connected", name);
2090
- return htmlResponse(`<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
2091
- <style>
2092
- * { margin:0; padding:0; box-sizing:border-box; }
2093
- body { font-family:ui-sans-serif,system-ui,-apple-system,sans-serif; display:flex; justify-content:center; align-items:center; min-height:100vh; background:#09090b; color:#fafafa; }
2094
- .card { background:#18181b; border:1px solid #27272a; border-radius:12px; padding:48px 40px; max-width:420px; text-align:center; }
2095
- .icon { width:64px; height:64px; border-radius:50%; background:#052e16; display:flex; align-items:center; justify-content:center; margin:0 auto 24px; }
2096
- .icon svg { width:32px; height:32px; color:#22c55e; }
2097
- h2 { font-size:24px; font-weight:600; margin-bottom:8px; color:#fafafa; }
2098
- .connector { color:#22c55e; font-weight:600; }
2099
- .subtitle { color:#a1a1aa; font-size:15px; margin-top:12px; line-height:1.5; }
2100
- .hint { color:#52525b; font-size:13px; margin-top:24px; }
2101
- .cmd { background:#27272a; color:#e4e4e7; padding:2px 8px; border-radius:4px; font-family:ui-monospace,monospace; font-size:12px; }
2102
- </style>
2103
- </head><body>
2104
- <div class="card">
2105
- <div class="icon"><svg fill="none" stroke="currentColor" stroke-width="2.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></div>
2106
- <h2>Connected!</h2>
2107
- <p class="subtitle"><span class="connector">${name}</span> is now authenticated and ready to use.</p>
2108
- <p class="hint">You can close this window.<br>Try <span class="cmd">connectors run ${name} --help</span></p>
2109
- <script>
2110
- if (window.opener) {
2111
- window.opener.postMessage({ type: 'oauth-complete', connector: '${name}' }, 'http://localhost:${port}');
2112
- }
2113
- </script>
2114
- </div>
2115
- </body></html>`);
2115
+ return htmlResponse(oauthPage("success", "Connected!", `<span class="connector">${name}</span> is now authenticated and ready to use.`, `You can close this window.<br>Try <code>connectors run ${name} --help</code>`, { script: `if(window.opener){window.opener.postMessage({type:'oauth-complete',connector:'${name}'},'http://localhost:${port}');}` }));
2116
2116
  } catch (e) {
2117
- return htmlResponse(errorPage("Authentication Failed", e instanceof Error ? e.message : "Unknown error", "You can close this window."));
2117
+ return htmlResponse(oauthPage("error", "Authentication Failed", e instanceof Error ? e.message : "Unknown error", "You can close this window."));
2118
2118
  }
2119
2119
  }
2120
2120
  if (method === "OPTIONS") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/connectors",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "description": "Open source connector library - Install API connectors with a single command",
5
5
  "type": "module",
6
6
  "bin": {