diff --git a/.changeset/five-penguins-rhyme.md b/.changeset/five-penguins-rhyme.md new file mode 100644 index 00000000..b1d8ef35 --- /dev/null +++ b/.changeset/five-penguins-rhyme.md @@ -0,0 +1,11 @@ +--- +"@oberoncms/plugin-uploadthing": minor +"create-oberon-app": minor +"@oberoncms/plugin-flydrive": minor +"@oberoncms/core": minor +"@tohuhono/dev": minor +"@oberon/playground": minor +"@oberon/recipe-nextjs": minor +--- + +Move all handlers to single api handler endpoint under cms diff --git a/apps/playground/app/(oberon)/api/auth/[...nextauth]/route.tsx b/apps/playground/app/(oberon)/api/auth/[...nextauth]/route.tsx deleted file mode 100644 index 3a9df4f5..00000000 --- a/apps/playground/app/(oberon)/api/auth/[...nextauth]/route.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import { handlers } from "@/oberon/adapter" - -export const { GET, POST } = handlers.auth || {} diff --git a/apps/playground/app/(oberon)/api/uploadthing/route.ts b/apps/playground/app/(oberon)/api/uploadthing/route.ts deleted file mode 100644 index 0ab6c644..00000000 --- a/apps/playground/app/(oberon)/api/uploadthing/route.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { initRouteHandler } from "@oberoncms/plugin-uploadthing/plugin" -import { adapter } from "@/oberon/adapter" - -export const { GET, POST } = initRouteHandler(adapter) diff --git a/apps/playground/app/(oberon)/cms/api/[...path]/route.tsx b/apps/playground/app/(oberon)/cms/api/[...path]/route.tsx new file mode 100644 index 00000000..41f5d039 --- /dev/null +++ b/apps/playground/app/(oberon)/cms/api/[...path]/route.tsx @@ -0,0 +1,3 @@ +import { handler } from "@/oberon/adapter" + +export const { GET, POST, PUT, PATCH, DELETE } = handler diff --git a/apps/playground/oberon/adapter.ts b/apps/playground/oberon/adapter.ts index 4d78aca2..da886dbc 100644 --- a/apps/playground/oberon/adapter.ts +++ b/apps/playground/oberon/adapter.ts @@ -9,7 +9,7 @@ import { plugin as uploadthingPlugin } from "@oberoncms/plugin-uploadthing/plugi import { plugin as sendPlugin } from "./send" import { config } from "./config" -export const { adapter, handlers } = initOberon({ +export const { adapter, handler } = initOberon({ config, plugins: [ developmentPlugin, diff --git a/packages/create-oberon-app/src/installer/install-adapter.ts b/packages/create-oberon-app/src/installer/install-adapter.ts index 1db0081b..f8c0fa8c 100644 --- a/packages/create-oberon-app/src/installer/install-adapter.ts +++ b/packages/create-oberon-app/src/installer/install-adapter.ts @@ -74,7 +74,7 @@ ${pluginImports} import { config } from "./config" -export const { adapter, handlers } = initOberon({ +export const { adapter, handler } = initOberon({ config, plugins: [ ${pluginAliasNames.join(", ")} diff --git a/packages/oberoncms/core/src/adapter/init-oberon.tsx b/packages/oberoncms/core/src/adapter/init-adapter.ts similarity index 56% rename from packages/oberoncms/core/src/adapter/init-oberon.tsx rename to packages/oberoncms/core/src/adapter/init-adapter.ts index a0aae8ae..e0852b79 100644 --- a/packages/oberoncms/core/src/adapter/init-oberon.tsx +++ b/packages/oberoncms/core/src/adapter/init-adapter.ts @@ -25,8 +25,8 @@ import { type TransformResult, type OberonPage, type PageData, - type OberonPlugin, - type OberonHandler, + type OberonPluginAdapter, + type PluginVersion, } from "../lib/dtd" import { applyTransforms, @@ -34,20 +34,16 @@ import { getTransforms, } from "./transforms" import { exportTailwindClasses } from "./export-tailwind-clases" -import { initPlugins } from "./init-plugins" -export function initOberon({ +export function initAdapter({ config, - plugins, + versions, + pluginAdapter: adapter, }: { config: OberonConfig - plugins: OberonPlugin[] -}): { - handlers: Record - adapter: OberonAdapter -} { - const { versions, handlers, adapter } = initPlugins(plugins) - + pluginAdapter: OberonPluginAdapter + versions: PluginVersion[] +}): OberonAdapter { const can: OberonAdapter["can"] = async (action, permission = "read") => { // Check unauthenticated first so we can do it outside of request context if (adapter.hasPermission({ action, permission })) { @@ -233,130 +229,127 @@ export function initOberon({ }) return { - handlers, - adapter: { - prebuild: async () => { - await adapter.prebuild() - await exportTailwindClasses(adapter) - }, - /* - * Auth - */ - can, - signIn: adapter.signIn, - signOut: adapter.signOut, - /* - * Site actions - */ - getConfig: async () => { - await will("site", "read") - return await getConfigCached() - }, - migrateData: async () => { - const user = await whoWill("site", "write") - return migrate(user) - }, - - /* - * Page actions - */ - getAllPaths: async function () { - await will("pages", "read") - return getAllPathsCached() - }, - getAllPages: async function () { - await will("pages", "read") - return getAllPagesCached() - }, - getPageData: async function (key) { - await will("pages", "read") - return getPageDataCached(key) - }, - // TODO return value - addPage: async function (data: unknown) { - const user = await whoWill("pages", "write") - const { key } = AddPageSchema.parse(data) - await adapter.addPage({ - key, - data: INITIAL_DATA, - updatedAt: new Date(), - updatedBy: user.email, - }) - revalidatePath(key) - revalidateTag("oberon-pages") - }, - // TODO return value - deletePage: async function (data: unknown) { - await will("pages", "write") - const { key } = DeletePageSchema.parse(data) - await adapter.deletePage(key) - revalidatePath(key) - revalidateTag("oberon-pages") - }, - publishPageData: async function (data: unknown) { - const user = await whoWill("pages", "write") - const { key, data: pageData } = PublishPageSchema.parse(data) - await updatePageData({ - key, - data: pageData as PageData, - updatedBy: user.email, - }) - return { message: `Successfully published ${key}` } - }, - - /* - * Image actions - */ - getAllImages: async function () { - await will("images", "read") - return getAllImagesCached() - }, - addImage: async function (data: unknown) { - await will("images", "write") - - const image = AddImageSchema.parse(data) - await adapter.addImage(image) - revalidateTag("oberon-images") - return adapter.getAllImages() - }, - // TODO uploadthing - deleteImage: async function (data) { - await will("images", "write") - revalidateTag("oberon-images") - return adapter.deleteImage(data) - }, - - /* - * User actions - */ - getAllUsers: async function () { - await will("users", "read") - return getAllUsersCached() - }, - addUser: async function (data: unknown) { - await will("users", "write") - const { email, role } = AddUserSchema.parse(data) - const { id } = await adapter.addUser({ - email, - role, - }) - revalidateTag("oberon-users") - return { id, email, role } - }, - deleteUser: async function (data: unknown) { - await will("users", "write") - const { id } = DeleteUserSchema.parse(data) - await adapter.deleteUser(id) - revalidateTag("oberon-users") - return { id } - }, - changeRole: async function (data: unknown) { - await will("users", "write") - const { role, id } = ChangeRoleSchema.parse(data) - await adapter.changeRole({ role, id }) - revalidateTag("oberon-users") - return { role, id } - }, + prebuild: async () => { + await adapter.prebuild() + await exportTailwindClasses(adapter) + }, + /* + * Auth + */ + can, + signIn: adapter.signIn, + signOut: adapter.signOut, + /* + * Site actions + */ + getConfig: async () => { + await will("site", "read") + return await getConfigCached() + }, + migrateData: async () => { + const user = await whoWill("site", "write") + return migrate(user) + }, + + /* + * Page actions + */ + getAllPaths: async function () { + await will("pages", "read") + return getAllPathsCached() + }, + getAllPages: async function () { + await will("pages", "read") + return getAllPagesCached() + }, + getPageData: async function (key) { + await will("pages", "read") + return getPageDataCached(key) + }, + // TODO return value + addPage: async function (data: unknown) { + const user = await whoWill("pages", "write") + const { key } = AddPageSchema.parse(data) + await adapter.addPage({ + key, + data: INITIAL_DATA, + updatedAt: new Date(), + updatedBy: user.email, + }) + revalidatePath(key) + revalidateTag("oberon-pages") + }, + // TODO return value + deletePage: async function (data: unknown) { + await will("pages", "write") + const { key } = DeletePageSchema.parse(data) + await adapter.deletePage(key) + revalidatePath(key) + revalidateTag("oberon-pages") + }, + publishPageData: async function (data: unknown) { + const user = await whoWill("pages", "write") + const { key, data: pageData } = PublishPageSchema.parse(data) + await updatePageData({ + key, + data: pageData as PageData, + updatedBy: user.email, + }) + return { message: `Successfully published ${key}` } + }, + + /* + * Image actions + */ + getAllImages: async function () { + await will("images", "read") + return getAllImagesCached() + }, + addImage: async function (data: unknown) { + await will("images", "write") + + const image = AddImageSchema.parse(data) + await adapter.addImage(image) + revalidateTag("oberon-images") + return adapter.getAllImages() + }, + // TODO uploadthing + deleteImage: async function (data) { + await will("images", "write") + revalidateTag("oberon-images") + return adapter.deleteImage(data) + }, + + /* + * User actions + */ + getAllUsers: async function () { + await will("users", "read") + return getAllUsersCached() + }, + addUser: async function (data: unknown) { + await will("users", "write") + const { email, role } = AddUserSchema.parse(data) + const { id } = await adapter.addUser({ + email, + role, + }) + revalidateTag("oberon-users") + return { id, email, role } + }, + deleteUser: async function (data: unknown) { + await will("users", "write") + const { id } = DeleteUserSchema.parse(data) + await adapter.deleteUser(id) + revalidateTag("oberon-users") + return { id } + }, + changeRole: async function (data: unknown) { + await will("users", "write") + const { role, id } = ChangeRoleSchema.parse(data) + await adapter.changeRole({ role, id }) + revalidateTag("oberon-users") + return { role, id } }, } } diff --git a/packages/oberoncms/core/src/adapter/init-oberon.ts b/packages/oberoncms/core/src/adapter/init-oberon.ts new file mode 100644 index 00000000..fdcef4b6 --- /dev/null +++ b/packages/oberoncms/core/src/adapter/init-oberon.ts @@ -0,0 +1,69 @@ +import type { NextRequest } from "next/server" +import { + type OberonAdapter, + type OberonConfig, + type OberonPlugin, + type OberonHandler, + type OberonMethod, +} from "../lib/dtd" +import { initAdapter } from "./init-adapter" +import { initPlugins } from "./init-plugins" + +function handle( + method: TMethod, + handlers: Record OberonHandler>, + adapter: OberonAdapter, +): OberonHandler<{ path: string[] }>[TMethod] { + return async ( + request: NextRequest, + { params: { path } }: { params: { path: string[] } }, + ) => { + const action = path?.[0] + + console.log("_>", method, action) + + if (!action) { + return new Response("", { status: 404 }) + } + + const handler = handlers[action]?.(adapter)[method] + + if (!handler) { + return new Response("", { status: 405 }) + } + + return handler(request) + } +} + +export function initOberon({ + config, + plugins, +}: { + config: OberonConfig + plugins: OberonPlugin[] +}): { + handler: OberonHandler<{ path: string[] }> + adapter: OberonAdapter +} { + const { versions, handlers, adapter: pluginAdapter } = initPlugins(plugins) + + const adapter = initAdapter({ + config, + versions, + pluginAdapter, + }) + + const handler = { + GET: handle("GET", handlers, adapter), + PUT: handle("PUT", handlers, adapter), + PATCH: handle("PATCH", handlers, adapter), + POST: handle("POST", handlers, adapter), + DELETE: handle("DELETE", handlers, adapter), + } + + return { + handler, + adapter, + } +} diff --git a/packages/oberoncms/core/src/adapter/init-plugins.tsx b/packages/oberoncms/core/src/adapter/init-plugins.ts similarity index 97% rename from packages/oberoncms/core/src/adapter/init-plugins.tsx rename to packages/oberoncms/core/src/adapter/init-plugins.ts index de590788..f59f5d8f 100644 --- a/packages/oberoncms/core/src/adapter/init-plugins.tsx +++ b/packages/oberoncms/core/src/adapter/init-plugins.ts @@ -4,13 +4,14 @@ import { type OberonPermissions, type PluginVersion, type OberonHandler, + type OberonAdapter, } from "../lib/dtd" import { notImplemented } from "../lib/utils" import { getInitialData } from "./get-initial-data" type InititalisedPlugins = { adapter: OberonPluginAdapter - handlers: Record + handlers: Record OberonHandler> versions: PluginVersion[] } diff --git a/packages/oberoncms/core/src/auth/next-auth.ts b/packages/oberoncms/core/src/auth/next-auth.ts index 13023e1c..98cce8af 100644 --- a/packages/oberoncms/core/src/auth/next-auth.ts +++ b/packages/oberoncms/core/src/auth/next-auth.ts @@ -30,7 +30,7 @@ const withCallback = (url: string) => { export const authPlugin: OberonPlugin = (adapter) => { const config = { - basePath: "/api/auth", + basePath: "/cms/api/auth", pages: { signIn: "/cms/login", }, @@ -114,7 +114,9 @@ export const authPlugin: OberonPlugin = (adapter) => { return { name: `${name}/auth`, version, - handlers: { auth: nextAuth.handlers }, + handlers: { + auth: () => nextAuth.handlers, + }, adapter: { getCurrentUser: async () => { const session = await nextAuth.auth() diff --git a/packages/oberoncms/core/src/components/login.tsx b/packages/oberoncms/core/src/components/login.tsx index e8208db4..487977ff 100644 --- a/packages/oberoncms/core/src/components/login.tsx +++ b/packages/oberoncms/core/src/components/login.tsx @@ -78,7 +78,7 @@ export function Login({ const tokenOnClick = form.handleSubmit(async ({ email, token }) => { setSubmitting(true) const response = await fetch( - `/api/auth/callback/email?email=${email}&token=${token}`, + `/cms/api/auth/callback/email?email=${email}&token=${token}`, ) if (response.ok) { router.push(callbackUrl || "/cms/pages") diff --git a/packages/oberoncms/core/src/hooks/use-oberon-images.ts b/packages/oberoncms/core/src/hooks/use-oberon-images.ts index 3cb76b54..a6d89203 100644 --- a/packages/oberoncms/core/src/hooks/use-oberon-images.ts +++ b/packages/oberoncms/core/src/hooks/use-oberon-images.ts @@ -9,7 +9,7 @@ export const useOberonImages = () => { data: images, mutate, isLoading: loading, - } = useSWR("/oberon/images", () => getAllImages()) + } = useSWR("/oberon/images", getAllImages) return { images, diff --git a/packages/oberoncms/core/src/lib/dtd.ts b/packages/oberoncms/core/src/lib/dtd.ts index d01e496d..a943286e 100644 --- a/packages/oberoncms/core/src/lib/dtd.ts +++ b/packages/oberoncms/core/src/lib/dtd.ts @@ -288,9 +288,7 @@ export type OberonMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" // Currently the only handles exported are NextAuth Handlers export type OberonHandler = Params extends undefined ? { - [key in OberonMethod]?: ( - req: NextRequest, - ) => Promise | Promise + [key in OberonMethod]?: (req: NextRequest) => Promise | Response } : { [key in OberonMethod]: ( @@ -299,14 +297,6 @@ export type OberonHandler = Params extends undefined ) => Promise } -export type OberonPlugin = (adapter: OberonPluginAdapter) => { - name: string - version?: string - disabled?: boolean - handlers?: Record - adapter?: Partial -} - export type OberonAdapter = { prebuild: () => Promise addPage: (page: z.infer) => Promise @@ -340,6 +330,14 @@ export type OberonAdapter = { signIn: (data: { email: string }) => Promise } +export type OberonPlugin = (adapter: OberonPluginAdapter) => { + name: string + version?: string + disabled?: boolean + handlers?: Record OberonHandler> + adapter?: Partial +} + export type OberonResponse = Promise< | { status: "success" diff --git a/packages/plugins/flydrive/src/blocks/image-field.tsx b/packages/plugins/flydrive/src/blocks/image-field.tsx index 0e40bcfa..3e5405d2 100644 --- a/packages/plugins/flydrive/src/blocks/image-field.tsx +++ b/packages/plugins/flydrive/src/blocks/image-field.tsx @@ -48,7 +48,7 @@ export const ImageField = ({ formData.append("image", file) try { - const response = await fetch("/api/flydrive", { + const response = await fetch("/cms/api/flydrive", { method: "POST", body: formData, }) diff --git a/packages/plugins/uploadthing/package.json b/packages/plugins/uploadthing/package.json index dbebba53..7a5151b7 100644 --- a/packages/plugins/uploadthing/package.json +++ b/packages/plugins/uploadthing/package.json @@ -50,12 +50,12 @@ "dependencies": { "@oberoncms/core": "workspace:*", "@radix-ui/react-icons": "^1.3.0", - "@uploadthing/react": "^6.5.4", - "@uploadthing/shared": "^6.7.4", + "@uploadthing/react": "^6.6.0", + "@uploadthing/shared": "^6.7.5", "image-size": "1.1.1", "next": "^14.2.3", - "uploadthing": "^6.10.4", - "server-cli-only": "^0.3.2" + "server-cli-only": "^0.3.2", + "uploadthing": "^6.12.0" }, "peerDependencies": { "react": ">=18.2.0", diff --git a/packages/plugins/uploadthing/src/uploadthing/components.tsx b/packages/plugins/uploadthing/src/uploadthing/components.tsx index 2a4fa6a6..16b3b977 100644 --- a/packages/plugins/uploadthing/src/uploadthing/components.tsx +++ b/packages/plugins/uploadthing/src/uploadthing/components.tsx @@ -7,7 +7,7 @@ import type { OurFileRouter } from "./file-router" export const UploadButton: ReturnType< typeof generateUploadButton -> = generateUploadButton() +> = generateUploadButton({ url: "/cms/api/uploadthing" }) export const UploadDropzone: ReturnType< typeof generateUploadDropzone -> = generateUploadDropzone() +> = generateUploadDropzone({ url: "/cms/api/uploadthing" }) diff --git a/packages/plugins/uploadthing/src/uploadthing/file-router.ts b/packages/plugins/uploadthing/src/uploadthing/file-router.ts index 96715e0f..ca273ccc 100644 --- a/packages/plugins/uploadthing/src/uploadthing/file-router.ts +++ b/packages/plugins/uploadthing/src/uploadthing/file-router.ts @@ -52,6 +52,7 @@ const initFileRouter = ({ can }: OberonAdapter) => { export function initRouteHandler(adapter: OberonAdapter) { return createRouteHandler({ router: initFileRouter(adapter), + config: { callbackUrl: "/cms/api/uploadthing" }, }) } diff --git a/packages/plugins/uploadthing/src/uploadthing/plugin.ts b/packages/plugins/uploadthing/src/uploadthing/plugin.ts index 78cdab47..3cbac2b0 100644 --- a/packages/plugins/uploadthing/src/uploadthing/plugin.ts +++ b/packages/plugins/uploadthing/src/uploadthing/plugin.ts @@ -1,17 +1,23 @@ import type { OberonPlugin } from "@oberoncms/core" import { name, version } from "../../package.json" with { type: "json" } import { deleteImage } from "./api" +import { initRouteHandler } from "./file-router" -export const plugin: OberonPlugin = (adapter) => ({ - name, - version, - adapter: { - deleteImage: async (key) => { - await Promise.allSettled([ - // - deleteImage(key), - adapter.deleteImage(key), - ]) +export const plugin: OberonPlugin = (adapter) => { + return { + name, + version, + handlers: { + uploadthing: (adapter) => initRouteHandler(adapter), }, - }, -}) + adapter: { + deleteImage: async (key) => { + await Promise.allSettled([ + // + deleteImage(key), + adapter.deleteImage(key), + ]) + }, + }, + } +} diff --git a/packages/tohuhono/dev/package.json b/packages/tohuhono/dev/package.json index 6c63b5cb..95b2ed4f 100644 --- a/packages/tohuhono/dev/package.json +++ b/packages/tohuhono/dev/package.json @@ -58,7 +58,6 @@ "tsx": "^4.13.3", "typescript": "5.4.2", "typescript-eslint": "^7.2.0", - "uploadthing": "^6.10.1", "vite": "^5.1.6", "vite-plugin-dts": "^3.7.3", "vite-plugin-externalize-deps": "^0.8.0" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7bb16da..ddc7067d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -670,11 +670,11 @@ importers: specifier: ^1.3.0 version: 1.3.0(react@18.2.0) '@uploadthing/react': - specifier: ^6.5.4 - version: 6.5.4(next@14.2.3)(react@18.2.0)(uploadthing@6.10.4) + specifier: ^6.6.0 + version: 6.6.0(next@14.2.3)(react@18.2.0)(uploadthing@6.12.0) '@uploadthing/shared': - specifier: ^6.7.4 - version: 6.7.4(@uploadthing/mime-types@0.2.10) + specifier: ^6.7.5 + version: 6.7.5 image-size: specifier: 1.1.1 version: 1.1.1 @@ -691,8 +691,8 @@ importers: specifier: ^0.3.2 version: 0.3.2 uploadthing: - specifier: ^6.10.4 - version: 6.10.4(next@14.2.3) + specifier: ^6.12.0 + version: 6.12.0(next@14.2.3) devDependencies: '@measured/puck': specifier: ^0.14.2 @@ -818,9 +818,6 @@ importers: typescript-eslint: specifier: ^7.2.0 version: 7.6.0(eslint@8.57.0)(typescript@5.4.2) - uploadthing: - specifier: ^6.10.1 - version: 6.10.4(tailwindcss@3.4.3) vite: specifier: ^5.1.6 version: 5.2.8(@types/node@20.11.30) @@ -5245,37 +5242,31 @@ packages: resolution: {integrity: sha512-kz3F0oEgAyts25NAGXlUBCWh3mXonbSOQJFGFMawHuIgbUbnzXbe4w5WI+0XdneCbjNmikfWrdWrs8m/7HATfQ==} dev: false - /@uploadthing/react@6.5.4(next@14.2.3)(react@18.2.0)(uploadthing@6.10.4): - resolution: {integrity: sha512-c1RFZggXqlc4wQ0hnxjgOM+9066NUMOJmUAPG2N7EKYO64/uRrZMpq5CvYdxsKwI0YiCnhIeInct21QvSSEa6Q==} + /@uploadthing/react@6.6.0(next@14.2.3)(react@18.2.0)(uploadthing@6.12.0): + resolution: {integrity: sha512-jLN4Oy21d0n8F6CNPl9qjEu0/Q1rnddSxny/02Lm89L/sYuR4RXfk1vBgBGPAGXBak0BO9z5eEmYURLrXXUAJQ==} peerDependencies: next: '*' react: ^17.0.2 || ^18.0.0 - uploadthing: 6.10.4 + uploadthing: 6.12.0 peerDependenciesMeta: next: optional: true dependencies: '@uploadthing/dropzone': 0.4.1(react@18.2.0) - '@uploadthing/shared': 6.7.4(@uploadthing/mime-types@0.2.10) + '@uploadthing/shared': 6.7.5 file-selector: 0.6.0 next: 14.2.3(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 tailwind-merge: 2.2.2 - uploadthing: 6.10.4(next@14.2.3) + uploadthing: 6.12.0(next@14.2.3) transitivePeerDependencies: - - '@uploadthing/mime-types' - solid-js - svelte - vue dev: false - /@uploadthing/shared@6.7.4(@uploadthing/mime-types@0.2.10): - resolution: {integrity: sha512-7e35U7/84qQQx+bhldSdze9ODiAo4NCCZiYEV3NomD44O9fE5bfQXcCPtBeXh3y3udf7S28PMZbT6ybJeuKfgw==} - peerDependencies: - '@uploadthing/mime-types': 0.2.10 - peerDependenciesMeta: - '@uploadthing/mime-types': - optional: true + /@uploadthing/shared@6.7.5: + resolution: {integrity: sha512-BZXzvh6zGEt4ip//mxfXdRTNWYw9XJ6tommL6A1TEo2l8jvdNbUpPUwXnMVWBMwio2b48BO7D9V3siYIKMD4pg==} dependencies: '@uploadthing/mime-types': 0.2.10 effect: 3.1.2 @@ -7299,7 +7290,7 @@ packages: eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.34.1(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) @@ -7337,7 +7328,7 @@ packages: enhanced-resolve: 5.16.0 eslint: 8.57.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.5 is-core-module: 2.13.1 @@ -7406,7 +7397,34 @@ packages: - supports-color dev: false - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + /eslint-module-utils@2.8.1(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + debug: 3.2.7 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.6.0)(eslint@8.57.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: @@ -7416,7 +7434,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/parser': 7.6.0(eslint@8.57.0)(typescript@5.4.2) array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 @@ -7425,7 +7443,7 @@ packages: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.6.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -7439,8 +7457,9 @@ packages: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color + dev: false - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.6.0)(eslint@8.57.0): + /eslint-plugin-import@2.29.1(eslint@8.57.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: @@ -7450,7 +7469,6 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 7.6.0(eslint@8.57.0)(typescript@5.4.2) array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 @@ -7459,7 +7477,7 @@ packages: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.6.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-module-utils: 2.8.1(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -7473,7 +7491,6 @@ packages: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - dev: false /eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0): resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} @@ -12800,8 +12817,8 @@ packages: picocolors: 1.0.1 dev: true - /uploadthing@6.10.4(next@14.2.3): - resolution: {integrity: sha512-0hGO0Q7R7MnxzVkUbYHE6PkwFieYH+UUa905uo7JtA0h3Gpc89bNDFaOfK8634Z66088VRLNVuWxY2FTIqw4sg==} + /uploadthing@6.12.0(next@14.2.3): + resolution: {integrity: sha512-uoWG1riH6z2IHCcbMo3xnGe6p/+sx2PPOOLOsk5DeqGv5HtlY7ISauFFRXW8H+jdhevZm1n/j4Je/Z+bbIziSg==} engines: {node: '>=18.13.0'} peerDependencies: express: '*' @@ -12823,7 +12840,7 @@ packages: dependencies: '@effect/schema': 0.66.14(effect@3.1.2)(fast-check@3.18.0) '@uploadthing/mime-types': 0.2.10 - '@uploadthing/shared': 6.7.4(@uploadthing/mime-types@0.2.10) + '@uploadthing/shared': 6.7.5 consola: 3.2.3 effect: 3.1.2 fast-check: 3.18.0 @@ -12831,37 +12848,6 @@ packages: std-env: 3.7.0 dev: false - /uploadthing@6.10.4(tailwindcss@3.4.3): - resolution: {integrity: sha512-0hGO0Q7R7MnxzVkUbYHE6PkwFieYH+UUa905uo7JtA0h3Gpc89bNDFaOfK8634Z66088VRLNVuWxY2FTIqw4sg==} - engines: {node: '>=18.13.0'} - peerDependencies: - express: '*' - fastify: '*' - h3: '*' - next: '*' - tailwindcss: '*' - peerDependenciesMeta: - express: - optional: true - fastify: - optional: true - h3: - optional: true - next: - optional: true - tailwindcss: - optional: true - dependencies: - '@effect/schema': 0.66.14(effect@3.1.2)(fast-check@3.18.0) - '@uploadthing/mime-types': 0.2.10 - '@uploadthing/shared': 6.7.4(@uploadthing/mime-types@0.2.10) - consola: 3.2.3 - effect: 3.1.2 - fast-check: 3.18.0 - std-env: 3.7.0 - tailwindcss: 3.4.3 - dev: false - /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -13049,7 +13035,7 @@ packages: peerDependencies: vite: '>2.0.0-0' dependencies: - vite: 5.2.8(@types/node@20.11.26) + vite: 5.2.8 dev: true /vite-plugin-dts@3.8.2(@types/node@20.11.30)(rollup@4.18.0)(typescript@5.4.2)(vite@5.2.8): @@ -13085,6 +13071,41 @@ packages: vite: 5.2.8(@types/node@20.11.30) dev: false + /vite@5.2.8: + resolution: {integrity: sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + esbuild: 0.20.2 + postcss: 8.4.38 + rollup: 4.17.2 + optionalDependencies: + fsevents: 2.3.3 + dev: true + /vite@5.2.8(@types/node@20.11.26): resolution: {integrity: sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==} engines: {node: ^18.0.0 || >=20.0.0} diff --git a/recipes/nextjs/app/(oberon)/api/auth/[...nextauth]/route.tsx b/recipes/nextjs/app/(oberon)/api/auth/[...nextauth]/route.tsx deleted file mode 100644 index 9732c747..00000000 --- a/recipes/nextjs/app/(oberon)/api/auth/[...nextauth]/route.tsx +++ /dev/null @@ -1,3 +0,0 @@ -import { handlers } from "@/oberon/adapter"; - -export const { GET, POST } = handlers.auth || {}; diff --git a/recipes/nextjs/app/(oberon)/cms/api/[...path]/route.tsx b/recipes/nextjs/app/(oberon)/cms/api/[...path]/route.tsx new file mode 100644 index 00000000..b6ec8e5b --- /dev/null +++ b/recipes/nextjs/app/(oberon)/cms/api/[...path]/route.tsx @@ -0,0 +1,3 @@ +import { handler } from "@/oberon/adapter"; + +export const { GET, POST, PUT, PATCH, DELETE } = handler; diff --git a/recipes/nextjs/oberon/adapter.ts b/recipes/nextjs/oberon/adapter.ts index 2cbdd15b..1d4aaa4c 100644 --- a/recipes/nextjs/oberon/adapter.ts +++ b/recipes/nextjs/oberon/adapter.ts @@ -5,7 +5,7 @@ import { authPlugin } from "@oberoncms/core/auth"; import { plugin as developmentPlugin } from "@oberoncms/plugin-development"; import { config } from "./config"; -export const { handlers, adapter } = initOberon({ +export const { handler, adapter } = initOberon({ config, plugins: [mockPlugin, developmentPlugin, authPlugin], });