Code Monkey home page Code Monkey logo

edgestore's Introduction

Docs

Check the official documentation for more information.

Quick Start

Next.js Setup

Install

Let's start by installing the required packages.

npm install @edgestore/server @edgestore/react zod

Environment Variables

Then go to your Dashboard, create a new project and copy the keys to your environment variables.

EDGE_STORE_ACCESS_KEY=your-access-key
EDGE_STORE_SECRET_KEY=your-secret-key

Backend

Now we can create the backend code for our Next.js app.
Edge Store is compatible with both types of Next.js apps (pages router and app router).

The example below is the simplest bucket you can create with Edge Store. Just a simple file bucket with no validation that will be accessible by anyone with the link.

You can have multiple buckets in your app, each with its own configuration.

import { initEdgeStore } from '@edgestore/server';
import { createEdgeStoreNextHandler } from '@edgestore/server/adapters/next/app';

const es = initEdgeStore.create();

/**
 * This is the main router for the Edge Store buckets.
 */
const edgeStoreRouter = es.router({
  publicFiles: es.fileBucket(),
});

const handler = createEdgeStoreNextHandler({
  router: edgeStoreRouter,
});

export { handler as GET, handler as POST };

/**
 * This type is used to create the type-safe client for the frontend.
 */
export type EdgeStoreRouter = typeof edgeStoreRouter;

Frontend

Now let's initiate our context provider.

'use client';

import { createEdgeStoreProvider } from '@edgestore/react';
import { type EdgeStoreRouter } from '../app/api/edgestore/[...edgestore]/route';

const { EdgeStoreProvider, useEdgeStore } =
  createEdgeStoreProvider<EdgeStoreRouter>();

export { EdgeStoreProvider, useEdgeStore };

And then wrap our app with the provider.

import { EdgeStoreProvider } from '../lib/edgestore';
import './globals.css';

// ...

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <EdgeStoreProvider>{children}</EdgeStoreProvider>
      </body>
    </html>
  );
}

Upload file

You can use the useEdgeStore hook to access typesafe frontend client and use it to upload files.

import * as React from 'react';
import { useEdgeStore } from '../lib/edgestore';

export default function Page() {
  const [file, setFile] = React.useState<File>();
  const { edgestore } = useEdgeStore();

  return (
    <div>
      <input
        type="file"
        onChange={(e) => {
          setFile(e.target.files?.[0]);
        }}
      />
      <button
        onClick={async () => {
          if (file) {
            const res = await edgestore.publicFiles.upload({
              file,
              onProgressChange: (progress) => {
                // you can use this to show a progress bar
                console.log(progress);
              },
            });
            // you can run some server action or api here
            // to add the necessary data to your database
            console.log(res);
          }
        }}
      >
        Upload
      </button>
    </div>
  );
}

Replace file

By passing the replaceTargetUrl option, you can replace an existing file with a new one. It will automatically delete the old file after the upload is complete.

You can also just upload the file using the same file name, but in that case, you might still see the old file for a while because of the CDN cache.

const res = await edgestore.publicFiles.upload({
  file,
  options: {
    replaceTargetUrl: oldFileUrl,
  },
  // ...
});

Delete file

await edgestore.publicFiles.delete({
  url: urlToDelete,
});

edgestore's People

Contributors

perfectbase avatar itzcrazykns avatar edgestorejs avatar lemonmantis5571 avatar vikorbogdan avatar itskush avatar leovoon avatar yagogmaisp avatar

Stargazers

Ikbal AZIMARI TOURE avatar Lateef Idris avatar Pratham Poddar avatar Minwoo Chun avatar Dimitar Yordanov avatar Takuma Yumi avatar Zeyad Etman avatar Nikolaus Schlemm avatar  avatar David Huh avatar Jesús Tosca avatar Lucas Travessa avatar Md. Azmal avatar Jack avatar Mohamed Rifkan avatar Aaron Marsh avatar Mats Huesmann avatar  avatar Aryan Prince avatar HDAS avatar Med Dhia Kassab avatar @lpha avatar 无重力广场 avatar  avatar  avatar Mark Ambrocio avatar Jackson Kasi avatar petukhov avatar Abdul Fatah avatar Nick Sansalone avatar  avatar Mehedi Hasan avatar João Vitor avatar Damian Tardencilla avatar Rei avatar Chameison Araújo avatar Jacks avatar Hashan Chanaka  avatar Prodromos Pantos avatar Michael Dobekidis avatar Utku avatar  avatar John Tsevdos avatar Hsiu Ta Yu avatar Amit Singh avatar Yad avatar Amir Sheikhmagomedov avatar Umer Sagheer avatar Luke Fiji avatar Christopher Carvalho avatar Iulian Carnaru avatar Dia Eldin avatar Min Htet Oo avatar Prince Jules Correa avatar  avatar omar avatar Tim Kendall avatar Ali Motahari avatar  avatar Ansh avatar  avatar Deri Kurniawan avatar Sharad K avatar Anjola Adeuyi avatar Inderjot Singh avatar  avatar oussama djaidri avatar  avatar  avatar Chaitanya Vaddisriram avatar Angel Zúñiga Navarro avatar Nihar Hegde  avatar  avatar  avatar N V S Pavan Kalyan avatar Tarek H Ghosn avatar Paolo avatar Wanderson Alves avatar Shakil Ansary avatar Christian Ehrhardt avatar  avatar André Carlos avatar Shiloh George avatar Johan Guse avatar gooney avatar Dan Smirnov avatar  avatar Enrique Giménez avatar Rodrigo S Martins avatar Shounak Chavan avatar Ikram Maulana avatar Yingzhou Jiang avatar Leonardo dos Santos Lima avatar  avatar Pavel Dovhomilja avatar Khalid Dahir avatar Dmitry Kaigorodov avatar Edgar Dyck avatar  avatar Augusto César avatar

Watchers

 avatar

edgestore's Issues

How to view the files on the other end once uploaded...?

So I have a feeling I just wasted time and spent time figuring this out only to not be able to access the files afterwards..
I can find a lot of docs on how to upload the files but I cant find anything showing how to display the files again... I am assuming there is a particular api i should call or something but cant seem to figure it out....
Any idea if this is possible or if the docs could be updated with an example of this?

delete files on the server side

Thanks for this nice and easy to user uploader.
I don't know if i missed something in the docs but is it possible to delete files from the server e.g. after a database entry was deleted the corresponding files should also be deleted.
To me it would make sense to delete the files in the same place the corresponding database entries get deleted and not in the frontend.

⨯ Error: Page /api/edgestore/[...edgestore] does not export a default function.

Hi, I tried to implement your example with Nextjs Page Router, when I drop files I get 500 (Internal Server Error) error with the following message in terminal:

⨯ Error: Page /api/edgestore/[...edgestore] does not export a default function. at new U (D:\nodejs\giahnahadeh-cms\node_modules\.pnpm\[email protected]_@[email protected][email protected][email protected][email protected]\node_modules\next\dist\compiled\next-server\pages-api.runtime.dev.js:21:3736) at eval (webpack-internal:///(api)/./node_modules/.pnpm/[email protected]_@[email protected][email protected][email protected][email protected]/node_modules/next/dist/build/webpack/loaders/next-route-loader/index.js?kind=PAGES_API&page=%2Fapi%2Fedgestore%2F%5B...edgestore%5D&preferredRegion=&absolutePagePath=.%2Fpages%5Capi%5Cedgestore%5C%5B...edgestore%5D.ts&middlewareConfigBase64=e30%3D!:25:21)

License

Could you elaborate more on the license?

Can I use the library or the edge service on a commercial project?

In the pricing section you wrote
Best for individuals and non-commercial projects.
It means commercial projects are not allowed?

How do you delete multiple files?

I have been using edgestore, and I like it a lot. But I couldn't find how to delete multiple files in a single go, maybe by using filtering with metadata or path. My use case is I store my user's data in this way {userId}/{file}, and when the user closes their account or I want to manually delete them from the system, I first want to delete all their files and then mark them closed in the database so doing something like es.userFiles.delete({ path: { userId: 923udasdiasd9 } }) and it deletes all the files. I am also okay If this could be done with the backend client. If there is no official way to do It I will have to create a wrapper that first gets all the files of user by filtering from path and then deleting them one by one using the url. Would love to know if there is an official way to do it.

Missing edgestore-ctx cookie "UNAUTHORIZED"

I have EdgeStore setup with AWS provider in my NextJS app version 14. I haven't come across this issue before until today. Locally it seems to work fine. I double checked the variables and credentials are provided. Here is the error I'm facing:

{message: "Missing edgestore-ctx cookie", code: "UNAUTHORIZED" } code: "UNAUTHORIZED" message: "Missing edgestore-ctx cookie"

I enabled the debug mode, I see the edgestore-ctx being created after successful initialization:

DEBUG	[EdgeStoreDebug] Finished [init] {
  ctx: {},
  newCookies: [
    'edgestore-ctx=*********************.D7cYW8E01jnwYBPD.PXciUa55XMu8Dv7yOfCujvL5TQMtaNpgYqMcl51a84ftOUHeFhGw_W4Yvag0M7YWl1wDXAl-HdUkNJoKjL_csVH8bxcb04fCTgCJ*******************; Max-Age=2592000; Path=/'
  ],
  token: undefined,
  baseUrl: 'https://s3-bucket-name.us-west-1.amazonaws.com'
}

I could use some assistance, thanks.

Product website isn't working.

When I go to this "https://edgestore.dev/" URL for the documentation and other things, It says "This site can’t be reached".

I want to use this in a production-ready project and I am kind of worried, was the website URL changed or the hosting plans expired?
Screenshot_select-area_20240310100906

Is there a way to dynamically Set S3 Bucket?

I have a multi tenant nextjs app that stores documents, I need to store each document into different S3 Buckets based on what client is user session. I'm trying to find a way to dynamically set S3 Bucket name before each upload, if thats even possible...

Any ideas? I could really use some guide here 🙏

(Happy Holidays)

Documentation for Multi Image upload.

I've been using the project and found the documentation very helpful for uploading a single image, multi file upload. However, I encountered scenarios where I needed to upload multiple images simultaneously, and the documentation does not cover this aspect. As If we use the Multi file upload component it doesn't return the thumbnails. I have been working on a writing my own component but still it's not as polished.

I believe it would be beneficial for users if the documentation could include a section or example that demonstrates the process of uploading multiple images similar to Multi file upload.

Thankyou.

Service only working on localhost

Only works on localhost, when I deploy the application to a real url the api route returns a 500 internal server error.

http://localhost:4200/api/edgestore/health
returns "OK" as expected.

https://mysite/api/edgestore/health
returns "500 | Internal Server Error."

Urgent: Mistakenly Uploaded Sensitive Document

Hello,

I was testing the multi-file components feature on EdgeStore.dev and mistakenly uploaded a document that contains sensitive private information. I realized my mistake immediately after the upload.

Due to the sensitive nature of the information, I cannot share the URL of the document publicly. I kindly request that someone from the support team reach out to me privately so we can resolve this issue as soon as possible.

I understand the severity of this situation and apologize for any inconvenience caused. I appreciate your prompt attention to this matter.

Thank you.

Error when deploying to vercel.

I am setting up a backend client based from the documentation https://edgestore.dev/docs/backend-client. But when i upload to vercel i faced this error message:

Failed to compile.

22:05:04.601 |  
22:05:04.602 | src/app/api/edgestore/[...edgestore]/route.ts
22:05:04.602 | Type error: Route "src/app/api/edgestore/[...edgestore]/route.ts" does not match the required types of a Next.js Route.
22:05:04.602 | "backendClient" is not a valid Route export field.
22:05:04.602 |  
22:05:04.726 | Error: Command "npm run build" exited with 1

edgestore/[...edgestore]/route.ts

import { initEdgeStore } from '@edgestore/server';
import { createEdgeStoreNextHandler } from '@edgestore/server/adapters/next/app';
import { initEdgeStoreClient } from '@edgestore/server/core';

const es = initEdgeStore.create();
 
const edgeStoreRouter = es.router({
  publicFiles: es.fileBucket(),
});
 
const handler = createEdgeStoreNextHandler({
  router: edgeStoreRouter,
});

export { handler as GET, handler as POST };
 

export type EdgeStoreRouter = typeof edgeStoreRouter;

export const backendClient = initEdgeStoreClient({
  router: edgeStoreRouter,
});

Ip blocking

HI team , for some reason when I try to access the edge store website or even fetch my files from the storage its blocking my ip unless I use VPN. Why is this happening ? On Phone network its working fine, but on my pc office internet is blocking

Upload files from backend to edgestore

I'm really enjoying edgestore so far! However, I ran into a problem where I needed to upload an image via the backend and I could not find any documentation on how to do this.

Im generating images via Dall-e3 and want to upload them as soon as I get a response from openai. Do I need to hit the edgestore api endpoint or is there a way to "reuse" the edgestore post handler in my own route?

Thank you for building such a nice product!

Deleting files from s3 bucket - possible to use edgestore?

Hi!
I managed to get the delete method working on the backend with edgestore files, but couldnt seem to get it working with aws - wondering if that is my mistake in thinking it could work or if I am just doing something wrong here?

This is my backendClient and handler in the route.ts file

const handler = createEdgeStoreNextHandler({
  provider: AWSProvider(),
    logLevel: 'debug',
    router: edgeStoreRouter,
    createContext: createContext,
  });

export const backendClient = initEdgeStoreClient({
  router: edgeStoreRouter,
  baseUrl: 'http://localhost:3000/api/edgestore',
});

And this is how I am trying to access it on the backend:

export async function deleteVideoAws(urlToDelete: any) {
    const res = await backendClient.publicFiles.deleteFile({
      url: urlToDelete,
    });
    console.log(res)
  }
  

I can get this to work for those I have uploaded to the edgestore, but it doesnt work for those which I have uploaded to aws bucket - just wondering if this (simple and nice) method should work for aws or if I need to implement my own thing?
Despite having 'debug' level on, all I get in return (res) is:

{
url: 'the s3 url I am trying to delete',
success: false
}

Thanks in advance!

Problems to implement file protection functionality.

Hi. I'm trying to implement file protection functionality, but I'm having problems with ctx.
It looks like I can't access the context of it.

.path(({ ctx, input }) => [{ type: input.type }, { owner: ctx.userId }])

But when I try to upload files without this context, it works.

.path(({ input }) => [{ type: input.type }])

I really liked edgestore. And I think it will make things much easier. So, I'd like some help.

Here's my code:

import { initEdgeStore } from '@edgestore/server'
import {
  CreateContextOptions,
  createEdgeStoreNextHandler,
} from '@edgestore/server/adapters/next/app'
// import { useSession } from 'next-auth/react'
import { z } from 'zod'

type Context = {
  userId: string
  userRole: 'admin' | 'user'
}

const inputSchema = z.object({
  type: z.enum(['post', 'profile', 'rdo']),
})

function createContext({ req }: CreateContextOptions): Context {
  // const { data } = useSession()

  // if (!data || !data.user) {
  //   return {
  //     userId: '',
  //     userRole: 'user',
  //   }
  // }

  return {
    userId: '123',
    userRole: 'admin',
  }
}

const es = initEdgeStore.context<Context>().create()

const imageBucketConfig = {
  maxSize: 5 * 1024 * 1024,
  accept: ['image/jpeg', 'image/jpg', 'image/png'],
}

function createMetadata(ctx: Context, input: { type: string }) {
  return {
    userRole: ctx.userRole,
    userId: ctx.userId,
    type: input.type,
  }
}

const edgeStoreRouter = es.router({
  publicImages: es
    .imageBucket(imageBucketConfig)
    .input(inputSchema)
    .path(({ ctx, input }) => [{ type: input.type }, { owner: ctx.userId }])
    .metadata(({ ctx, input }) => createMetadata(ctx, input)),

  protectedFiles: es
    .fileBucket(imageBucketConfig)
    .input(inputSchema)
    .path(({ ctx, input }) => [{ type: input.type }, { owner: ctx.userId }])
    .metadata(({ ctx, input }) => createMetadata(ctx, input))
    .accessControl({
      OR: [{ userId: { path: 'owner' } }, { userRole: { eq: 'admin' } }],
    }),
})

const handler = createEdgeStoreNextHandler({
  router: edgeStoreRouter,
  createContext,
})

export { handler as GET, handler as POST }

export type EdgeStoreRouter = typeof edgeStoreRouter

And this is how it is implemented on frontend:

                <MultiFileDropzone
                  className='bg-slate-100 dark:bg-slate-900'
                  value={fileStates}
                  onChange={(files) => {
                    setFileStates(files)
                  }}
                  onFilesAdded={async (addedFiles) => {
                    setFileStates([...fileStates, ...addedFiles])
                    await Promise.all(
                      addedFiles.map(async (addedFileState) => {
                        try {
                          const res = await edgestore.protectedFiles.upload({
                            file: addedFileState.file,
                            options: {
                              temporary: true,
                            },
                            input: { type: 'rdo' },
                            onProgressChange: async (progress: number) => {
                              updateFileProgress(addedFileState.key, progress)
                              if (progress === 100) {
                                // wait 1 second to set it to complete
                                // so that the user can see the progress bar at 100%
                                await new Promise((resolve) =>
                                  setTimeout(resolve, 1000),
                                )
                                updateFileProgress(
                                  addedFileState.key,
                                  'COMPLETE',
                                )
                              }
                            },
                          })
                          setUrls((urls) => [...urls, res.url])
                          console.log(res)
                        } catch (err) {
                          console.log(
                            '🚀 ~ file: NewRDOModal.tsx:219 ~ addedFiles.map ~ err:',
                            (err as Error).message,
                          )
                          updateFileProgress(addedFileState.key, 'ERROR')
                        }
                      }),
                    )
                  }}
                />

Thanks in advance.

Issue when nextjs trailingSlash = true

Background:

  • I am currently developing a web frontend application using Next.js.
  • The application is built on Next.js version 14.0.4.
  • I am attempting to upload files using a storage service called Edgestore.
  • To my understanding, Edgestore provides cloud storage services similar to AWS's S3.

Error Message:
I encountered an error while trying to integrate Edgestore into my project. The error message is as follows:

EdgeStoreError: Failed to parse response. Make sure the API is correctly configured at http://localhost:3000/api/edgestore/init/

Suspected Causes:

  • I suspect this issue might be related to the version of Next.js I am using. Could there be any compatibility issues with Next.js 14.0.4?
  • Or my layout.tsx
  • Here is my src/app/layout.tsx file
  • Because when i debug my project code, i deleted all code related edgestore without
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <EdgeStoreProvider>{children}</EdgeStoreProvider>
        <Toaster />
      </body>
    </html>
  );
}

How to integrate with react-hook-form?

I like edgestore. I want to integrate uploads with react-hook-form in order to enforce a minimum and maximum number of uploads. There must also be size a constraint.
For some reason I don't manage to get it working with react-hook-form

// schema
export const FormSchema = z.object({
  name: z.string({ required_error: "Name erforderlich" }).min(2, {
    message: "Name erforderlich",
  }),
  phone: z
    .string({ required_error: "Telefonnummer erforderlich" })
    .regex(phoneRegex, {
      message: "Bitte geben Sie eine gültige Telefonnummer ein",
    }),
  email: z.string({ required_error: "Email erforderlich" }).email({
    message: "Bitte geben Sie eine gültige E-Mail Adresse ein",
  }),
  description: z
    .string({ required_error: "Beschreibung erforderlich" })
    .min(20, {
      message: "Beschreibung (min. 50 Zeichen) ist zu kurz",
    }),
  fileStates: z
    .array(
      z.object({
        file: z.instanceof(File), // Ensure file is an instance of File
        key: z.string(), // Assume key is a string
        progress: z.union([
          z.literal("PENDING"),
          z.literal("COMPLETE"),
          z.literal("ERROR"),
          z.number(),
        ]), // Union of allowed values
      })
    )
    .min(2, { message: "Bitte laden Sie mindestens 2 Dateien hoch" })
    .max(5, { message: "Maximal 5 Dateien erlaubt" }),
  fileUrls: z
    .array(z.string())
    .min(2, { message: "Bitte laden Sie mindestens 2 Dateien hoch" })
    .max(5, { message: "Maximal 5 Dateien erlaubt" }),
});

// type
export type TFormSchema = z.infer<typeof FormSchema>;

// zod
  const form = useForm<TFormSchema>({
    resolver: zodResolver(FormSchema),
    defaultValues: {
      name: "",
      phone: "",
      email: "",
      description: "",
      fileStates: [],
      fileUrls: [],
    },
  });


// update function
  function updateFileProgress(key: string, progress: FileState["progress"]) {
    form.setValue("fileStates", (formFileStates) => { //  ---> already shows here a type error
      const newFileStates = structuredClone(formFileStates);
      const fileState = newFileStates.find(
        (fileState) => fileState.key === key
      );
      if (fileState) {
        fileState.progress = progress;
      }
      return newFileStates;
    });
  }


// formfield
  <FormField
              control={form.control}
              name="fileStates"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Fotos/Dokumente hochladen</FormLabel>
                  <FormControl>
                    <MultiFileDropzone
                      {...field}
                      className="w-full"
                      value={field.value}
                      onChange={field.onChange}
                      onFilesAdded={async (addedFiles) => {
                        // form.setValue("fileStates", [
                        //   ...field.value,
                        //   ...addedFiles,
                        // ]);
                        setFileStates([...field.value, ...addedFiles]);
                        await Promise.all(
                          form
                            .getValues("fileStates")
                            .map(async (addedFileState) => {
                              try {
                                const res = await edgestore.publicFiles.upload({
                                  file: addedFileState.file,

                                  onProgressChange: async (progress) => {
                                    updateFileProgress(
                                      addedFileState.key,
                                      progress
                                    );
                                    if (progress === 100) {
                                      // wait 1 second to set it to complete
                                      // so that the user can see the progress bar at 100%
                                      await new Promise((resolve) =>
                                        setTimeout(resolve, 1000)
                                      );
                                      updateFileProgress(
                                        addedFileState.key,
                                        "COMPLETE"
                                      );
                                    }
                                  },
                                });

                                getDownloadUrl(res.url);
                              } catch (error) {
                                updateFileProgress(addedFileState.key, "ERROR");
                                // All errors are typed and you will get intellisense for them
                                if (error instanceof EdgeStoreApiClientError) {
                                  // if it fails due to the `maxSize` set in the router config
                                  if (error.data.code === "FILE_TOO_LARGE") {
                                    alert(
                                      `Datei zu groß. Sie darf maximal ${formatFileSize(
                                        error.data.details.maxFileSize
                                      )} groß sein`
                                    );
                                  }
                                  // if it fails due to the `accept` set in the router config
                                  if (
                                    error.data.code === "MIME_TYPE_NOT_ALLOWED"
                                  ) {
                                    alert(
                                      `Dateityp nicht erlaubt. Erlaubte Typen sind  ${error.data.details.allowedMimeTypes.join(
                                        ", "
                                      )}`
                                    );
                                  }
                                }
                              }
                            })
                        );
                      }}
                    />

Any idea what I miss here?

Thumbnail rotated

I have noticed that sometimes the thumbnail is rotated. Here is an image where I can encounter this problem
test

Getting Server Error 500

Hello,

I was trying to use edgestore in my NextJS app (NextJs -> 14.0.1). I followed the steps mentioned in the documentation and I noticed that I am getting this error when the app starts:

Request URL: http://localhost:3001/api/edgestore/init
Request Method: POST
Status Code: 500 Internal Server Error
Remote Address: [::1]:3001
Referrer Policy: strict-origin-when-cross-origin

And I can see the response message is showing Missing path param

When I try to ignore the error and proceed to upload the image anyway. I get the same error but of course the API path will be different since it will be now trying to upload the image.

I have configured my .env file correctly with the key I got from the project.

Here is the route.ts code:

import { currentUser, redirectToSignIn } from "@clerk/nextjs"
import { initEdgeStore } from "@edgestore/server"
import {
  CreateContextOptions,
  createEdgeStoreNextHandler,
} from "@edgestore/server/adapters/next/app"
import { z } from "zod"

type Context = {
  userId: string | undefined
}

async function createContext({ req }: CreateContextOptions): Promise<Context> {
  const user = await currentUser()
  return {
    userId: user?.id,
  }
}

const es = initEdgeStore.context<Context>().create()

const edgeStoreRouter = es.router({
  publicImages: es
    .imageBucket({
      maxSize: 1024 * 1024 * 1, //1MB
      accept: ["image/jpeg", "image/png"],
    })
    .input(
      z.object({
        type: z.enum(["post", "profile", "market"]),
      })
    )
    .path(({ input }) => [{ type: input.type }, {}])
    .accessControl({
      userId: { not: undefined },
    }),
})
const handler = createEdgeStoreNextHandler({
  router: edgeStoreRouter,
  createContext,
})
export { handler as GET, handler as POST }
export type EdgeStoreRouter = typeof edgeStoreRouter

Here is the provider code:

"use client"

import { createEdgeStoreProvider } from "@edgestore/react"

import { type EdgeStoreRouter } from "@/app/api/edgestore/[...edgestore]/route"

const { EdgeStoreProvider, useEdgeStore } =
  createEdgeStoreProvider<EdgeStoreRouter>()

export { EdgeStoreProvider, useEdgeStore }

I am stuck here and I am not sure why I keep getting the 500 error. I can't even see this error in my VSCode console

Any idea how to fix this?

CORS policy: No 'Access-Control-Allow-Origin'

Hey, hello.

I'm using edgestore in my nextjs app hosted in vercel, everything works fine in localhost, but when I try to upload files in my vercel app I get a cors error

Access to fetch at 'https://files.edgestore.dev/.../publicFiles/_public/uuid.pdf' from origin 'https://myhost.vercel.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
1866d874-9d824f0eb67088a0.js:22 
        
        
GET https://files.edgestore.dev/.../publicFiles/_public/uuid.pdf net::ERR_FAILED 200 (OK)

I tried to bypass the cors config in vercel.json but no success.

Any ideas ?

Product website not working - Internet Provider blocking the site?

Hi!

I know this is a repeat but I am still getting the same error as in the other post and the issue is closed so I don't think I would get a reply there... I have done a little investigation as to when I can access the website and when I cannot. I don't understand the reason for it but have looked into it a little at least:

  1. Trying generally no matter the browser does not work and I get the following error:

This is what the error looks like on brave:
Screenshot 2024-03-18 at 08 33 24

The 'advanced' error on that says:

"edgestore.dev normally uses encryption to protect your information. When Brave tried to connect to edgestore.dev this time, the website sent back unusual and incorrect credentials. This may happen when an attacker is trying to pretend to be edgestore.dev, or a Wi-Fi sign-in screen has interrupted the connection. Your information is still secure because Brave stopped the connection before any data was exchanged.

You cannot visit edgestore.dev right now because the website uses HSTS. Network errors and attacks are usually temporary, so this page will probably work later."

I tried late last week, but it seems like the error is still happening.

This is the error on Firefox (safari's is just very plain and general as was chromes)
Screenshot 2024-03-18 at 08 45 04
(note I reported it to the telstra 'report this website as safe' here: https://www.telstra.com.au/forms/report-misuse-of-service)

  1. If I try on my phone when it is connected to my home wifi it does not work
  2. If I try on my phone when not connected to the home wifi it works
  3. If I try with a vpn, it works

I have no clue what is causing the issue but it might be telstra blocking the site, however given there was another report of it, it seems like there might be something causing the website being flagged by ISP's... So might be worthwhile figuring out the security issue or why it is being flagged suddenly (was working about a month ago for me at least)

No clue if this could help, but if the website is not accessible to people you are going to lose out on customers/people using it.

Error when starting next-intl issue

index.mjs:23 Uncaught (in promise) EdgeStoreError: Failed to parse response. Make sure the api is correctly configured at http://localhost:3000/api/edgestore/init
at handleError (index.mjs:23:15)

image

all things are setted, but i think im getting error because next-intl, since there's a [locale] folder, i suspect edgestore is not finding because of that, there's a working round for this ? btw i tried to put api folder inside and outside locale.

accessControl is giving me unauthorized

Hello everyone!

I have been following the Youtube video tutorial for this amazing library and I was trying to implement the access control to protect the app images.

Now, the projection does not care about the user role or anything. I just need to make sure that the user is logged in regardless who he is.

The upload works great. But whenever I try to display the uploaded images in my app (with a logged in user), I get the unauthorized error.

Maybe I am doing something wong?

Here is the route.ts code:

import { currentUser, redirectToSignIn } from "@clerk/nextjs"
import { initEdgeStore } from "@edgestore/server"
import {
  CreateContextOptions,
  createEdgeStoreNextHandler,
} from "@edgestore/server/adapters/next/app"
import { z } from "zod"

context = {
  userId: string
}

async function createContext({ req }: CreateContextOptions): Promise<Context> {
  //logic to get the user from the session from clerk
  const user = await currentUser()
  if (user) {
    return {
      userId: user.id,
    }
  } else {
    return {
      userId: "Unknown",
    }
  }
}

const es = initEdgeStore.context<Context>().create()

const edgeStoreRouter = es.router({
  publicImages: es
    .imageBucket({
      maxSize: 1024 * 1024 * 1,
      accept: ["image/jpeg", "image/png"],
    })
    .input(
      z.object({
        type: z.enum(["post", "profile", "market"]),
      })
    )
    //example: /post/my-post.jpg
    .path(({ input }) => [{ type: input.type }])
    .accessControl({
      userId: { not: "Unknown" },
    }),
})
const handler = createEdgeStoreNextHandler({
  router: edgeStoreRouter,
  createContext,
})
export { handler as GET, handler as POST }

export type EdgeStoreRouter = typeof edgeStoreRouter

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.