Thanks for showing interest in contributing! Contributions of any kind are welcome.
You can contribute to Filenest by
This project uses pnpm as the package manager. Make sure to install it first.
You'll need to open multiple terminals to run the project.
First, run the following command in the root dir to start the watcher to build all packages on file changes.
In another terminal, you can run an example app to test your changes.
If you want to add a new adapter, please also add an example app to test it.
To run the docs development server, run the following command in the root dir.
You can build the docs by running:
Filenest was initially created without any tests, because it was first designed for personal use. When I decided to turn it into an open-source project, I wanted to move quickly and publish it as fast as possible to focus on my main project.
Tests will be added incrementally, while the library is in beta.
Please open an issue or create a discussion if you want to take the initiative to add tests.
This project is a monorepo using Turborepo.
All packages are located in the packages
directory.
@filenest/core
The core package contains the Provider
interface which all providers must implement.
@filenest/provider-<provider>
Each provider package contains the implementation of the Provider
interface for a specific provider.
It's important to use as few dependencies as possible and to avoid large SDKs (e.g. AWS SDK or Cloudinary SDK).
Each provider package should communicate with the provider's REST API via plain fetch
.
Some provider methods must return specific error messages,
so @filenest/react
can respond by showing alert dialogs, for example.
deleteFolder
should return { success: false, message: "ERR_FOLDER_NOT_EMPTY" }
when trying to delete a non-empty folder.renameAsset
should return { success: false, message: "ERR_DELIVERY_URL_WILL_CHANGE" }
when renaming an asset would change its delivery URL.renameAsset
should return { success: false, message: "ERR_UPDATE_DELIVERY_URL_REQUIRED" }
when renaming an asset would change the display name only, and can optionally change the delivery URL.Also, make sure to prefix private methods and properties with an underscore _
.
For implementation details, or as a guide to implement a new provider, check out the Cloudinary provider.
react
packageUploading files is done by getting a signed URL from the Filenest API and uploading files to the provider directly from the client.
That code is currently tailored to Cloudinary, as that was the first provider, but it should be abstracted to work with any provider.
For example, Cloudinary needs a file
parameter to upload a file.
See this line of code
Other providers might work differently and need different parameters, so this will need to be refactored.
One way could be to implement a provider.getProvider()
method that returns the provider name as a string.
With that result, we could switch between different upload implementations. There are probably better ways.
@filenest/adapter-<adapter>
An adapter basically wraps a provider and returns its methods in a way to conform to a framework's API.
If you want to add a new adapter, please also add an example app to test it.
If possible, an adapter should accept global or per-route middleware, so that a user can add authorization, logging, etc.
Check out the tRPC Adapter for an example.
@filenest/react
This package contains all frontend components.
Talking to the Filenest API is done using a fetchers util,
which is made available in the Global Context
.