Fix: notion integration

This commit is contained in:
Dhravya Shah 2025-03-30 20:30:14 -07:00
parent 9998ed25b9
commit c34a3352ac
4 changed files with 49 additions and 93 deletions

View file

@ -1,29 +1,27 @@
import { z } from "zod";
import { Context, Hono } from "hono";
import { type Context, Hono } from "hono";
import { auth } from "./auth";
import { logger } from "hono/logger";
import { timing } from "hono/timing";
import { Env, Variables } from "./types";
import type { Env, Variables } from "./types";
import { zValidator } from "@hono/zod-validator";
import { database } from "@supermemory/db";
import { waitlist } from "@supermemory/db/schema";
import { cors } from "hono/cors";
import { ContentWorkflow } from "./workflow";
import { Resend } from "resend";
import { RedirectStatusCode, StatusCode } from "hono/utils/http-status";
import { LandingPage } from "./components/landing";
import user from "./routes/user";
import spacesRoute from "./routes/spaces";
import actions from "./routes/actions";
import memories from "./routes/memories";
import integrations from "./routes/integrations";
import { fromHono, OpenAPIRoute } from "chanfana";
import { fromHono } from "chanfana";
import {
cloudflareRateLimiter,
DurableObjectRateLimiter,
DurableObjectStore,
} from "@hono-rate-limiter/cloudflare";
import { ConfigType, GeneralConfigType, rateLimiter } from "hono-rate-limiter";
import type { ConfigType, GeneralConfigType, rateLimiter } from "hono-rate-limiter";
// Create base Hono app first
const honoApp = new Hono<{ Variables: Variables; Bindings: Env }>();
@ -94,9 +92,7 @@ app.use("/v1/*", (c, next) => {
common: {
standardHeaders: "draft-6",
keyGenerator: (c: Context) =>
(user?.uuid ?? c.req.header("cf-connecting-ip")) +
"-" +
new Date().getDate(), // day so that limit gets reset every day
`${user?.uuid ?? c.req.header("cf-connecting-ip")}-${new Date().getDate()}`, // day so that limit gets reset every day
store: new DurableObjectStore({ namespace: c.env.RATE_LIMITER }),
} as GeneralConfigType<ConfigType>,
};
@ -145,7 +141,7 @@ app.all("/api/*", async (c) => {
const newPath = path.replace("/api", "/v1");
// Preserve query parameters and build target URL
const redirectUrl = "https://api.supermemory.ai" + newPath + url.search;
const redirectUrl = `https://api.supermemory.ai${newPath}${url.search}`;
// Use c.redirect() for a proper redirect
return c.redirect(redirectUrl);

View file

@ -1,5 +1,5 @@
import { Hono } from "hono";
import { Env, Variables } from "../types";
import type { Env, Variables } from "../types";
import { getDecryptedKV } from "encrypt-workers-kv";
import { getAllNotionPageContents } from "../utils/notion";
import { and, eq, or } from "@supermemory/db";

View file

@ -1,6 +1,4 @@
*,
::before,
::after {
*, ::before, ::after {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
@ -132,7 +130,7 @@
::before,
::after {
--tw-content: "";
--tw-content: '';
}
/*
@ -154,11 +152,9 @@ html,
-moz-tab-size: 4;
/* 3 */
-o-tab-size: 4;
tab-size: 4;
tab-size: 4;
/* 3 */
font-family:
ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol", "Noto Color Emoji";
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
/* 4 */
font-feature-settings: normal;
/* 5 */
@ -201,7 +197,7 @@ Add the correct text decoration in Chrome, Edge, and Safari.
abbr:where([title]) {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
text-decoration: underline dotted;
}
/*
@ -247,9 +243,7 @@ code,
kbd,
samp,
pre {
font-family:
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
"Courier New", monospace;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
/* 1 */
font-feature-settings: normal;
/* 2 */
@ -350,9 +344,9 @@ select {
*/
button,
input:where([type="button"]),
input:where([type="reset"]),
input:where([type="submit"]) {
input:where([type='button']),
input:where([type='reset']),
input:where([type='submit']) {
-webkit-appearance: button;
/* 1 */
background-color: transparent;
@ -399,7 +393,7 @@ Correct the cursor style of increment and decrement buttons in Safari.
2. Correct the outline style in Safari.
*/
[type="search"] {
[type='search'] {
-webkit-appearance: textfield;
/* 1 */
outline-offset: -2px;
@ -492,8 +486,7 @@ textarea {
2. Set the default placeholder color to the user's configured gray 400 color.
*/
input::-moz-placeholder,
textarea::-moz-placeholder {
input::-moz-placeholder, textarea::-moz-placeholder {
opacity: 1;
/* 1 */
color: #9ca3af;
@ -590,9 +583,7 @@ video {
body {
background-color: hsl(var(--background));
font-family:
ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol", "Noto Color Emoji";
font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
color: hsl(var(--foreground));
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
@ -835,29 +826,21 @@ body {
.translate-x-\[-50\%\] {
--tw-translate-x: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y))
rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-y-\[-50\%\] {
--tw-translate-y: -50%;
transform: translate(var(--tw-translate-x), var(--tw-translate-y))
rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rotate-180 {
--tw-rotate: 180deg;
transform: translate(var(--tw-translate-x), var(--tw-translate-y))
rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y))
rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y))
scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
@keyframes spin {
@ -876,8 +859,8 @@ body {
.select-none {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-moz-user-select: none;
user-select: none;
}
.flex-col {
@ -1340,39 +1323,26 @@ body {
.shadow {
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--tw-shadow-colored:
0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
box-shadow:
var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-lg {
--tw-shadow:
0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--tw-shadow-colored:
0 10px 15px -3px var(--tw-shadow-color),
0 4px 6px -4px var(--tw-shadow-color);
box-shadow:
var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-md {
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--tw-shadow-colored:
0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
box-shadow:
var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-sm {
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
box-shadow:
var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
var(--tw-shadow);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.outline-none {
@ -1389,9 +1359,7 @@ body {
}
.filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast)
var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate)
var(--tw-sepia) var(--tw-drop-shadow);
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.transition-all {
@ -1401,8 +1369,7 @@ body {
}
.transition-colors {
transition-property:
color, background-color, border-color, text-decoration-color, fill, stroke;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
@ -1501,13 +1468,9 @@ body {
}
.focus\:ring-2:focus {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0
calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow:
var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
var(--tw-shadow, 0 0 #0000);
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.focus\:ring-ring:focus {
@ -1524,13 +1487,9 @@ body {
}
.focus-visible\:ring-1:focus-visible {
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0
var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0
calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow:
var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
var(--tw-shadow, 0 0 #0000);
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.focus-visible\:ring-ring:focus-visible {
@ -1620,9 +1579,7 @@ body {
color: hsl(var(--muted-foreground));
}
.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0
[cmdk-group]:not([hidden])
~ [cmdk-group] {
.\[\&_\[cmdk-group\]\:not\(\[hidden\]\)_\~\[cmdk-group\]\]\:pt-0 [cmdk-group]:not([hidden]) ~[cmdk-group] {
padding-top: 0px;
}

View file

@ -351,6 +351,11 @@ app.all("/auth/notion/callback", zValidator("query", z.object({ code: z.string()
const notionCredentials = btoa(`${c.env.NOTION_CLIENT_ID}:${c.env.NOTION_CLIENT_SECRET}`);
const redirectUri = c.env.NODE_ENV === "development"
? "http://localhost:3000/auth/notion/callback"
: "https://supermemory.ai/auth/notion/callback";
console.log(redirectUri)
const response = await fetch("https://api.notion.com/v1/oauth/token", {
method: "POST",
headers: {
@ -360,10 +365,7 @@ app.all("/auth/notion/callback", zValidator("query", z.object({ code: z.string()
body: JSON.stringify({
grant_type: "authorization_code",
code: code,
redirect_uri:
c.env.NODE_ENV === "production"
? "https://supermemory.ai/auth/notion/callback"
: "http://localhost:3000/auth/notion/callback",
redirect_uri: redirectUri,
}),
});
@ -381,6 +383,7 @@ app.all("/auth/notion/callback", zValidator("query", z.object({ code: z.string()
const success = !(data as any).error;
if (!success) {
console.error("Failed to get Notion access token:", data, (data as any).error);
return c.redirect(`/?error=${(data as any).error}`);
}